payfrit-works/api/orders/getPendingForUser.cfm
John Mizerek d8d7efe056 Add user account APIs and fix Lucee header handling
- Add avatar.cfm: GET/POST for user profile photos with multi-extension support
- Add profile.cfm: GET/POST for user profile (name, email, phone)
- Add history.cfm: Order history endpoint with pagination
- Add addresses/list.cfm and add.cfm: Delivery address management
- Add setOrderType.cfm: Set delivery/takeaway type on orders
- Add checkToken.cfm: Debug endpoint for token validation
- Fix headerValue() in Application.cfm to use servlet request object
  (Lucee CGI scope doesn't expose custom HTTP headers like X-User-Token)
- Update public allowlist for new endpoints
- Add privacy.html page

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 20:01:07 -08:00

109 lines
3.6 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">
<cfscript>
/**
* Get pending orders for a user at a specific business
* Used when a beacon is detected to check if user has an order to pick up
*
* Query params:
* UserID - the user's ID
* BusinessID - the business ID
*
* Returns orders with status 1-3 (Submitted, Preparing, Ready)
*/
response = { "OK": false };
try {
UserID = val(url.UserID ?: 0);
BusinessID = val(url.BusinessID ?: 0);
if (UserID LTE 0) {
response["ERROR"] = "missing_user";
response["MESSAGE"] = "UserID is required";
writeOutput(serializeJSON(response));
abort;
}
if (BusinessID LTE 0) {
response["ERROR"] = "missing_business";
response["MESSAGE"] = "BusinessID is required";
writeOutput(serializeJSON(response));
abort;
}
// Get orders with status 1 (Submitted), 2 (Preparing), or 3 (Ready)
// These are orders that are paid but not yet completed/picked up
qOrders = queryExecute("
SELECT
o.OrderID,
o.OrderUUID,
o.OrderTypeID,
o.OrderStatusID,
o.OrderSubmittedOn,
o.OrderServicePointID,
sp.ServicePointName,
b.BusinessName,
(SELECT COALESCE(SUM(oli.OrderLineItemPrice * oli.OrderLineItemQuantity), 0)
FROM OrderLineItems oli
WHERE oli.OrderLineItemOrderID = o.OrderID
AND oli.OrderLineItemIsDeleted = 0
AND oli.OrderLineItemParentOrderLineItemID = 0) as Subtotal
FROM Orders o
LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
LEFT JOIN Businesses b ON b.BusinessID = o.OrderBusinessID
WHERE o.OrderUserID = :userId
AND o.OrderBusinessID = :businessId
AND o.OrderStatusID IN (1, 2, 3)
ORDER BY o.OrderSubmittedOn DESC
LIMIT 5
", {
userId: { value: UserID, cfsqltype: "cf_sql_integer" },
businessId: { value: BusinessID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
orders = [];
for (row in qOrders) {
statusName = "";
switch (row.OrderStatusID) {
case 1: statusName = "Submitted"; break;
case 2: statusName = "Preparing"; break;
case 3: statusName = "Ready for Pickup"; break;
}
orderTypeName = "";
switch (row.OrderTypeID) {
case 1: orderTypeName = "Dine-In"; break;
case 2: orderTypeName = "Takeaway"; break;
case 3: orderTypeName = "Delivery"; break;
}
arrayAppend(orders, {
"OrderID": row.OrderID,
"OrderUUID": row.OrderUUID,
"OrderTypeID": row.OrderTypeID,
"OrderTypeName": orderTypeName,
"OrderStatusID": row.OrderStatusID,
"StatusName": statusName,
"SubmittedOn": dateTimeFormat(row.OrderSubmittedOn, "yyyy-mm-dd HH:nn:ss"),
"ServicePointID": row.OrderServicePointID,
"ServicePointName": len(trim(row.ServicePointName)) ? row.ServicePointName : "",
"BusinessName": len(trim(row.BusinessName)) ? row.BusinessName : "",
"Subtotal": row.Subtotal
});
}
response["OK"] = true;
response["ORDERS"] = orders;
response["HAS_PENDING"] = arrayLen(orders) GT 0;
} catch (any e) {
response["ERROR"] = "server_error";
response["MESSAGE"] = e.message;
}
writeOutput(serializeJSON(response));
</cfscript>