From 496ef74c4cd1afa4364c82e26ca3203d4d952d4e Mon Sep 17 00:00:00 2001 From: John Mizerek Date: Tue, 3 Mar 2026 12:56:14 -0800 Subject: [PATCH] fix: prevent tab cancel when approved orders exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cancel.cfm previously only blocked cancel if orders had StatusID >= 1 (submitted to kitchen). If submitOrder() failed after addOrderToTab() succeeded, the order stayed at StatusID 0 but was linked to the tab with ApprovalStatus='approved'. This allowed cancelling the tab free. Now checks TabOrders directly — any approved orders with non-zero subtotals block the cancel, regardless of kitchen submission status. Co-Authored-By: Claude Opus 4.6 --- api/tabs/cancel.cfm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/api/tabs/cancel.cfm b/api/tabs/cancel.cfm index b90c24a..f32e09f 100644 --- a/api/tabs/cancel.cfm +++ b/api/tabs/cancel.cfm @@ -6,7 +6,7 @@ /** * Cancel Tab - * Only allowed if no orders have been submitted to kitchen (StatusID >= 1). + * Only allowed if no approved orders with non-zero subtotals exist. * Releases the Stripe hold. * * POST: { TabID: int, UserID: int } @@ -29,15 +29,15 @@ try { if (qTab.StatusID != 1) apiAbort({ "OK": false, "ERROR": "tab_not_open" }); if (qTab.OwnerUserID != userID) apiAbort({ "OK": false, "ERROR": "not_owner" }); - // Check for submitted orders - qSubmitted = queryTimed(" - SELECT COUNT(*) AS Cnt FROM TabOrders tbo - JOIN Orders o ON o.ID = tbo.OrderID - WHERE tbo.TabID = :tabID AND tbo.ApprovalStatus = 'approved' AND o.StatusID >= 1 + // Check for any approved orders (regardless of kitchen status) + qApproved = queryTimed(" + SELECT COUNT(*) AS Cnt, COALESCE(SUM(SubtotalCents), 0) AS TotalCents + FROM TabOrders + WHERE TabID = :tabID AND ApprovalStatus = 'approved' ", { tabID: { value: tabID, cfsqltype: "cf_sql_integer" } }); - if (qSubmitted.Cnt > 0) { - apiAbort({ "OK": false, "ERROR": "has_submitted_orders", "MESSAGE": "Tab has orders in progress. Close the tab instead of cancelling." }); + if (qApproved.Cnt > 0 && val(qApproved.TotalCents) > 0) { + apiAbort({ "OK": false, "ERROR": "has_orders", "MESSAGE": "Tab has approved orders. Close the tab instead of cancelling." }); } // Cancel Stripe PI