/** * Portal Dashboard Stats * POST: { BusinessID: int } * Returns: { OK: true, STATS: { ordersToday, revenueToday, pendingOrders, menuItems } } */ response = { "OK": false }; try { // Get request data requestBody = toString(getHttpRequestData().content); if (len(requestBody) == 0) { response["ERROR"] = "Request body is required"; writeOutput(serializeJSON(response)); abort; } requestData = deserializeJSON(requestBody); businessID = val(requestData.BusinessID ?: 0); if (businessID == 0) { response["ERROR"] = "BusinessID is required"; writeOutput(serializeJSON(response)); abort; } // Get today's date boundaries as strings for MySQL todayStart = dateFormat(now(), "yyyy-mm-dd") & " 00:00:00"; todayEnd = dateFormat(now(), "yyyy-mm-dd") & " 23:59:59"; // Combined stats query — 1 round trip instead of 4 qStats = queryTimed(" SELECT (SELECT COUNT(*) FROM Orders WHERE OrderBusinessID = :businessID AND OrderSubmittedOn >= :todayStart AND OrderSubmittedOn <= :todayEnd) as ordersToday, (SELECT COALESCE(SUM(li.OrderLineItemQuantity * li.OrderLineItemPrice), 0) FROM Orders o JOIN OrderLineItems li ON li.OrderLineItemOrderID = o.OrderID WHERE o.OrderBusinessID = :businessID AND o.OrderSubmittedOn >= :todayStart AND o.OrderSubmittedOn <= :todayEnd AND o.OrderStatusID >= 1) as revenueToday, (SELECT COUNT(*) FROM Orders WHERE OrderBusinessID = :businessID AND OrderStatusID IN (1, 2)) as pendingOrders, (SELECT COUNT(*) FROM Items WHERE ItemBusinessID = :businessID AND ItemIsActive = 1 AND ItemParentItemID > 0) as menuItems ", { businessID: businessID, todayStart: { value: todayStart, cfsqltype: "cf_sql_varchar" }, todayEnd: { value: todayEnd, cfsqltype: "cf_sql_varchar" } }); response["OK"] = true; response["STATS"] = { "ordersToday": qStats.ordersToday, "revenueToday": qStats.revenueToday, "pendingOrders": qStats.pendingOrders, "menuItems": qStats.menuItems }; } catch (any e) { response["ERROR"] = e.message; } logPerf(); writeOutput(serializeJSON(response));