This repository has been archived on 2026-03-21. You can view files and clone it, but cannot push or open issues or pull requests.
payfrit-biz/api/tasks/listMine.cfm
John Mizerek 31a89018f5 Launch prep: fix menu builder, payment flow, comment out pre-launch features
- Fix menu builder dropdown showing empty names (return MenuName instead of Name)
- Add default menu selection (setDefault action, DefaultMenuID in getForBuilder)
- Fix createPaymentIntent column names for dev schema (ID, StripeAccountID, etc.)
- Fix menu-builder favicon and remove redundant business label
- Comment out Tabs/Running Checks feature for launch (HTML + JS)
- Comment out Service Point Marketing/Grants feature for launch (HTML + JS)
- Add testMarkPaid.cfm for testing orders without Stripe webhooks
- Task API updates for worker payout ledger integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 10:18:33 -08:00

171 lines
6.1 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cffunction name="apiAbort" access="public" returntype="void" output="true">
<cfargument name="payload" type="struct" required="true">
<cfcontent type="application/json; charset=utf-8">
<cfoutput>#serializeJSON(arguments.payload)#</cfoutput>
<cfabort>
</cffunction>
<cffunction name="readJsonBody" access="public" returntype="struct" output="false">
<cfset var raw = getHttpRequestData().content>
<cfif isNull(raw) OR len(trim(raw)) EQ 0>
<cfreturn {}>
</cfif>
<cftry>
<cfset var data = deserializeJSON(raw)>
<cfif isStruct(data)>
<cfreturn data>
<cfelse>
<cfreturn {}>
</cfif>
<cfcatch>
<cfreturn {}>
</cfcatch>
</cftry>
</cffunction>
<cfset data = readJsonBody()>
<cfset UserID = val( structKeyExists(data,"UserID") ? data.UserID : 0 )>
<cfset BusinessID = val( structKeyExists(data,"BusinessID") ? data.BusinessID : 0 )>
<cfset FilterType = structKeyExists(data,"FilterType") ? lcase(toString(data.FilterType)) : "active">
<cfif UserID LTE 0>
<cfset apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "UserID is required." })>
</cfif>
<cftry>
<!--- Build WHERE clause based on filter type --->
<cfset whereClauses = ["t.ClaimedByUserID = ?"]>
<cfset params = [ { value = UserID, cfsqltype = "cf_sql_integer" } ]>
<!--- Filter by business if provided --->
<cfif BusinessID GT 0>
<cfset arrayAppend(whereClauses, "t.BusinessID = ?")>
<cfset arrayAppend(params, { value = BusinessID, cfsqltype = "cf_sql_integer" })>
</cfif>
<!--- Filter by type: active (not completed), completed, today, week --->
<cfswitch expression="#FilterType#">
<cfcase value="active">
<cfset arrayAppend(whereClauses, "t.CompletedOn IS NULL")>
</cfcase>
<cfcase value="completed">
<cfset arrayAppend(whereClauses, "t.CompletedOn IS NOT NULL")>
</cfcase>
<cfcase value="today">
<cfset arrayAppend(whereClauses, "DATE(t.ClaimedOn) = CURDATE()")>
</cfcase>
<cfcase value="week">
<cfset arrayAppend(whereClauses, "t.ClaimedOn >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)")>
</cfcase>
</cfswitch>
<cfset whereSQL = arrayToList(whereClauses, " AND ")>
<cfset qTasks = queryTimed("
SELECT
t.ID,
t.BusinessID,
t.CategoryID,
t.OrderID,
t.TaskTypeID,
t.Title,
t.Details,
t.CreatedOn,
t.ClaimedByUserID,
t.ClaimedOn,
t.CompletedOn,
tc.Name AS CategoryName,
tc.Color AS CategoryColor,
tt.Name AS TaskTypeName,
tt.Icon AS TaskTypeIcon,
tt.Color AS TaskTypeColor,
b.Name AS BusinessName
FROM Tasks t
LEFT JOIN TaskCategories tc ON tc.ID = t.CategoryID
LEFT JOIN tt_TaskTypes tt ON tt.ID = t.TaskTypeID
LEFT JOIN Businesses b ON b.ID = t.BusinessID
WHERE #whereSQL#
ORDER BY t.ClaimedOn DESC
", params, { datasource = "payfrit" })>
<cfset tasks = []>
<cfloop query="qTasks">
<!--- Use stored title if available, otherwise build from order --->
<cfset taskTitle = "">
<cfif NOT isNull(qTasks.Title) AND len(trim(qTasks.Title)) GT 0>
<cfset taskTitle = qTasks.Title>
<cfelseif qTasks.OrderID GT 0>
<cfset taskTitle = "Order ##" & qTasks.OrderID>
<cfelse>
<cfset taskTitle = "Task ##" & qTasks.ID>
</cfif>
<cfset taskDetails = "">
<cfif NOT isNull(qTasks.Details) AND len(trim(qTasks.Details)) GT 0>
<cfset taskDetails = qTasks.Details>
</cfif>
<cfset arrayAppend(tasks, {
"TaskID": qTasks.ID,
"BusinessID": qTasks.BusinessID,
"BusinessName": qTasks.BusinessName ?: "",
"TaskCategoryID": qTasks.CategoryID,
"TaskTypeID": qTasks.TaskTypeID,
"Title": taskTitle,
"Details": taskDetails,
"CreatedOn": dateFormat(qTasks.CreatedOn, "yyyy-mm-dd") & "T" & timeFormat(qTasks.CreatedOn, "HH:mm:ss"),
"ClaimedOn": (isNull(qTasks.ClaimedOn) OR len(trim(qTasks.ClaimedOn)) EQ 0) ? "" : dateFormat(qTasks.ClaimedOn, "yyyy-mm-dd") & "T" & timeFormat(qTasks.ClaimedOn, "HH:mm:ss"),
"CompletedOn": (isNull(qTasks.CompletedOn) OR len(trim(qTasks.CompletedOn)) EQ 0) ? "" : dateFormat(qTasks.CompletedOn, "yyyy-mm-dd") & "T" & timeFormat(qTasks.CompletedOn, "HH:mm:ss"),
"StatusID": (isNull(qTasks.CompletedOn) OR len(trim(qTasks.CompletedOn)) EQ 0) ? 1 : 3,
"SourceType": "order",
"SourceID": qTasks.OrderID,
"CategoryName": len(trim(qTasks.CategoryName)) ? qTasks.CategoryName : "General",
"CategoryColor": len(trim(qTasks.CategoryColor)) ? qTasks.CategoryColor : "##888888",
"TaskTypeName": len(trim(qTasks.TaskTypeName)) ? qTasks.TaskTypeName : "",
"TaskTypeIcon": len(trim(qTasks.TaskTypeIcon)) ? qTasks.TaskTypeIcon : "notifications",
"TaskTypeColor": len(trim(qTasks.TaskTypeColor)) ? qTasks.TaskTypeColor : "##9C27B0"
})>
</cfloop>
<!--- Calculate OrderTotal for tasks with linked orders --->
<cfloop from="1" to="#arrayLen(tasks)#" index="i">
<cfif val(tasks[i].SourceID) GT 0>
<cfset qOT = queryTimed("
SELECT SUM(oli.Price * oli.Quantity) AS Subtotal, o.TipAmount, o.DeliveryFee, o.OrderTypeID, b.TaxRate
FROM Orders o
INNER JOIN Businesses b ON b.ID = o.BusinessID
LEFT JOIN OrderLineItems oli ON oli.OrderID = o.ID AND oli.IsDeleted = b'0'
WHERE o.ID = ?
GROUP BY o.ID
", [{ value = tasks[i].SourceID, cfsqltype = "cf_sql_integer" }], { datasource = "payfrit" })>
<cfif qOT.recordCount GT 0>
<cfset sub = val(qOT.Subtotal)>
<cfset tasks[i]["OrderTotal"] = numberFormat(sub + (sub * val(qOT.TaxRate)) + val(qOT.TipAmount) + ((val(qOT.OrderTypeID) EQ 3) ? val(qOT.DeliveryFee) : 0) + (sub * 0.05), "0.00")>
<cfelse>
<cfset tasks[i]["OrderTotal"] = 0>
</cfif>
<cfelse>
<cfset tasks[i]["OrderTotal"] = 0>
</cfif>
</cfloop>
<cfset apiAbort({
"OK": true,
"ERROR": "",
"TASKS": tasks,
"COUNT": arrayLen(tasks)
})>
<cfcatch>
<cfset apiAbort({
"OK": false,
"ERROR": "server_error",
"MESSAGE": "Error loading tasks",
"DETAIL": cfcatch.message
})>
</cfcatch>
</cftry>