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/tabs/pendingOrders.cfm
John Mizerek 4c0479db5c Add Open Tabs feature: tab APIs, presence tracking, shared tabs, cron, portal settings
- New api/tabs/ directory with 13 endpoints: open, close, cancel, get, getActive,
  addOrder, increaseAuth, addMember, removeMember, getPresence, approveOrder,
  rejectOrder, pendingOrders
- New api/presence/heartbeat.cfm for beacon-based user presence tracking
- New cron/expireTabs.cfm for idle tab expiry and presence cleanup
- Modified submit.cfm for tab-aware order submission (skip payment, update running total)
- Modified getOrCreateCart.cfm to auto-detect active tab and set TabID on new carts
- Modified webhook.cfm to handle tab capture events (metadata type=tab_close)
- Modified businesses/get.cfm and updateTabs.cfm with new tab config columns
- Updated portal tab settings UI with auth amounts, max members, approval toggle
- Added tab and presence endpoints to Application.cfm public allowlist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:56:07 -08:00

74 lines
2.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 Tab Orders
* Returns orders awaiting tab owner approval, with line item details.
*
* POST: { TabID: int, UserID: int (tab owner) }
*/
try {
requestData = deserializeJSON(toString(getHttpRequestData().content));
tabID = val(requestData.TabID ?: 0);
userID = val(requestData.UserID ?: 0);
if (tabID == 0) apiAbort({ "OK": false, "ERROR": "missing_TabID" });
if (userID == 0) apiAbort({ "OK": false, "ERROR": "missing_UserID" });
qTab = queryTimed("SELECT OwnerUserID FROM Tabs WHERE ID = :tabID LIMIT 1", {
tabID: { value: tabID, cfsqltype: "cf_sql_integer" }
});
if (qTab.recordCount == 0) apiAbort({ "OK": false, "ERROR": "tab_not_found" });
if (qTab.OwnerUserID != userID) apiAbort({ "OK": false, "ERROR": "not_owner" });
qPending = queryTimed("
SELECT tbo.OrderID, tbo.UserID, tbo.SubtotalCents, tbo.TaxCents, tbo.AddedOn,
u.FirstName, u.LastName
FROM TabOrders tbo
JOIN Users u ON u.ID = tbo.UserID
WHERE tbo.TabID = :tabID AND tbo.ApprovalStatus = 'pending'
ORDER BY tbo.AddedOn
", { tabID: { value: tabID, cfsqltype: "cf_sql_integer" } });
orders = [];
for (row in qPending) {
// Get line items for this order
qItems = queryTimed("
SELECT oli.ID, oli.ItemID, oli.Price, oli.Quantity, oli.Remark,
i.Name AS ItemName
FROM OrderLineItems oli
JOIN Items i ON i.ID = oli.ItemID
WHERE oli.OrderID = :orderID AND oli.IsDeleted = 0 AND oli.ParentOrderLineItemID = 0
", { orderID: { value: row.OrderID, cfsqltype: "cf_sql_integer" } });
items = [];
for (item in qItems) {
arrayAppend(items, {
"Name": item.ItemName,
"Price": item.Price,
"Quantity": item.Quantity,
"Remark": item.Remark ?: ""
});
}
arrayAppend(orders, {
"OrderID": row.OrderID,
"UserID": row.UserID,
"UserName": "#row.FirstName# #row.LastName#",
"SubtotalCents": row.SubtotalCents,
"TaxCents": row.TaxCents,
"AddedOn": toISO8601(row.AddedOn),
"Items": items
});
}
apiAbort({ "OK": true, "PENDING_ORDERS": orders });
} catch (any e) {
apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message });
}
</cfscript>