diff --git a/api/setup/saveWizard.cfm b/api/setup/saveWizard.cfm index 429759e..121e17c 100644 --- a/api/setup/saveWizard.cfm +++ b/api/setup/saveWizard.cfm @@ -33,29 +33,120 @@ try { data = deserializeJSON(requestBody); businessId = structKeyExists(data, "businessId") ? val(data.businessId) : 0; + userId = structKeyExists(data, "userId") ? val(data.userId) : 0; wizardData = structKeyExists(data, "data") ? data.data : {}; - - if (businessId == 0) { - throw(message="businessId is required"); - } - - // Verify business exists - qBiz = queryExecute(" - SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID = :id - ", { id: businessId }, { datasource: "payfrit" }); - - if (qBiz.recordCount == 0) { - throw(message="Business not found: " & businessId); - } - - response.steps.append("Found business: " & qBiz.BusinessName); - - // Update business info if provided biz = structKeyExists(wizardData, "business") ? wizardData.business : {}; - if (structKeyExists(biz, "name") && len(biz.name)) { - // Optionally update business name and other info - // For now we'll skip updating existing business - just add menu - response.steps.append("Business info available (not updating existing)"); + + // If no businessId, create a new business + if (businessId == 0) { + response.steps.append("No businessId provided - creating new business"); + + if (!structKeyExists(biz, "name") || !len(biz.name)) { + throw(message="Business name is required to create new business"); + } + + if (userId == 0) { + throw(message="userId is required to create new business"); + } + + // Create address record first (use extracted address fields) + addressLine1 = structKeyExists(biz, "addressLine1") ? biz.addressLine1 : ""; + city = structKeyExists(biz, "city") ? biz.city : ""; + state = structKeyExists(biz, "state") ? biz.state : ""; + zip = structKeyExists(biz, "zip") ? biz.zip : ""; + + // Look up state ID from state abbreviation + stateID = 0; + if (len(state)) { + qState = queryExecute(" + SELECT tt_StateID FROM tt_States WHERE tt_StateAbbreviation = :abbr + ", { abbr: uCase(state) }, { datasource: "payfrit" }); + + if (qState.recordCount > 0) { + stateID = qState.tt_StateID; + } + } + + queryExecute(" + INSERT INTO Addresses (AddressLine1, AddressCity, AddressStateID, AddressZIPCode, AddressUserID, AddressTypeID, AddressAddedOn) + VALUES (:line1, :city, :stateID, :zip, :userID, :typeID, NOW()) + ", { + line1: len(addressLine1) ? addressLine1 : "Address pending", + city: len(city) ? city : "", + stateID: stateID, + zip: len(zip) ? zip : "", + userID: userId, + typeID: 2 + }, { datasource: "payfrit" }); + + qNewAddr = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + addressId = qNewAddr.id; + response.steps.append("Created address record (ID: " & addressId & ")"); + + // Create new business with address link + queryExecute(" + INSERT INTO Businesses (BusinessName, BusinessUserID, BusinessAddressID, BusinessDeliveryZipCodes, BusinessAddedOn) + VALUES (:name, :userId, :addressId, :deliveryZips, NOW()) + ", { + name: biz.name, + userId: userId, + addressId: addressId, + deliveryZips: len(zip) ? zip : "" + }, { datasource: "payfrit" }); + + qNewBiz = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); + businessId = qNewBiz.id; + response.steps.append("Created new business: " & biz.name & " (ID: " & businessId & ")"); + + // Update address with business ID link + queryExecute(" + UPDATE Addresses SET AddressBusinessID = :businessID WHERE AddressID = :addressID + ", { + businessID: businessId, + addressID: addressId + }, { datasource: "payfrit" }); + response.steps.append("Linked address to business"); + + // Save business hours from structured schedule + if (structKeyExists(biz, "hoursSchedule") && isArray(biz.hoursSchedule)) { + hoursSchedule = biz.hoursSchedule; + response.steps.append("Processing " & arrayLen(hoursSchedule) & " days of hours"); + + for (i = 1; i <= arrayLen(hoursSchedule); i++) { + dayData = hoursSchedule[i]; + dayID = structKeyExists(dayData, "dayId") ? val(dayData.dayId) : 0; + openTime = structKeyExists(dayData, "open") ? dayData.open : "09:00"; + closeTime = structKeyExists(dayData, "close") ? dayData.close : "17:00"; + + // Convert HH:MM to HH:MM:SS if needed + if (len(openTime) == 5) openTime = openTime & ":00"; + if (len(closeTime) == 5) closeTime = closeTime & ":00"; + + // Insert hours record for this day + queryExecute(" + INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) + VALUES (:bizID, :dayID, :openTime, :closeTime) + ", { + bizID: businessId, + dayID: dayID, + openTime: openTime, + closeTime: closeTime + }, { datasource: "payfrit" }); + } + + response.steps.append("Created " & arrayLen(hoursSchedule) & " hours records"); + } + } else { + // Verify existing business exists + qBiz = queryExecute(" + SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID = :id + ", { id: businessId }, { datasource: "payfrit" }); + + if (qBiz.recordCount == 0) { + throw(message="Business not found: " & businessId); + } + + response.steps.append("Found existing business: " & qBiz.BusinessName); } // Build modifier template map @@ -77,21 +168,21 @@ try { WHERE i.ItemBusinessID = :bizID AND i.ItemName = :name AND i.ItemParentItemID = 0 - AND i.ItemIsCollapsible = 1 + AND i.ItemCategoryID = 0 ", { bizID: businessId, name: tmplName }, { datasource: "payfrit" }); if (qTmpl.recordCount > 0) { templateItemID = qTmpl.ItemID; response.steps.append("Template exists: " & tmplName & " (ID: " & templateItemID & ")"); } else { - // Create template as Item with ItemIsCollapsible=1 to mark as template + // Create template as Item with ItemCategoryID=0 to mark as template queryExecute(" INSERT INTO Items ( - ItemBusinessID, ItemName, ItemParentItemID, ItemPrice, + ItemBusinessID, ItemName, ItemParentItemID, ItemCategoryID, ItemPrice, ItemIsActive, ItemRequiresChildSelection, ItemMaxNumSelectionReq, - ItemSortOrder, ItemIsCollapsible + ItemSortOrder ) VALUES ( - :bizID, :name, 0, 0, 1, :required, 1, 0, 1 + :bizID, :name, 0, 0, 0, 1, :required, 1, 0 ) ", { bizID: businessId, @@ -109,6 +200,11 @@ try { // Create/update template options optionOrder = 1; for (opt in options) { + // Safety check: ensure opt is a struct with a name + if (!isStruct(opt) || !structKeyExists(opt, "name") || !len(opt.name)) { + continue; + } + optName = opt.name; optPrice = structKeyExists(opt, "price") ? val(opt.price) : 0; @@ -120,10 +216,10 @@ try { if (qOpt.recordCount == 0) { queryExecute(" INSERT INTO Items ( - ItemBusinessID, ItemName, ItemParentItemID, ItemPrice, - ItemIsActive, ItemSortOrder + ItemBusinessID, ItemName, ItemParentItemID, ItemCategoryID, + ItemPrice, ItemIsActive, ItemSortOrder ) VALUES ( - :bizID, :name, :parentID, :price, 1, :sortOrder + :bizID, :name, :parentID, 0, :price, 1, :sortOrder ) ", { bizID: businessId, @@ -139,7 +235,7 @@ try { // Build category map categories = structKeyExists(wizardData, "categories") ? wizardData.categories : []; - categoryMap = {}; // Maps category name to ItemID + categoryMap = {}; // Maps category name to CategoryID response.steps.append("Processing " & arrayLen(categories) & " categories..."); @@ -147,25 +243,22 @@ try { for (cat in categories) { catName = cat.name; - // Check if category exists (Item at ParentID=0, not a template) + // Check if category exists in Categories table qCat = queryExecute(" - SELECT ItemID FROM Items - WHERE ItemBusinessID = :bizID - AND ItemName = :name - AND ItemParentItemID = 0 - AND (ItemIsCollapsible IS NULL OR ItemIsCollapsible = 0) + SELECT CategoryID FROM Categories + WHERE CategoryBusinessID = :bizID AND CategoryName = :name ", { bizID: businessId, name: catName }, { datasource: "payfrit" }); if (qCat.recordCount > 0) { - categoryItemID = qCat.ItemID; - response.steps.append("Category exists: " & catName); + categoryID = qCat.CategoryID; + response.steps.append("Category exists: " & catName & " (ID: " & categoryID & ")"); } else { + // Create category in Categories table queryExecute(" - INSERT INTO Items ( - ItemBusinessID, ItemName, ItemParentItemID, ItemPrice, - ItemIsActive, ItemSortOrder, ItemIsCollapsible + INSERT INTO Categories ( + CategoryBusinessID, CategoryName, CategorySortOrder ) VALUES ( - :bizID, :name, 0, 0, 1, :sortOrder, 0 + :bizID, :name, :sortOrder ) ", { bizID: businessId, @@ -174,11 +267,11 @@ try { }, { datasource: "payfrit" }); qNewCat = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" }); - categoryItemID = qNewCat.id; - response.steps.append("Created category: " & catName & " (ID: " & categoryItemID & ")"); + categoryID = qNewCat.id; + response.steps.append("Created category: " & catName & " (ID: " & categoryID & ")"); } - categoryMap[catName] = categoryItemID; + categoryMap[catName] = categoryID; catOrder++; } @@ -206,7 +299,7 @@ try { continue; } - categoryItemID = categoryMap[itemCategory]; + categoryID = categoryMap[itemCategory]; // Track sort order within category if (!structKeyExists(categoryItemOrder, itemCategory)) { @@ -218,8 +311,10 @@ try { // Check if item exists qItem = queryExecute(" SELECT ItemID FROM Items - WHERE ItemBusinessID = :bizID AND ItemName = :name AND ItemParentItemID = :parentID - ", { bizID: businessId, name: itemName, parentID: categoryItemID }, { datasource: "payfrit" }); + WHERE ItemBusinessID = :bizID + AND ItemName = :name + AND ItemCategoryID = :catID + ", { bizID: businessId, name: itemName, catID: categoryID }, { datasource: "payfrit" }); if (qItem.recordCount > 0) { menuItemID = qItem.ItemID; @@ -240,15 +335,15 @@ try { queryExecute(" INSERT INTO Items ( ItemBusinessID, ItemName, ItemDescription, ItemParentItemID, - ItemPrice, ItemIsActive, ItemSortOrder + ItemCategoryID, ItemPrice, ItemIsActive, ItemSortOrder ) VALUES ( - :bizID, :name, :desc, :parentID, :price, 1, :sortOrder + :bizID, :name, :desc, 0, :catID, :price, 1, :sortOrder ) ", { bizID: businessId, name: itemName, desc: itemDesc, - parentID: categoryItemID, + catID: categoryID, price: itemPrice, sortOrder: itemOrder }, { datasource: "payfrit" }); diff --git a/portal/setup-wizard.html b/portal/setup-wizard.html index 845aaeb..3d8286e 100644 --- a/portal/setup-wizard.html +++ b/portal/setup-wizard.html @@ -651,8 +651,8 @@
Upload your menu images and I'll extract all the information for you
+Upload your menu images or PDFs and I'll extract then input all the information for you to preview!
I found your restaurant information:
| Day | +Open | +Close | +Closed | +
|---|---|---|---|
| ${day} | ++ + | ++ + | ++ + | +
Is this information correct?