/** * Approve Tab Order * Tab owner approves a pending member order. Order is then submitted to kitchen. * * POST: { TabID: int, OrderID: int, UserID: int (tab owner) } */ try { requestData = deserializeJSON(toString(getHttpRequestData().content)); tabID = val(requestData.TabID ?: 0); orderID = val(requestData.OrderID ?: 0); userID = val(requestData.UserID ?: 0); if (tabID == 0) apiAbort({ "OK": false, "ERROR": "missing_TabID" }); if (orderID == 0) apiAbort({ "OK": false, "ERROR": "missing_OrderID" }); if (userID == 0) apiAbort({ "OK": false, "ERROR": "missing_UserID" }); // Verify tab owner qTab = queryTimed(" SELECT ID, OwnerUserID, StatusID, AuthAmountCents, RunningTotalCents 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.StatusID != 1) apiAbort({ "OK": false, "ERROR": "tab_not_open" }); if (qTab.OwnerUserID != userID) apiAbort({ "OK": false, "ERROR": "not_owner" }); // Get the pending order qTabOrder = queryTimed(" SELECT ID, SubtotalCents, TaxCents, ApprovalStatus FROM TabOrders WHERE TabID = :tabID AND OrderID = :orderID LIMIT 1 ", { tabID: { value: tabID, cfsqltype: "cf_sql_integer" }, orderID: { value: orderID, cfsqltype: "cf_sql_integer" } }); if (qTabOrder.recordCount == 0) apiAbort({ "OK": false, "ERROR": "order_not_on_tab" }); if (qTabOrder.ApprovalStatus != "pending") apiAbort({ "OK": false, "ERROR": "not_pending", "MESSAGE": "Order is #qTabOrder.ApprovalStatus#, not pending." }); // Check authorization limit orderTotal = qTabOrder.SubtotalCents + qTabOrder.TaxCents; newRunning = qTab.RunningTotalCents + orderTotal; if (newRunning > qTab.AuthAmountCents) { apiAbort({ "OK": false, "ERROR": "exceeds_authorization", "MESSAGE": "Approving this order would exceed your tab authorization. Increase your authorization first.", "RUNNING_TOTAL_CENTS": qTab.RunningTotalCents, "ORDER_CENTS": orderTotal, "AUTH_AMOUNT_CENTS": qTab.AuthAmountCents }); } // Approve queryTimed(" UPDATE TabOrders SET ApprovalStatus = 'approved', ApprovedByUserID = :approverID, ApprovedOn = NOW() WHERE TabID = :tabID AND OrderID = :orderID ", { approverID: { value: userID, cfsqltype: "cf_sql_integer" }, tabID: { value: tabID, cfsqltype: "cf_sql_integer" }, orderID: { value: orderID, cfsqltype: "cf_sql_integer" } }); // Update running total queryTimed(" UPDATE Tabs SET RunningTotalCents = :newRunning, LastActivityOn = NOW() WHERE ID = :tabID ", { newRunning: { value: newRunning, cfsqltype: "cf_sql_integer" }, tabID: { value: tabID, cfsqltype: "cf_sql_integer" } }); // Auto-submit order to kitchen (StatusID 0 → 1) qOrder = queryTimed("SELECT StatusID FROM Orders WHERE ID = :orderID LIMIT 1", { orderID: { value: orderID, cfsqltype: "cf_sql_integer" } }); if (qOrder.StatusID == 0) { queryTimed(" UPDATE Orders SET StatusID = 1, SubmittedOn = NOW(), LastEditedOn = NOW() WHERE ID = :orderID ", { orderID: { value: orderID, cfsqltype: "cf_sql_integer" } }); } apiAbort({ "OK": true, "RUNNING_TOTAL_CENTS": newRunning, "AUTH_REMAINING_CENTS": qTab.AuthAmountCents - newRunning }); } catch (any e) { apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message }); }