diff --git a/api/menu/getForBuilder.cfm b/api/menu/getForBuilder.cfm index 35e02bf..f728dd4 100644 --- a/api/menu/getForBuilder.cfm +++ b/api/menu/getForBuilder.cfm @@ -60,6 +60,16 @@ try { // Check for MenuID filter (optional - if provided, only return categories for that menu) menuID = structKeyExists(requestData, "MenuID") ? val(requestData.MenuID) : 0; + // Get business's default menu setting + defaultMenuID = 0; + try { + qBiz = queryTimed("SELECT DefaultMenuID FROM Businesses WHERE ID = :businessID", + { businessID: businessID }, { datasource: "payfrit" }); + if (qBiz.recordCount > 0 && !isNull(qBiz.DefaultMenuID)) { + defaultMenuID = val(qBiz.DefaultMenuID); + } + } catch (any e) {} + // Get all menus for this business allMenus = []; try { @@ -74,11 +84,11 @@ try { for (m = 1; m <= qMenus.recordCount; m++) { arrayAppend(allMenus, { "MenuID": qMenus.ID[m], - "Name": qMenus.Name[m], - "Description": isNull(qMenus.Description[m]) ? "" : qMenus.Description[m], - "DaysActive": qMenus.DaysActive[m], - "StartTime": isNull(qMenus.StartTime[m]) ? "" : timeFormat(qMenus.StartTime[m], "HH:mm"), - "EndTime": isNull(qMenus.EndTime[m]) ? "" : timeFormat(qMenus.EndTime[m], "HH:mm"), + "MenuName": qMenus.Name[m], + "MenuDescription": isNull(qMenus.Description[m]) ? "" : qMenus.Description[m], + "MenuDaysActive": qMenus.DaysActive[m], + "MenuStartTime": isNull(qMenus.StartTime[m]) ? "" : timeFormat(qMenus.StartTime[m], "HH:mm"), + "MenuEndTime": isNull(qMenus.EndTime[m]) ? "" : timeFormat(qMenus.EndTime[m], "HH:mm"), "SortOrder": qMenus.SortOrder[m] }); } @@ -113,8 +123,11 @@ try { // If exactly one menu is active now, auto-select it if (arrayLen(activeMenuIds) == 1) { menuID = activeMenuIds[1]; + } else if (arrayLen(activeMenuIds) > 1 && defaultMenuID > 0 && arrayFind(activeMenuIds, defaultMenuID)) { + // Multiple menus active - use business default if it's among the active ones + menuID = defaultMenuID; } - // If multiple match (overlap) or none match, show all (menuID stays 0) + // If multiple match with no default, or none match, show all (menuID stays 0) } } catch (any e) { // Menus table might not exist yet @@ -455,6 +468,7 @@ try { response["MENU"] = { "categories": categories }; response["MENUS"] = allMenus; response["SELECTED_MENU_ID"] = menuID; + response["DEFAULT_MENU_ID"] = defaultMenuID; response["TEMPLATES"] = templateLibrary; response["BRANDCOLOR"] = brandColor; response["CATEGORY_COUNT"] = arrayLen(categories); diff --git a/api/menu/menus.cfm b/api/menu/menus.cfm index 69a1c85..44570b2 100644 --- a/api/menu/menus.cfm +++ b/api/menu/menus.cfm @@ -234,6 +234,32 @@ try { response = { "OK": true, "ACTION": "reordered" }; break; + case "setDefault": + // Set the default menu for this business + menuID = structKeyExists(requestData, "MenuID") ? val(requestData.MenuID) : 0; + // MenuID of 0 means "no default" (clear the default) + + if (menuID > 0) { + // Verify the menu exists and belongs to this business + qCheck = queryTimed(" + SELECT ID FROM Menus WHERE ID = :menuID AND BusinessID = :businessID AND IsActive = 1 + ", { menuID: menuID, businessID: businessID }, { datasource: "payfrit" }); + + if (qCheck.recordCount == 0) { + apiAbort({ "OK": false, "ERROR": "invalid_menu", "MESSAGE": "Menu not found or not active" }); + } + } + + queryTimed(" + UPDATE Businesses SET DefaultMenuID = :menuID WHERE ID = :businessID + ", { + menuID: { value: menuID, cfsqltype: "cf_sql_integer", null: menuID == 0 }, + businessID: { value: businessID, cfsqltype: "cf_sql_integer" } + }, { datasource: "payfrit" }); + + response = { "OK": true, "ACTION": "defaultSet", "DefaultMenuID": menuID }; + break; + default: apiAbort({ "OK": false, "ERROR": "invalid_action", "MESSAGE": "Unknown action: " & action }); } diff --git a/api/orders/testMarkPaid.cfm b/api/orders/testMarkPaid.cfm new file mode 100644 index 0000000..6ea9ffc --- /dev/null +++ b/api/orders/testMarkPaid.cfm @@ -0,0 +1,55 @@ + + + + + +/** + * TEST ONLY: Mark an order as submitted and paid without Stripe + * This bypasses the payment flow for development testing + * + * POST: { OrderID: int } + */ + +response = { "OK": false }; + +try { + requestData = deserializeJSON(toString(getHttpRequestData().content)); + orderID = val(requestData.OrderID ?: 0); + + if (orderID == 0) { + response["ERROR"] = "OrderID is required"; + writeOutput(serializeJSON(response)); + abort; + } + + // Check order exists + qOrder = queryExecute(" + SELECT ID, StatusID, PaymentStatus FROM Orders WHERE ID = :orderID + ", { orderID: orderID }, { datasource: "payfrit" }); + + if (qOrder.recordCount == 0) { + response["ERROR"] = "Order not found"; + writeOutput(serializeJSON(response)); + abort; + } + + // Mark as submitted and paid + queryExecute(" + UPDATE Orders + SET StatusID = 1, + PaymentStatus = 'paid', + PaymentCompletedOn = NOW(), + SubmittedOn = COALESCE(SubmittedOn, NOW()), + LastEditedOn = NOW() + WHERE ID = :orderID + ", { orderID: orderID }, { datasource: "payfrit" }); + + response["OK"] = true; + response["MESSAGE"] = "Order #orderID# marked as submitted and paid"; + +} catch (any e) { + response["ERROR"] = e.message; +} + +writeOutput(serializeJSON(response)); + diff --git a/api/stripe/createPaymentIntent.cfm b/api/stripe/createPaymentIntent.cfm index 26e0793..f13082a 100644 --- a/api/stripe/createPaymentIntent.cfm +++ b/api/stripe/createPaymentIntent.cfm @@ -62,9 +62,9 @@ try { // Get business Stripe account qBusiness = queryExecute(" - SELECT StripeAccountID AS BusinessStripeAccountID, StripeOnboardingComplete AS BusinessStripeOnboardingComplete, Name AS BusinessName + SELECT StripeAccountID, StripeOnboardingComplete, Name FROM Businesses - WHERE BusinessID = :businessID + WHERE ID = :businessID ", { businessID: businessID }, { datasource: "payfrit" }); if (qBusiness.recordCount == 0) { @@ -103,7 +103,7 @@ try { } // For testing, allow orders even without Stripe Connect setup - hasStripeConnect = qBusiness.BusinessStripeOnboardingComplete == 1 && len(trim(qBusiness.BusinessStripeAccountID)) > 0; + hasStripeConnect = qBusiness.StripeOnboardingComplete == 1 && len(trim(qBusiness.StripeAccountID)) > 0; // ============================================================ // FEE CALCULATION @@ -138,7 +138,7 @@ try { // SP-SM: Add grant owner fee to platform fee (Payfrit collects, then transfers to owner) effectivePlatformFeeCents = totalPlatformFeeCents + grantOwnerFeeCents; httpService.addParam(type="formfield", name="application_fee_amount", value=effectivePlatformFeeCents); - httpService.addParam(type="formfield", name="transfer_data[destination]", value=qBusiness.BusinessStripeAccountID); + httpService.addParam(type="formfield", name="transfer_data[destination]", value=qBusiness.StripeAccountID); } httpService.addParam(type="formfield", name="metadata[order_id]", value=orderID); @@ -150,7 +150,7 @@ try { httpService.addParam(type="formfield", name="metadata[grant_owner_business_id]", value=grantOwnerBusinessID); httpService.addParam(type="formfield", name="metadata[grant_owner_fee_cents]", value=grantOwnerFeeCents); } - httpService.addParam(type="formfield", name="description", value="Order ###orderID# at #qBusiness.BusinessName#"); + httpService.addParam(type="formfield", name="description", value="Order ###orderID# at #qBusiness.Name#"); if (customerEmail != "") { httpService.addParam(type="formfield", name="receipt_email", value=customerEmail); diff --git a/api/tasks/complete.cfm b/api/tasks/complete.cfm index 0a8f62c..f0b36ff 100644 --- a/api/tasks/complete.cfm +++ b/api/tasks/complete.cfm @@ -37,6 +37,7 @@ + @@ -46,9 +47,13 @@ @@ -58,6 +63,7 @@ + @@ -74,7 +80,8 @@ - + + @@ -101,6 +108,77 @@ + + + + + + + + + + + + + = DATE_SUB(NOW(), INTERVAL 30 DAY) + ", [{ value = customerUserID, cfsqltype = "cf_sql_integer" }], { datasource = "payfrit" })> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -225,15 +364,26 @@ - + "LedgerCreated": ledgerCreated, + "CashProcessed": cashProcessed + }> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - +

Invites & Active Grants

@@ -447,8 +445,6 @@
- - + END COMMENTED OUT --> @@ -695,6 +692,7 @@ +
diff --git a/portal/menu-builder.html b/portal/menu-builder.html index cfb225a..5cc9652 100644 --- a/portal/menu-builder.html +++ b/portal/menu-builder.html @@ -4,7 +4,7 @@ Menu Builder - Payfrit - +