From 703a283d322e9059ae3f3a9ccb13f168dbc78c2d Mon Sep 17 00:00:00 2001 From: John Mizerek Date: Mon, 16 Feb 2026 12:53:57 -0800 Subject: [PATCH] Enable cart recovery API with optional business filter - getActiveCart now returns existing cart for user - Optional BusinessID parameter to filter by specific business - Used by Android app for cart recovery when scanning at a business Co-Authored-By: Claude Opus 4.5 --- api/orders/getActiveCart.cfm | 74 ++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/api/orders/getActiveCart.cfm b/api/orders/getActiveCart.cfm index 2e0a7a4..ae668ce 100644 --- a/api/orders/getActiveCart.cfm +++ b/api/orders/getActiveCart.cfm @@ -6,13 +6,79 @@ /** * Get the user's active cart (status=0) if one exists - * DISABLED: Always returns no cart - old carts are abandoned automatically + * Optionally filter by BusinessID to check for cart at specific business */ -// Always return no active cart - users start fresh each session +param name="url.UserID" type="numeric" default=0; +param name="url.BusinessID" type="numeric" default=0; + +if (url.UserID == 0) { + writeOutput(serializeJSON({ + "OK": false, + "ERROR": "UserID is required" + })); + abort; +} + +// Build query with optional business filter +sql = " + SELECT + o.ID as OrderID, + o.UUID as OrderUUID, + o.BusinessID, + b.Name as BusinessName, + o.OrderTypeID, + COALESCE(ot.Name, 'Undecided') as OrderTypeName, + o.ServicePointID, + COALESCE(sp.Name, '') as ServicePointName, + (SELECT COUNT(*) FROM OrderLineItems oli + WHERE oli.OrderID = o.ID AND oli.ParentOrderLineItemID = 0 AND oli.IsDeleted = 0) as ItemCount + FROM Orders o + INNER JOIN Businesses b ON b.ID = o.BusinessID + LEFT JOIN tt_OrderTypes ot ON ot.ID = o.OrderTypeID + LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID + WHERE o.UserID = :userId + AND o.StatusID = 0 +"; + +params = [{ name: "userId", value: url.UserID, cfsqltype: "integer" }]; + +if (url.BusinessID > 0) { + sql &= " AND o.BusinessID = :businessId"; + params.append({ name: "businessId", value: url.BusinessID, cfsqltype: "integer" }); +} + +sql &= " ORDER BY o.AddedOn DESC LIMIT 1"; + +query name="qCart" datasource="#request.ds#" { + writeOutput(sql); + for (p in params) { + cfqueryparam(value=p.value, cfsqltype=p.cfsqltype); + } +} + +if (qCart.recordCount == 0) { + writeOutput(serializeJSON({ + "OK": true, + "HAS_CART": false, + "CART": javacast("null", "") + })); + abort; +} + writeOutput(serializeJSON({ "OK": true, - "HAS_CART": false, - "CART": javacast("null", "") + "HAS_CART": true, + "CART": { + "OrderID": qCart.OrderID, + "OrderUUID": qCart.OrderUUID, + "BusinessID": qCart.BusinessID, + "BusinessName": qCart.BusinessName, + "OrderTypeID": qCart.OrderTypeID, + "OrderTypeName": qCart.OrderTypeName, + "ServicePointID": qCart.ServicePointID, + "ServicePointName": qCart.ServicePointName, + "ItemCount": qCart.ItemCount + } }));