@@ -160,14 +160,14 @@ function escapeHtml(s){
}
function loadIntoForm(sp){
- document.getElementById("ServicePointID").value = sp.ServicePointID || "";
- document.getElementById("ServicePointName").value = sp.ServicePointName || "";
- document.getElementById("ServicePointTypeID").value = (sp.ServicePointTypeID ?? 0);
- document.getElementById("ServicePointCode").value = sp.ServicePointCode || "";
+ document.getElementById("ServicePointID").value = sp.ID || "";
+ document.getElementById("Name").value = sp.Name || "";
+ document.getElementById("TypeID").value = (sp.TypeID ?? 0);
+ document.getElementById("Code").value = sp.Code || "";
document.getElementById("Description").value = sp.Description || "";
document.getElementById("SortOrder").value = (sp.SortOrder ?? 0);
document.getElementById("IsActive").value = ("" + (sp.IsActive ?? 1));
- document.getElementById("DelServicePointID").value = sp.ServicePointID || "";
+ document.getElementById("DelServicePointID").value = sp.ID || "";
}
async function refresh() {
@@ -181,10 +181,10 @@ async function refresh() {
for (const sp of items) {
const tr = document.createElement("tr");
tr.innerHTML = `
-
${sp.ServicePointID} |
-
${escapeHtml(sp.ServicePointName||"")} |
-
${sp.ServicePointTypeID} |
-
${escapeHtml(sp.ServicePointCode||"")} |
+
${sp.ID} |
+
${escapeHtml(sp.Name||"")} |
+
${sp.TypeID} |
+
${escapeHtml(sp.Code||"")} |
${sp.SortOrder} |
${sp.IsActive} |
`;
@@ -195,17 +195,17 @@ async function refresh() {
}
async function saveSP() {
- const name = (document.getElementById("ServicePointName").value || "").trim();
+ const name = (document.getElementById("Name").value || "").trim();
if (!name) {
- show({ OK:false, ERROR:"missing_servicepoint_name", MESSAGE:"ServicePointName is required" });
+ show({ OK:false, ERROR:"missing_servicepoint_name", MESSAGE:"Name is required" });
return;
}
const body = {
ServicePointID: valIntOrNull("ServicePointID"),
- ServicePointName: name,
- ServicePointTypeID: valIntOrZero("ServicePointTypeID"),
- ServicePointCode: (document.getElementById("ServicePointCode").value || "").trim(),
+ Name: name,
+ TypeID: valIntOrZero("TypeID"),
+ Code: (document.getElementById("Code").value || "").trim(),
Description: (document.getElementById("Description").value || "").trim(),
SortOrder: valIntOrZero("SortOrder"),
IsActive: parseInt(document.getElementById("IsActive").value, 10)
diff --git a/api/Application.cfm b/api/Application.cfm
index 8e1d4b3..3fef6e3 100644
--- a/api/Application.cfm
+++ b/api/Application.cfm
@@ -1,11 +1,6 @@
-
-
-
-
-
+
try {
- cached = appCacheGet("states", 86400);
- if (!isNull(cached)) {
- writeOutput(cached);
- abort;
- }
-
qStates = queryExecute("
- SELECT tt_StateID as StateID, tt_StateAbbreviation as StateAbbreviation, tt_StateName as StateName
+ SELECT tt_StateID as StateID, Abbreviation as StateAbbreviation, Name as StateName
FROM tt_States
- ORDER BY tt_StateName
+ ORDER BY Name
", {}, { datasource: "payfrit" });
states = [];
@@ -26,12 +20,10 @@ try {
});
}
- jsonResponse = serializeJSON({
+ writeOutput(serializeJSON({
"OK": true,
"STATES": states
- });
- appCachePut("states", jsonResponse);
- writeOutput(jsonResponse);
+ }));
} catch (any e) {
writeOutput(serializeJSON({
diff --git a/api/admin/addCategoryIsActiveColumn.cfm b/api/admin/addCategoryIsActiveColumn.cfm
index 65f53ab..046935d 100644
--- a/api/admin/addCategoryIsActiveColumn.cfm
+++ b/api/admin/addCategoryIsActiveColumn.cfm
@@ -2,25 +2,25 @@
-// Add TaskCategoryIsActive column to TaskCategories table
+// Add IsActive column to TaskCategories table
try {
// Check if column exists
qCheck = queryExecute("
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'TaskCategories'
- AND COLUMN_NAME = 'TaskCategoryIsActive'
+ AND COLUMN_NAME = 'IsActive'
", [], { datasource: "payfrit" });
if (qCheck.recordCount == 0) {
queryExecute("
ALTER TABLE TaskCategories
- ADD COLUMN TaskCategoryIsActive TINYINT(1) NOT NULL DEFAULT 1
+ ADD COLUMN IsActive TINYINT(1) NOT NULL DEFAULT 1
", [], { datasource: "payfrit" });
writeOutput(serializeJSON({
"OK": true,
- "MESSAGE": "Column TaskCategoryIsActive added to TaskCategories"
+ "MESSAGE": "Column IsActive added to TaskCategories"
}));
} else {
writeOutput(serializeJSON({
diff --git a/api/admin/addCategoryScheduleFields.cfm b/api/admin/addCategoryScheduleFields.cfm
index f5be694..963e600 100644
--- a/api/admin/addCategoryScheduleFields.cfm
+++ b/api/admin/addCategoryScheduleFields.cfm
@@ -8,9 +8,9 @@
* Add Schedule Fields to Categories Table
*
* Adds time-based scheduling fields:
- * - CategoryScheduleStart: TIME - Start time when category is available (e.g., 06:00:00 for breakfast)
- * - CategoryScheduleEnd: TIME - End time when category stops being available (e.g., 11:00:00)
- * - CategoryScheduleDays: VARCHAR(20) - Comma-separated list of day IDs (1=Sun, 2=Mon, etc.) or NULL for all days
+ * - ScheduleStart: TIME - Start time when category is available (e.g., 06:00:00 for breakfast)
+ * - ScheduleEnd: TIME - End time when category stops being available (e.g., 11:00:00)
+ * - ScheduleDays: VARCHAR(20) - Comma-separated list of day IDs (1=Sun, 2=Mon, etc.) or NULL for all days
*
* Run this once to migrate the schema.
*/
@@ -24,38 +24,38 @@ try {
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'Categories'
- AND COLUMN_NAME IN ('CategoryScheduleStart', 'CategoryScheduleEnd', 'CategoryScheduleDays')
+ AND COLUMN_NAME IN ('ScheduleStart', 'ScheduleEnd', 'ScheduleDays')
", {}, { datasource: "payfrit" });
existingCols = valueList(qCheck.COLUMN_NAME);
added = [];
- // Add CategoryScheduleStart if not exists
- if (!listFindNoCase(existingCols, "CategoryScheduleStart")) {
+ // Add ScheduleStart if not exists
+ if (!listFindNoCase(existingCols, "ScheduleStart")) {
queryExecute("
ALTER TABLE Categories
- ADD COLUMN CategoryScheduleStart TIME NULL
+ ADD COLUMN ScheduleStart TIME NULL
", {}, { datasource: "payfrit" });
- arrayAppend(added, "CategoryScheduleStart");
+ arrayAppend(added, "ScheduleStart");
}
- // Add CategoryScheduleEnd if not exists
- if (!listFindNoCase(existingCols, "CategoryScheduleEnd")) {
+ // Add ScheduleEnd if not exists
+ if (!listFindNoCase(existingCols, "ScheduleEnd")) {
queryExecute("
ALTER TABLE Categories
- ADD COLUMN CategoryScheduleEnd TIME NULL
+ ADD COLUMN ScheduleEnd TIME NULL
", {}, { datasource: "payfrit" });
- arrayAppend(added, "CategoryScheduleEnd");
+ arrayAppend(added, "ScheduleEnd");
}
- // Add CategoryScheduleDays if not exists
- if (!listFindNoCase(existingCols, "CategoryScheduleDays")) {
+ // Add ScheduleDays if not exists
+ if (!listFindNoCase(existingCols, "ScheduleDays")) {
queryExecute("
ALTER TABLE Categories
- ADD COLUMN CategoryScheduleDays VARCHAR(20) NULL
+ ADD COLUMN ScheduleDays VARCHAR(20) NULL
", {}, { datasource: "payfrit" });
- arrayAppend(added, "CategoryScheduleDays");
+ arrayAppend(added, "ScheduleDays");
}
response["OK"] = true;
diff --git a/api/admin/addDrinkModifiers.cfm b/api/admin/addDrinkModifiers.cfm
index ec4cea2..81b24d6 100644
--- a/api/admin/addDrinkModifiers.cfm
+++ b/api/admin/addDrinkModifiers.cfm
@@ -15,8 +15,8 @@ try {
// Find the Fountain Soda item we created
qFountain = queryExecute("
- SELECT ItemID, ItemName FROM Items
- WHERE ItemBusinessID = :bizId AND ItemName = 'Fountain Soda'
+ SELECT ID, Name FROM Items
+ WHERE BusinessID = :bizId AND Name = 'Fountain Soda'
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
if (qFountain.recordCount == 0) {
@@ -31,13 +31,13 @@ try {
// Update Fountain Soda to require child selection and be collapsible
queryExecute("
UPDATE Items
- SET ItemRequiresChildSelection = 1, ItemIsCollapsible = 1
+ SET RequiresChildSelection = 1, IsCollapsible = 1
WHERE ItemID = :itemId
", { itemId: fountainId }, { datasource: "payfrit" });
// Check if modifiers already exist
qExisting = queryExecute("
- SELECT COUNT(*) as cnt FROM Items WHERE ItemParentItemID = :parentId
+ SELECT COUNT(*) as cnt FROM Items WHERE ParentItemID = :parentId
", { parentId: fountainId }, { datasource: "payfrit" });
if (qExisting.cnt > 0) {
@@ -53,10 +53,10 @@ try {
queryExecute("
INSERT INTO Items (
- ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
- ItemName, ItemDescription, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemIsCollapsible, ItemRequiresChildSelection,
- ItemMaxNumSelectionReq, ItemAddedOn
+ ItemID, BusinessID, CategoryID, ParentItemID,
+ Name, Description, Price, IsActive,
+ SortOrder, IsCollapsible, RequiresChildSelection,
+ MaxNumSelectionReq, AddedOn
) VALUES (
:itemId, :bizId, 0, :parentId,
'Size', 'Choose your size', 0, 1,
@@ -80,10 +80,10 @@ try {
qMaxItem = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
queryExecute("
INSERT INTO Items (
- ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
- ItemName, ItemDescription, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemIsCollapsible, ItemIsCheckedByDefault,
- ItemAddedOn
+ ItemID, BusinessID, CategoryID, ParentItemID,
+ Name, Description, Price, IsActive,
+ SortOrder, IsCollapsible, IsCheckedByDefault,
+ AddedOn
) VALUES (
:itemId, :bizId, 0, :parentId,
:name, '', :price, 1,
@@ -108,10 +108,10 @@ try {
queryExecute("
INSERT INTO Items (
- ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
- ItemName, ItemDescription, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemIsCollapsible, ItemRequiresChildSelection,
- ItemMaxNumSelectionReq, ItemAddedOn
+ ItemID, BusinessID, CategoryID, ParentItemID,
+ Name, Description, Price, IsActive,
+ SortOrder, IsCollapsible, RequiresChildSelection,
+ MaxNumSelectionReq, AddedOn
) VALUES (
:itemId, :bizId, 0, :parentId,
'Flavor', 'Choose your drink', 0, 1,
@@ -139,10 +139,10 @@ try {
qMaxItem = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
queryExecute("
INSERT INTO Items (
- ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
- ItemName, ItemDescription, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemIsCollapsible, ItemIsCheckedByDefault,
- ItemAddedOn
+ ItemID, BusinessID, CategoryID, ParentItemID,
+ Name, Description, Price, IsActive,
+ SortOrder, IsCollapsible, IsCheckedByDefault,
+ AddedOn
) VALUES (
:itemId, :bizId, 0, :parentId,
:name, '', 0, 1,
diff --git a/api/admin/addItemCategoryColumn.cfm b/api/admin/addItemCategoryColumn.cfm
index 61589f2..c04b791 100644
--- a/api/admin/addItemCategoryColumn.cfm
+++ b/api/admin/addItemCategoryColumn.cfm
@@ -5,7 +5,7 @@
/**
- * Add ItemCategoryID column to Items table
+ * Add CategoryID column to Items table
*/
response = { "OK": false };
@@ -17,30 +17,30 @@ try {
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'Items'
- AND COLUMN_NAME = 'ItemCategoryID'
+ AND COLUMN_NAME = 'CategoryID'
", {}, { datasource: "payfrit" });
if (qCheck.recordCount > 0) {
response["OK"] = true;
- response["MESSAGE"] = "ItemCategoryID column already exists";
+ response["MESSAGE"] = "CategoryID column already exists";
} else {
// Add the column
queryExecute("
ALTER TABLE Items
- ADD COLUMN ItemCategoryID INT NULL DEFAULT 0 AFTER ItemParentItemID
+ ADD COLUMN CategoryID INT NULL DEFAULT 0 AFTER ParentItemID
", {}, { datasource: "payfrit" });
// Add index for performance
try {
queryExecute("
- CREATE INDEX idx_items_categoryid ON Items(ItemCategoryID)
+ CREATE INDEX idx_items_categoryid ON Items(CategoryID)
", {}, { datasource: "payfrit" });
} catch (any indexErr) {
// Index might already exist
}
response["OK"] = true;
- response["MESSAGE"] = "ItemCategoryID column added successfully";
+ response["MESSAGE"] = "CategoryID column added successfully";
}
} catch (any e) {
diff --git a/api/admin/addLatLng.cfm b/api/admin/addLatLng.cfm
index 983cda6..5c89c1d 100644
--- a/api/admin/addLatLng.cfm
+++ b/api/admin/addLatLng.cfm
@@ -6,7 +6,7 @@
try {
// Check if columns already exist
checkCols = queryExecute(
- "SHOW COLUMNS FROM Addresses LIKE 'AddressLat'",
+ "SHOW COLUMNS FROM Addresses LIKE 'Latitude'",
[],
{ datasource = "payfrit" }
);
@@ -15,8 +15,8 @@ try {
// Add the columns
queryExecute(
"ALTER TABLE Addresses
- ADD COLUMN AddressLat DECIMAL(10,7) NULL,
- ADD COLUMN AddressLng DECIMAL(10,7) NULL",
+ ADD COLUMN Latitude DECIMAL(10,7) NULL,
+ ADD COLUMN Longitude DECIMAL(10,7) NULL",
[],
{ datasource = "payfrit" }
);
diff --git a/api/admin/addServiceCategoryColumn.cfm b/api/admin/addServiceCategoryColumn.cfm
index 9a7939d..bdbccbc 100644
--- a/api/admin/addServiceCategoryColumn.cfm
+++ b/api/admin/addServiceCategoryColumn.cfm
@@ -9,18 +9,18 @@ try {
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'tt_TaskTypes'
- AND COLUMN_NAME = 'tt_TaskTypeCategoryID'
+ AND COLUMN_NAME = 'TaskCategoryID'
", [], { datasource: "payfrit" });
if (qCheck.recordCount == 0) {
queryExecute("
ALTER TABLE tt_TaskTypes
- ADD COLUMN tt_TaskTypeCategoryID INT NULL
+ ADD COLUMN TaskCategoryID INT NULL
", [], { datasource: "payfrit" });
writeOutput(serializeJSON({
"OK": true,
- "MESSAGE": "Column tt_TaskTypeCategoryID added to tt_TaskTypes"
+ "MESSAGE": "Column TaskCategoryID added to tt_TaskTypes"
}));
} else {
writeOutput(serializeJSON({
diff --git a/api/admin/addTaskSourceColumns.cfm b/api/admin/addTaskSourceColumns.cfm
index 20b5147..df621f0 100644
--- a/api/admin/addTaskSourceColumns.cfm
+++ b/api/admin/addTaskSourceColumns.cfm
@@ -3,7 +3,7 @@
-// Add TaskSourceType and TaskSourceID columns to Tasks table
+// Add SourceType and SourceID columns to Tasks table
// These are needed for chat persistence feature
result = { "OK": true, "STEPS": [] };
@@ -15,30 +15,30 @@ try {
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'Tasks'
- AND COLUMN_NAME IN ('TaskSourceType', 'TaskSourceID')
+ AND COLUMN_NAME IN ('SourceType', 'SourceID')
", [], { datasource: "payfrit" });
existingCols = valueList(cols.COLUMN_NAME);
arrayAppend(result.STEPS, "Existing columns: #existingCols#");
- // Add TaskSourceType if missing
- if (!listFindNoCase(existingCols, "TaskSourceType")) {
+ // Add SourceType if missing
+ if (!listFindNoCase(existingCols, "SourceType")) {
queryExecute("
- ALTER TABLE Tasks ADD COLUMN TaskSourceType VARCHAR(50) NULL
+ ALTER TABLE Tasks ADD COLUMN SourceType VARCHAR(50) NULL
", [], { datasource: "payfrit" });
- arrayAppend(result.STEPS, "Added TaskSourceType column");
+ arrayAppend(result.STEPS, "Added SourceType column");
} else {
- arrayAppend(result.STEPS, "TaskSourceType already exists");
+ arrayAppend(result.STEPS, "SourceType already exists");
}
- // Add TaskSourceID if missing
- if (!listFindNoCase(existingCols, "TaskSourceID")) {
+ // Add SourceID if missing
+ if (!listFindNoCase(existingCols, "SourceID")) {
queryExecute("
- ALTER TABLE Tasks ADD COLUMN TaskSourceID INT NULL
+ ALTER TABLE Tasks ADD COLUMN SourceID INT NULL
", [], { datasource: "payfrit" });
- arrayAppend(result.STEPS, "Added TaskSourceID column");
+ arrayAppend(result.STEPS, "Added SourceID column");
} else {
- arrayAppend(result.STEPS, "TaskSourceID already exists");
+ arrayAppend(result.STEPS, "SourceID already exists");
}
// Verify columns now exist
@@ -47,7 +47,7 @@ try {
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'Tasks'
- AND COLUMN_NAME IN ('TaskSourceType', 'TaskSourceID')
+ AND COLUMN_NAME IN ('SourceType', 'SourceID')
", [], { datasource: "payfrit" });
result.COLUMNS = [];
diff --git a/api/admin/beaconStatus.cfm b/api/admin/beaconStatus.cfm
index 1eab4df..7252e25 100644
--- a/api/admin/beaconStatus.cfm
+++ b/api/admin/beaconStatus.cfm
@@ -6,49 +6,49 @@
// Show all beacons with their current business/service point assignments
q = queryExecute("
SELECT
- b.BeaconID,
- b.BeaconUUID,
- b.BeaconName,
- lt.BusinessID,
- lt.ServicePointID,
- biz.BusinessName,
- sp.ServicePointName
+ b.ID,
+ b.UUID,
+ b.Name,
+ sp_link.BusinessID,
+ sp_link.ID,
+ biz.Name,
+ sp.Name
FROM Beacons b
- LEFT JOIN lt_Beacon_Businesses_ServicePoints lt ON lt.BeaconID = b.BeaconID
- LEFT JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
- WHERE b.BeaconIsActive = 1
- ORDER BY b.BeaconID
+ LEFT JOIN ServicePoints sp_link ON sp_link.BeaconID = b.ID
+ LEFT JOIN Businesses biz ON biz.ID = sp_link.BusinessID
+ LEFT JOIN ServicePoints sp ON sp.ID = sp_link.ID
+ WHERE b.IsActive = 1
+ ORDER BY b.ID
", {}, { datasource: "payfrit" });
rows = [];
for (row in q) {
arrayAppend(rows, {
- "BeaconID": row.BeaconID,
- "BeaconUUID": row.BeaconUUID,
- "BeaconName": row.BeaconName ?: "",
+ "BeaconID": row.ID,
+ "UUID": row.UUID,
+ "Name": row.Name ?: "",
"BusinessID": row.BusinessID ?: 0,
- "BusinessName": row.BusinessName ?: "",
+ "Name": row.Name ?: "",
"ServicePointID": row.ServicePointID ?: 0,
- "ServicePointName": row.ServicePointName ?: ""
+ "Name": row.Name ?: ""
});
}
// Also get service points for reference
spQuery = queryExecute("
- SELECT sp.ServicePointID, sp.ServicePointName, sp.ServicePointBusinessID, b.BusinessName
+ SELECT sp.ID, sp.Name, sp.BusinessID, b.Name
FROM ServicePoints sp
- JOIN Businesses b ON b.BusinessID = sp.ServicePointBusinessID
- ORDER BY sp.ServicePointBusinessID, sp.ServicePointID
+ JOIN Businesses b ON b.ID = sp.BusinessID
+ ORDER BY sp.BusinessID, sp.ID
", {}, { datasource: "payfrit" });
servicePoints = [];
for (sp in spQuery) {
arrayAppend(servicePoints, {
- "ServicePointID": sp.ServicePointID,
- "ServicePointName": sp.ServicePointName,
- "BusinessID": sp.ServicePointBusinessID,
- "BusinessName": sp.BusinessName
+ "ServicePointID": sp.ID,
+ "Name": sp.Name,
+ "BusinessID": sp.BusinessID,
+ "Name": sp.Name
});
}
diff --git a/api/admin/checkBigDeans.cfm b/api/admin/checkBigDeans.cfm
index 5262e7c..ef674a7 100644
--- a/api/admin/checkBigDeans.cfm
+++ b/api/admin/checkBigDeans.cfm
@@ -5,16 +5,16 @@
// Check Big Dean's owner
q = queryExecute("
- SELECT b.BusinessID, b.BusinessName, b.BusinessUserID
+ SELECT b.ID, b.Name, b.UserID
FROM Businesses b
- WHERE b.BusinessID = 27
+ WHERE b.ID = 27
", {}, { datasource: "payfrit" });
// Get users
users = queryExecute("
SELECT *
FROM Users
- ORDER BY UserID
+ ORDER BY ID
LIMIT 20
", {}, { datasource: "payfrit" });
@@ -23,9 +23,9 @@ colNames = users.getColumnNames();
writeOutput(serializeJSON({
"OK": true,
"BigDeans": {
- "BusinessID": q.BusinessID,
- "BusinessName": q.BusinessName,
- "BusinessUserID": q.BusinessUserID
+ "BusinessID": q.ID,
+ "Name": q.Name,
+ "UserID": q.UserID
},
"UserColumns": colNames,
"UserCount": users.recordCount
diff --git a/api/admin/checkUser.cfm b/api/admin/checkUser.cfm
index 1f558e5..6994ce8 100644
--- a/api/admin/checkUser.cfm
+++ b/api/admin/checkUser.cfm
@@ -12,9 +12,9 @@ if (!len(phone)) {
}
q = queryExecute("
- SELECT UserID, UserFirstName, UserLastName, UserEmail, UserPhone, UserIsContactVerified
+ SELECT ID, FirstName, LastName, EmailAddress, ContactNumber, IsContactVerified
FROM Users
- WHERE UserPhone = :phone OR UserEmail = :phone
+ WHERE ContactNumber = :phone OR EmailAddress = :phone
LIMIT 1
", { phone: phone }, { datasource: "payfrit" });
@@ -25,11 +25,11 @@ if (q.recordCount EQ 0) {
writeOutput(serializeJSON({
"OK": true,
- "UserID": q.UserID,
- "FirstName": q.UserFirstName,
- "LastName": q.UserLastName,
- "Email": q.UserEmail,
- "Phone": q.UserPhone,
- "Verified": q.UserIsContactVerified
+ "UserID": q.ID,
+ "FirstName": q.FirstName,
+ "LastName": q.LastName,
+ "Email": q.EmailAddress,
+ "Phone": q.ContactNumber,
+ "Verified": q.IsContactVerified
}));
diff --git a/api/admin/cleanupBeacons.cfm b/api/admin/cleanupBeacons.cfm
index c8b925a..40dba28 100644
--- a/api/admin/cleanupBeacons.cfm
+++ b/api/admin/cleanupBeacons.cfm
@@ -5,7 +5,8 @@
/**
* Cleanup Lazy Daisy Beacons
- * - Removes duplicate beacons created by setupBeaconTables
+ * - Unassigns beacons 7, 8, 9 from service points
+ * - Deletes beacons 7, 8, 9
* - Updates original beacons with proper names
*/
response = { "OK": false, "steps": [] };
@@ -13,52 +14,50 @@ response = { "OK": false, "steps": [] };
try {
lazyDaisyID = 37;
- // Delete duplicate assignments for beacons 7, 8, 9
+ // Unassign beacons 7, 8, 9 from any service points
queryExecute("
- DELETE FROM lt_Beacon_Businesses_ServicePoints
+ UPDATE ServicePoints
+ SET BeaconID = NULL, AssignedByUserID = NULL
WHERE BeaconID IN (7, 8, 9) AND BusinessID = :bizId
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
- response.steps.append("Deleted duplicate assignments for beacons 7, 8, 9");
+ response.steps.append("Unassigned beacons 7, 8, 9 from service points");
// Delete duplicate beacons 7, 8, 9
queryExecute("
DELETE FROM Beacons
- WHERE BeaconID IN (7, 8, 9) AND BeaconBusinessID = :bizId
+ WHERE ID IN (7, 8, 9) AND BusinessID = :bizId
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
response.steps.append("Deleted duplicate beacons 7, 8, 9");
// Update original beacons with names based on their service point assignments
- // Beacon 4 -> Table 1 (ServicePointID 4)
- // Beacon 5 -> Table 2 (ServicePointID 5)
- // Beacon 6 -> Table 3 (ServicePointID 6)
-
queryExecute("
- UPDATE Beacons SET BeaconName = 'Beacon - Table 1'
- WHERE BeaconID = 4 AND BeaconBusinessID = :bizId
+ UPDATE Beacons SET Name = 'Beacon - Table 1'
+ WHERE ID = 4 AND BusinessID = :bizId
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
response.steps.append("Updated Beacon 4 name to 'Beacon - Table 1'");
queryExecute("
- UPDATE Beacons SET BeaconName = 'Beacon - Table 2'
- WHERE BeaconID = 5 AND BeaconBusinessID = :bizId
+ UPDATE Beacons SET Name = 'Beacon - Table 2'
+ WHERE ID = 5 AND BusinessID = :bizId
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
response.steps.append("Updated Beacon 5 name to 'Beacon - Table 2'");
queryExecute("
- UPDATE Beacons SET BeaconName = 'Beacon - Table 3'
- WHERE BeaconID = 6 AND BeaconBusinessID = :bizId
+ UPDATE Beacons SET Name = 'Beacon - Table 3'
+ WHERE ID = 6 AND BusinessID = :bizId
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
response.steps.append("Updated Beacon 6 name to 'Beacon - Table 3'");
// Get final status
qFinal = queryExecute("
- SELECT lt.BeaconID, b.BeaconUUID, b.BeaconName, lt.BusinessID, biz.BusinessName, lt.ServicePointID, sp.ServicePointName
- FROM lt_Beacon_Businesses_ServicePoints lt
- JOIN Beacons b ON b.BeaconID = lt.BeaconID
- JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
- WHERE lt.BusinessID = :bizId
- ORDER BY lt.BeaconID
+ SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
+ b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
+ biz.Name AS BusinessName
+ FROM ServicePoints sp
+ JOIN Beacons b ON b.ID = sp.BeaconID
+ JOIN Businesses biz ON biz.ID = sp.BusinessID
+ WHERE sp.BusinessID = :bizId AND sp.BeaconID IS NOT NULL
+ ORDER BY sp.BeaconID
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
beacons = [];
@@ -66,8 +65,9 @@ try {
arrayAppend(beacons, {
"BeaconID": qFinal.BeaconID[i],
"BeaconName": qFinal.BeaconName[i],
- "UUID": qFinal.BeaconUUID[i],
+ "UUID": qFinal.UUID[i],
"BusinessName": qFinal.BusinessName[i],
+ "ServicePointID": qFinal.ServicePointID[i],
"ServicePointName": qFinal.ServicePointName[i]
});
}
diff --git a/api/admin/cleanupCategories.cfm b/api/admin/cleanupCategories.cfm
index 2f73a50..b842664 100644
--- a/api/admin/cleanupCategories.cfm
+++ b/api/admin/cleanupCategories.cfm
@@ -13,10 +13,10 @@
* Cleanup Categories - Final step after migration verification
*
* This script:
- * 1. Verifies all Items have ItemBusinessID set
+ * 1. Verifies all Items have BusinessID set
* 2. Finds orphan items (ParentID=0, no children, not in links)
- * 3. Drops ItemCategoryID column
- * 4. Drops ItemIsModifierTemplate column (derived from ItemTemplateLinks now)
+ * 3. Drops CategoryID column
+ * 4. Drops IsModifierTemplate column (derived from lt_ItemID_TemplateItemID now)
* 5. Drops Categories table
*
* Query param: ?confirm=YES to actually execute (otherwise shows verification only)
@@ -30,7 +30,7 @@ try {
// Verification Step 1: Check for items without BusinessID
qNoBusinessID = queryExecute("
SELECT COUNT(*) as cnt FROM Items
- WHERE ItemBusinessID IS NULL OR ItemBusinessID = 0
+ WHERE BusinessID IS NULL OR BusinessID = 0
", {}, { datasource: "payfrit" });
response.verification["itemsWithoutBusinessID"] = qNoBusinessID.cnt;
@@ -46,38 +46,38 @@ try {
qCategoryItems = queryExecute("
SELECT COUNT(DISTINCT p.ItemID) as cnt
FROM Items p
- INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
- WHERE p.ItemParentItemID = 0
- AND p.ItemBusinessID > 0
+ INNER JOIN Items c ON c.ParentItemID = p.ItemID
+ WHERE p.ParentItemID = 0
+ AND p.BusinessID > 0
AND NOT EXISTS (
- SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
+ SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ItemID
)
", {}, { datasource: "payfrit" });
response.verification["categoryItemsCreated"] = qCategoryItems.cnt;
- // Verification Step 4: Check templates exist (in ItemTemplateLinks)
+ // Verification Step 4: Check templates exist (in lt_ItemID_TemplateItemID)
qTemplates = queryExecute("
SELECT COUNT(DISTINCT tl.TemplateItemID) as cnt
- FROM ItemTemplateLinks tl
+ FROM lt_ItemID_TemplateItemID tl
INNER JOIN Items t ON t.ItemID = tl.TemplateItemID
", {}, { datasource: "payfrit" });
response.verification["templatesInLinks"] = qTemplates.cnt;
// Verification Step 5: Find orphans at ParentID=0
- // Orphan = ParentID=0, no children pointing to it, not in ItemTemplateLinks
+ // Orphan = ParentID=0, no children pointing to it, not in lt_ItemID_TemplateItemID
qOrphans = queryExecute("
- SELECT i.ItemID, i.ItemName, i.ItemBusinessID
+ SELECT i.ID, i.Name, i.BusinessID
FROM Items i
- WHERE i.ItemParentItemID = 0
+ WHERE i.ParentItemID = 0
AND NOT EXISTS (
- SELECT 1 FROM Items child WHERE child.ItemParentItemID = i.ItemID
+ SELECT 1 FROM Items child WHERE child.ParentItemID = i.ID
)
AND NOT EXISTS (
- SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID
+ SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = i.ID
)
- ORDER BY i.ItemBusinessID, i.ItemName
+ ORDER BY i.BusinessID, i.Name
", {}, { datasource: "payfrit" });
response.verification["orphanCount"] = qOrphans.recordCount;
@@ -85,8 +85,8 @@ try {
for (orphan in qOrphans) {
arrayAppend(response.orphans, {
"ItemID": orphan.ItemID,
- "ItemName": orphan.ItemName,
- "BusinessID": orphan.ItemBusinessID
+ "Name": orphan.Name,
+ "BusinessID": orphan.BusinessID
});
}
@@ -96,7 +96,7 @@ try {
if (!safeToCleanup) {
arrayAppend(response.steps, "VERIFICATION FAILED - Cannot cleanup yet");
- arrayAppend(response.steps, "- " & qNoBusinessID.cnt & " items still missing ItemBusinessID");
+ arrayAppend(response.steps, "- " & qNoBusinessID.cnt & " items still missing BusinessID");
response["OK"] = false;
writeOutput(serializeJSON(response));
abort;
@@ -119,31 +119,31 @@ try {
// Execute cleanup
arrayAppend(response.steps, "Executing cleanup...");
- // Step 1: Drop ItemCategoryID column
+ // Step 1: Drop CategoryID column
try {
queryExecute("
- ALTER TABLE Items DROP COLUMN ItemCategoryID
+ ALTER TABLE Items DROP COLUMN CategoryID
", {}, { datasource: "payfrit" });
- arrayAppend(response.steps, "Dropped ItemCategoryID column from Items");
+ arrayAppend(response.steps, "Dropped CategoryID column from Items");
} catch (any e) {
if (findNoCase("check that column", e.message) || findNoCase("Unknown column", e.message)) {
- arrayAppend(response.steps, "ItemCategoryID column already dropped");
+ arrayAppend(response.steps, "CategoryID column already dropped");
} else {
- arrayAppend(response.steps, "Warning dropping ItemCategoryID: " & e.message);
+ arrayAppend(response.steps, "Warning dropping CategoryID: " & e.message);
}
}
- // Step 2: Drop ItemIsModifierTemplate column (now derived from ItemTemplateLinks)
+ // Step 2: Drop IsModifierTemplate column (now derived from lt_ItemID_TemplateItemID)
try {
queryExecute("
- ALTER TABLE Items DROP COLUMN ItemIsModifierTemplate
+ ALTER TABLE Items DROP COLUMN IsModifierTemplate
", {}, { datasource: "payfrit" });
- arrayAppend(response.steps, "Dropped ItemIsModifierTemplate column from Items");
+ arrayAppend(response.steps, "Dropped IsModifierTemplate column from Items");
} catch (any e) {
if (findNoCase("check that column", e.message) || findNoCase("Unknown column", e.message)) {
- arrayAppend(response.steps, "ItemIsModifierTemplate column already dropped");
+ arrayAppend(response.steps, "IsModifierTemplate column already dropped");
} else {
- arrayAppend(response.steps, "Warning dropping ItemIsModifierTemplate: " & e.message);
+ arrayAppend(response.steps, "Warning dropping IsModifierTemplate: " & e.message);
}
}
diff --git a/api/admin/cleanupDuplicateEmployees.cfm b/api/admin/cleanupDuplicateEmployees.cfm
index c2f5170..40e76d8 100644
--- a/api/admin/cleanupDuplicateEmployees.cfm
+++ b/api/admin/cleanupDuplicateEmployees.cfm
@@ -34,8 +34,8 @@ if (businessId <= 0) {
try {
// Find duplicate UserIDs for this business (keep the one with highest status or oldest)
qDupes = queryExecute("
- SELECT UserID, COUNT(*) as cnt, MIN(EmployeeID) as keepId
- FROM lt_Users_Businesses_Employees
+ SELECT ID, COUNT(*) as cnt, MIN(ID) as keepId
+ FROM Employees
WHERE BusinessID = ?
GROUP BY UserID
HAVING COUNT(*) > 1
@@ -45,8 +45,8 @@ try {
for (row in qDupes) {
// Delete all but the one we want to keep (the one with lowest EmployeeID)
qDel = queryExecute("
- DELETE FROM lt_Users_Businesses_Employees
- WHERE BusinessID = ? AND UserID = ? AND EmployeeID != ?
+ DELETE FROM Employees
+ WHERE BusinessID = ? AND UserID = ? AND ID != ?
", [
{ value: businessId, cfsqltype: "cf_sql_integer" },
{ value: row.UserID, cfsqltype: "cf_sql_integer" },
@@ -57,19 +57,19 @@ try {
// Get remaining employees
qRemaining = queryExecute("
- SELECT e.EmployeeID, e.UserID, u.UserFirstName, u.UserLastName
- FROM lt_Users_Businesses_Employees e
- JOIN Users u ON e.UserID = u.UserID
+ SELECT e.ID, e.UserID, u.FirstName, u.LastName
+ FROM Employees e
+ JOIN Users u ON e.UserID = u.ID
WHERE e.BusinessID = ?
- ORDER BY e.EmployeeID
+ ORDER BY e.ID
", [{ value: businessId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
remaining = [];
for (r in qRemaining) {
arrayAppend(remaining, {
- "EmployeeID": r.EmployeeID,
+ "EmployeeID": r.ID,
"UserID": r.UserID,
- "Name": trim(r.UserFirstName & " " & r.UserLastName)
+ "Name": trim(r.FirstName & " " & r.LastName)
});
}
diff --git a/api/admin/cleanupForLazyDaisy.cfm b/api/admin/cleanupForLazyDaisy.cfm
index b663b50..e4ff9ac 100644
--- a/api/admin/cleanupForLazyDaisy.cfm
+++ b/api/admin/cleanupForLazyDaisy.cfm
@@ -9,106 +9,120 @@ try {
// Keep only Lazy Daisy (BusinessID 37)
keepBusinessID = 37;
- // First, reassign all beacons to Lazy Daisy
+ // Unassign all beacons from service points of other businesses
queryExecute("
- UPDATE lt_Beacon_Businesses_ServicePoints
- SET BusinessID = :keepID
+ UPDATE ServicePoints
+ SET BeaconID = NULL, AssignedByUserID = NULL
+ WHERE BusinessID != :keepID AND BeaconID IS NOT NULL
", { keepID: keepBusinessID }, { datasource: "payfrit" });
- response.steps.append("Reassigned all beacons to Lazy Daisy");
+ response.steps.append("Unassigned beacons from other businesses' service points");
// Get list of businesses to delete
qBiz = queryExecute("
- SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID != :keepID
+ SELECT ID, Name FROM Businesses WHERE ID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
deletedBusinesses = [];
for (i = 1; i <= qBiz.recordCount; i++) {
- arrayAppend(deletedBusinesses, qBiz.BusinessName[i]);
+ arrayAppend(deletedBusinesses, qBiz.Name[i]);
}
response.steps.append("Found " & qBiz.recordCount & " businesses to delete");
// Delete related data first (foreign key constraints)
- // Delete ItemTemplateLinks for items from other businesses
+ // Delete lt_ItemID_TemplateItemID for items from other businesses
queryExecute("
- DELETE itl FROM ItemTemplateLinks itl
- JOIN Items i ON i.ItemID = itl.ItemID
- WHERE i.ItemBusinessID != :keepID
+ DELETE itl FROM lt_ItemID_TemplateItemID itl
+ JOIN Items i ON i.ID = itl.ItemID
+ WHERE i.BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
- response.steps.append("Deleted ItemTemplateLinks for other businesses");
+ response.steps.append("Deleted lt_ItemID_TemplateItemID for other businesses");
// Delete Items for other businesses
qItems = queryExecute("
- SELECT COUNT(*) as cnt FROM Items WHERE ItemBusinessID != :keepID
+ SELECT COUNT(*) as cnt FROM Items WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
queryExecute("
- DELETE FROM Items WHERE ItemBusinessID != :keepID
+ DELETE FROM Items WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted " & qItems.cnt & " items from other businesses");
// Delete Categories for other businesses
queryExecute("
- DELETE FROM Categories WHERE CategoryBusinessID != :keepID
+ DELETE FROM Categories WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted categories from other businesses");
// Delete Hours for other businesses
queryExecute("
- DELETE FROM Hours WHERE HoursBusinessID != :keepID
+ DELETE FROM Hours WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted hours from other businesses");
- // Delete Employees for other businesses (skip if table doesn't exist)
+ // Delete Employees for other businesses
try {
queryExecute("
- DELETE FROM Employees WHERE EmployeeBusinessID != :keepID
+ DELETE FROM Employees WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted employees from other businesses");
} catch (any e) {
response.steps.append("Skipped employees (table may not exist)");
}
- // Delete ServicePoints for other businesses (skip if table doesn't exist)
+ // Delete ServicePoints for other businesses
try {
queryExecute("
- DELETE FROM ServicePoints WHERE ServicePointBusinessID != :keepID
+ DELETE FROM ServicePoints WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted service points from other businesses");
} catch (any e) {
response.steps.append("Skipped service points (table may not exist)");
}
- // Delete Stations for other businesses (skip if table doesn't exist)
+ // Delete Stations for other businesses
try {
queryExecute("
- DELETE FROM Stations WHERE StationBusinessID != :keepID
+ DELETE FROM Stations WHERE BusinessID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted stations from other businesses");
} catch (any e) {
response.steps.append("Skipped stations (table may not exist)");
}
+ // Delete beacon-business mappings for other businesses
+ try {
+ queryExecute("
+ DELETE FROM lt_BeaconsID_BusinessesID WHERE BusinessID != :keepID
+ ", { keepID: keepBusinessID }, { datasource: "payfrit" });
+ response.steps.append("Deleted beacon mappings for other businesses");
+ } catch (any e) {
+ response.steps.append("Skipped beacon mappings (table may not exist)");
+ }
+
// Finally delete the businesses themselves
queryExecute("
- DELETE FROM Businesses WHERE BusinessID != :keepID
+ DELETE FROM Businesses WHERE ID != :keepID
", { keepID: keepBusinessID }, { datasource: "payfrit" });
response.steps.append("Deleted " & arrayLen(deletedBusinesses) & " businesses");
// Get beacon status
qBeacons = queryExecute("
- SELECT lt.BeaconID, b.BeaconUUID, lt.BusinessID, biz.BusinessName, lt.ServicePointID
- FROM lt_Beacon_Businesses_ServicePoints lt
- JOIN Beacons b ON b.BeaconID = lt.BeaconID
- JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
+ SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
+ b.UUID, biz.Name AS BusinessName, sp.Name AS ServicePointName
+ FROM ServicePoints sp
+ JOIN Beacons b ON b.ID = sp.BeaconID
+ JOIN Businesses biz ON biz.ID = sp.BusinessID
+ WHERE sp.BeaconID IS NOT NULL
", {}, { datasource: "payfrit" });
beacons = [];
for (i = 1; i <= qBeacons.recordCount; i++) {
arrayAppend(beacons, {
"BeaconID": qBeacons.BeaconID[i],
- "UUID": qBeacons.BeaconUUID[i],
+ "UUID": qBeacons.UUID[i],
"BusinessID": qBeacons.BusinessID[i],
"BusinessName": qBeacons.BusinessName[i],
- "ServicePointID": qBeacons.ServicePointID[i]
+ "ServicePointID": qBeacons.ServicePointID[i],
+ "ServicePointName": qBeacons.ServicePointName[i]
});
}
diff --git a/api/admin/cleanupOrphanItem.cfm b/api/admin/cleanupOrphanItem.cfm
index 36b3076..4637990 100644
--- a/api/admin/cleanupOrphanItem.cfm
+++ b/api/admin/cleanupOrphanItem.cfm
@@ -7,9 +7,9 @@ param name="url.action" default="check"; // "check" or "deactivate"
// Check the item first
qItem = queryExecute("
- SELECT ItemID, ItemName, ItemParentItemID, ItemIsActive, ItemIsCollapsible
+ SELECT ID, Name, ParentItemID, IsActive, IsCollapsible
FROM Items
- WHERE ItemID = :itemId
+ WHERE ID = :itemId
", { itemId: url.itemId });
if (qItem.recordCount == 0) {
@@ -19,25 +19,25 @@ if (qItem.recordCount == 0) {
// Get all children (direct only for display)
qChildren = queryExecute("
- SELECT ItemID, ItemName
+ SELECT ID, Name
FROM Items
- WHERE ItemParentItemID = :itemId
+ WHERE ParentItemID = :itemId
", { itemId: url.itemId });
childList = [];
for (row in qChildren) {
- arrayAppend(childList, { "ItemID": row.ItemID, "ItemName": row.ItemName });
+ arrayAppend(childList, { "ItemID": row.ID, "Name": row.Name });
}
result = {
"OK": true,
"ACTION": url.action,
"ITEM": {
- "ItemID": qItem.ItemID,
- "ItemName": qItem.ItemName,
- "ItemParentItemID": qItem.ItemParentItemID,
- "ItemIsActive": qItem.ItemIsActive,
- "ItemIsCollapsible": qItem.ItemIsCollapsible
+ "ItemID": qItem.ID,
+ "Name": qItem.Name,
+ "ParentItemID": qItem.ParentItemID,
+ "IsActive": qItem.IsActive,
+ "IsCollapsible": qItem.IsCollapsible
},
"HAS_CHILDREN": qChildren.recordCount > 0,
"CHILD_COUNT": qChildren.recordCount,
@@ -48,14 +48,14 @@ if (url.action == "deactivate") {
// Deactivate children first
queryExecute("
UPDATE Items
- SET ItemIsActive = 0
- WHERE ItemParentItemID = :itemId
+ SET IsActive = 0
+ WHERE ParentItemID = :itemId
", { itemId: url.itemId });
// Then deactivate the parent
queryExecute("
UPDATE Items
- SET ItemIsActive = 0
+ SET IsActive = 0
WHERE ItemID = :itemId
", { itemId: url.itemId });
diff --git a/api/admin/clearCarts.cfm b/api/admin/clearCarts.cfm
index 097b5cc..ba7cd14 100644
--- a/api/admin/clearCarts.cfm
+++ b/api/admin/clearCarts.cfm
@@ -5,13 +5,13 @@
// Delete cart orders (status 0) to reset for testing
result = queryExecute("
DELETE FROM OrderLineItems
- WHERE OrderLineItemOrderID IN (
- SELECT OrderID FROM Orders WHERE OrderStatusID = 0
+ WHERE OrderID IN (
+ SELECT ID FROM Orders WHERE StatusID = 0
)
", {}, { datasource = "payfrit" });
result2 = queryExecute("
- DELETE FROM Orders WHERE OrderStatusID = 0
+ DELETE FROM Orders WHERE StatusID = 0
", {}, { datasource = "payfrit" });
writeOutput(serializeJSON({
diff --git a/api/admin/clearLocalCoffee.cfm b/api/admin/clearLocalCoffee.cfm
index 9f3a021..da77556 100644
--- a/api/admin/clearLocalCoffee.cfm
+++ b/api/admin/clearLocalCoffee.cfm
@@ -10,27 +10,27 @@ try {
businessIDs = [38, 39, 40, 41, 42];
for (bizID in businessIDs) {
- // Delete ItemTemplateLinks for items belonging to this business
+ // Delete lt_ItemID_TemplateItemID for items belonging to this business
queryExecute("
- DELETE itl FROM ItemTemplateLinks itl
- INNER JOIN Items i ON i.ItemID = itl.ItemID
- WHERE i.ItemBusinessID = :bizID
+ DELETE itl FROM lt_ItemID_TemplateItemID itl
+ INNER JOIN Items i ON i.ID = itl.ItemID
+ WHERE i.BusinessID = :bizID
", { bizID: bizID }, { datasource: "payfrit" });
// Delete Items
- queryExecute("DELETE FROM Items WHERE ItemBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Items WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
// Delete Categories
- queryExecute("DELETE FROM Categories WHERE CategoryBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Categories WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
// Delete Hours
- queryExecute("DELETE FROM Hours WHERE HoursBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Hours WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
// Delete Addresses linked to this business
- queryExecute("DELETE FROM Addresses WHERE AddressBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Addresses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
// Delete the Business itself
- queryExecute("DELETE FROM Businesses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Businesses WHERE ID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
response.steps.append("Deleted business " & bizID & " and all related data");
}
diff --git a/api/admin/closeAllChats.cfm b/api/admin/closeAllChats.cfm
index 476d4fa..237f710 100644
--- a/api/admin/closeAllChats.cfm
+++ b/api/admin/closeAllChats.cfm
@@ -5,9 +5,9 @@
try {
result = queryExecute("
UPDATE Tasks
- SET TaskCompletedOn = NOW()
+ SET CompletedOn = NOW()
WHERE TaskTypeID = 2
- AND TaskCompletedOn IS NULL
+ AND CompletedOn IS NULL
", {}, { datasource: "payfrit" });
affected = result.recordCount ?: 0;
diff --git a/api/admin/copyDrinksToBigDeans.cfm b/api/admin/copyDrinksToBigDeans.cfm
index 40bb89d..091d1ff 100644
--- a/api/admin/copyDrinksToBigDeans.cfm
+++ b/api/admin/copyDrinksToBigDeans.cfm
@@ -15,24 +15,24 @@ try {
// First, check if Big Dean's has a Beverages/Drinks category
qExistingCat = queryExecute("
- SELECT CategoryID, CategoryName FROM Categories
- WHERE CategoryBusinessID = :bizId AND (CategoryName LIKE '%Drink%' OR CategoryName LIKE '%Beverage%')
+ SELECT ID, Name FROM Categories
+ WHERE BusinessID = :bizId AND (Name LIKE '%Drink%' OR Name LIKE '%Beverage%')
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
if (qExistingCat.recordCount > 0) {
drinksCategoryId = qExistingCat.CategoryID;
- response["CategoryNote"] = "Using existing category: " & qExistingCat.CategoryName;
+ response["CategoryNote"] = "Using existing category: " & qExistingCat.Name;
} else {
// Create a new Beverages category for Big Dean's
qMaxCat = queryExecute("SELECT COALESCE(MAX(CategoryID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" });
drinksCategoryId = qMaxCat.nextId;
qMaxSort = queryExecute("
- SELECT COALESCE(MAX(CategorySortOrder), 0) + 1 as nextSort FROM Categories WHERE CategoryBusinessID = :bizId
+ SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort FROM Categories WHERE BusinessID = :bizId
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
queryExecute("
- INSERT INTO Categories (CategoryID, CategoryBusinessID, CategoryParentCategoryID, CategoryName, CategorySortOrder, CategoryAddedOn)
+ INSERT INTO Categories (CategoryID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn)
VALUES (:catId, :bizId, 0, 'Beverages', :sortOrder, NOW())
", {
catId: drinksCategoryId,
@@ -61,8 +61,8 @@ try {
for (drink in drinks) {
// Check if item already exists
qExists = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizId AND ItemName = :name AND ItemCategoryID = :catId
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizId AND Name = :name AND CategoryID = :catId
", { bizId: bigDeansBusinessId, name: drink.name, catId: drinksCategoryId }, { datasource: "payfrit" });
if (qExists.recordCount == 0) {
@@ -72,10 +72,10 @@ try {
queryExecute("
INSERT INTO Items (
- ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
- ItemName, ItemDescription, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemIsCollapsible, ItemRequiresChildSelection,
- ItemAddedOn
+ ItemID, BusinessID, CategoryID, ParentItemID,
+ Name, Description, Price, IsActive,
+ SortOrder, IsCollapsible, RequiresChildSelection,
+ AddedOn
) VALUES (
:itemId, :bizId, :catId, 0,
:name, :desc, :price, 1,
@@ -103,10 +103,10 @@ try {
qMaxOpt = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
queryExecute("
INSERT INTO Items (
- ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
- ItemName, ItemDescription, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemIsCollapsible, ItemIsCheckedByDefault,
- ItemAddedOn
+ ItemID, BusinessID, CategoryID, ParentItemID,
+ Name, Description, Price, IsActive,
+ SortOrder, IsCollapsible, IsCheckedByDefault,
+ AddedOn
) VALUES (
:itemId, :bizId, 0, :parentId,
:name, '', 0, 1,
diff --git a/api/admin/createBeacons.cfm b/api/admin/createBeacons.cfm
index 475efd9..bb49b55 100644
--- a/api/admin/createBeacons.cfm
+++ b/api/admin/createBeacons.cfm
@@ -20,69 +20,74 @@ try {
uuid = beaconUUIDs[i];
// Check if beacon exists
- qB = queryExecute("SELECT BeaconID FROM Beacons WHERE BeaconUUID = :uuid", { uuid: uuid }, { datasource: "payfrit" });
+ qB = queryExecute("SELECT ID FROM Beacons WHERE UUID = :uuid", { uuid: uuid }, { datasource: "payfrit" });
if (qB.recordCount == 0) {
- queryExecute("INSERT INTO Beacons (BeaconUUID, BeaconBusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" });
+ queryExecute("INSERT INTO Beacons (UUID, BusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" });
qNew = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
beaconID = qNew.id;
response.steps.append("Created beacon " & beaconID & " with UUID: " & uuid);
} else {
- beaconID = qB.BeaconID;
+ beaconID = qB.ID;
response.steps.append("Beacon exists: " & beaconID & " with UUID: " & uuid);
}
}
// Get service point Table 1
qSP = queryExecute("
- SELECT ServicePointID FROM ServicePoints
- WHERE ServicePointBusinessID = :bizID AND ServicePointName = 'Table 1'
+ SELECT ID FROM ServicePoints
+ WHERE BusinessID = :bizID AND Name = 'Table 1'
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
if (qSP.recordCount == 0) {
queryExecute("
- INSERT INTO ServicePoints (ServicePointBusinessID, ServicePointName, ServicePointTypeID)
- VALUES (:bizID, 'Table 1', 1)
+ INSERT INTO ServicePoints (BusinessID, Name)
+ VALUES (:bizID, 'Table 1')
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
servicePointID = qSP.id;
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
} else {
- servicePointID = qSP.ServicePointID;
+ servicePointID = qSP.ID;
response.steps.append("Found service point 'Table 1' (ID: " & servicePointID & ")");
}
- // Get all beacons and map them
- qBeacons = queryExecute("SELECT BeaconID, BeaconUUID FROM Beacons", {}, { datasource: "payfrit" });
+ // Assign all beacons to the Table 1 service point
+ qBeacons = queryExecute("SELECT ID, UUID FROM Beacons WHERE BusinessID = :bizID", { bizID: lazyDaisyID }, { datasource: "payfrit" });
for (i = 1; i <= qBeacons.recordCount; i++) {
- beaconID = qBeacons.BeaconID[i];
+ beaconID = qBeacons.ID[i];
- // Delete old mapping if exists
- queryExecute("DELETE FROM lt_Beacon_Businesses_ServicePoints WHERE BeaconID = :beaconID", { beaconID: beaconID }, { datasource: "payfrit" });
-
- // Create new mapping
+ // Unassign this beacon from any existing service point
queryExecute("
- INSERT INTO lt_Beacon_Businesses_ServicePoints (BeaconID, BusinessID, ServicePointID)
- VALUES (:beaconID, :bizID, :spID)
+ UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL
+ WHERE BeaconID = :beaconID
+ ", { beaconID: beaconID }, { datasource: "payfrit" });
+
+ // Assign beacon to Table 1 service point
+ queryExecute("
+ UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1
+ WHERE ID = :spID AND BusinessID = :bizID
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
- response.steps.append("Mapped beacon " & beaconID & " to Lazy Daisy, Table 1");
+ response.steps.append("Assigned beacon " & beaconID & " to Table 1");
}
// Get final status
qFinal = queryExecute("
- SELECT lt.BeaconID, b.BeaconUUID, lt.BusinessID, biz.BusinessName, lt.ServicePointID, sp.ServicePointName
- FROM lt_Beacon_Businesses_ServicePoints lt
- JOIN Beacons b ON b.BeaconID = lt.BeaconID
- JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
+ SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
+ b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
+ biz.Name AS BusinessName
+ FROM ServicePoints sp
+ JOIN Beacons b ON b.ID = sp.BeaconID
+ JOIN Businesses biz ON biz.ID = sp.BusinessID
+ WHERE sp.BeaconID IS NOT NULL
", {}, { datasource: "payfrit" });
beacons = [];
for (i = 1; i <= qFinal.recordCount; i++) {
arrayAppend(beacons, {
"BeaconID": qFinal.BeaconID[i],
- "UUID": qFinal.BeaconUUID[i],
+ "UUID": qFinal.UUID[i],
"BusinessID": qFinal.BusinessID[i],
"BusinessName": qFinal.BusinessName[i],
"ServicePointID": qFinal.ServicePointID[i],
diff --git a/api/admin/createChatMessagesTable.cfm b/api/admin/createChatMessagesTable.cfm
index 7183532..a641e6b 100644
--- a/api/admin/createChatMessagesTable.cfm
+++ b/api/admin/createChatMessagesTable.cfm
@@ -5,11 +5,11 @@ try {
// Create ChatMessages table
queryExecute("
CREATE TABLE IF NOT EXISTS ChatMessages (
- MessageID INT AUTO_INCREMENT PRIMARY KEY,
+ ID INT AUTO_INCREMENT PRIMARY KEY,
TaskID INT NOT NULL,
SenderUserID INT NOT NULL,
SenderType ENUM('customer', 'worker') NOT NULL,
- MessageText TEXT NOT NULL,
+ MessageBody TEXT NOT NULL,
IsRead TINYINT(1) DEFAULT 0,
CreatedOn DATETIME DEFAULT NOW(),
@@ -21,13 +21,13 @@ try {
// Also add a "Chat" category if it doesn't exist for business 17
existing = queryExecute("
- SELECT TaskCategoryID FROM TaskCategories
- WHERE TaskCategoryBusinessID = 17 AND TaskCategoryName = 'Chat'
+ SELECT ID FROM TaskCategories
+ WHERE BusinessID = 17 AND Name = 'Chat'
", {}, { datasource: "payfrit" });
if (existing.recordCount == 0) {
queryExecute("
- INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
+ INSERT INTO TaskCategories (BusinessID, Name, Color)
VALUES (17, 'Chat', '##2196F3')
", {}, { datasource: "payfrit" });
}
diff --git a/api/admin/createMenusTable.cfm b/api/admin/createMenusTable.cfm
index c93596e..129302c 100644
--- a/api/admin/createMenusTable.cfm
+++ b/api/admin/createMenusTable.cfm
@@ -32,47 +32,47 @@ try {
queryExecute("
CREATE TABLE Menus (
MenuID INT AUTO_INCREMENT PRIMARY KEY,
- MenuBusinessID INT NOT NULL,
- MenuName VARCHAR(100) NOT NULL,
- MenuDescription VARCHAR(500) NULL,
- MenuDaysActive INT NOT NULL DEFAULT 127,
- MenuStartTime TIME NULL,
- MenuEndTime TIME NULL,
- MenuSortOrder INT NOT NULL DEFAULT 0,
- MenuIsActive TINYINT NOT NULL DEFAULT 1,
- MenuAddedOn DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- INDEX idx_menus_business (MenuBusinessID),
- INDEX idx_menus_active (MenuBusinessID, MenuIsActive)
+ BusinessID INT NOT NULL,
+ Name VARCHAR(100) NOT NULL,
+ Description VARCHAR(500) NULL,
+ DaysActive INT NOT NULL DEFAULT 127,
+ StartTime TIME NULL,
+ EndTime TIME NULL,
+ SortOrder INT NOT NULL DEFAULT 0,
+ IsActive TINYINT NOT NULL DEFAULT 1,
+ AddedOn DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ INDEX idx_menus_business (BusinessID),
+ INDEX idx_menus_active (BusinessID, IsActive)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
", {}, { datasource: "payfrit" });
response["OK"] = true;
response["MESSAGE"] = "Menus table created successfully";
response["SCHEMA"] = {
- "MenuDaysActive": "Bitmask: 1=Sun, 2=Mon, 4=Tue, 8=Wed, 16=Thu, 32=Fri, 64=Sat (127 = all days)"
+ "DaysActive": "Bitmask: 1=Sun, 2=Mon, 4=Tue, 8=Wed, 16=Thu, 32=Fri, 64=Sat (127 = all days)"
};
}
- // Check if CategoryMenuID column exists in Categories table
+ // Check if MenuID column exists in Categories table
qCatCol = queryExecute("
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'payfrit'
AND TABLE_NAME = 'Categories'
- AND COLUMN_NAME = 'CategoryMenuID'
+ AND COLUMN_NAME = 'MenuID'
", {}, { datasource: "payfrit" });
if (qCatCol.recordCount == 0) {
- // Add CategoryMenuID column to Categories table
+ // Add MenuID column to Categories table
queryExecute("
ALTER TABLE Categories
- ADD COLUMN CategoryMenuID INT NULL DEFAULT NULL AFTER CategoryBusinessID,
- ADD INDEX idx_categories_menu (CategoryMenuID)
+ ADD COLUMN MenuID INT NULL DEFAULT NULL AFTER BusinessID,
+ ADD INDEX idx_categories_menu (MenuID)
", {}, { datasource: "payfrit" });
response["CATEGORIES_UPDATED"] = true;
- response["CATEGORIES_MESSAGE"] = "Added CategoryMenuID column to Categories table";
+ response["CATEGORIES_MESSAGE"] = "Added MenuID column to Categories table";
} else {
response["CATEGORIES_UPDATED"] = false;
- response["CATEGORIES_MESSAGE"] = "CategoryMenuID column already exists";
+ response["CATEGORIES_MESSAGE"] = "MenuID column already exists";
}
} catch (any e) {
diff --git a/api/admin/createParentBusiness.cfm b/api/admin/createParentBusiness.cfm
index cec0003..a60325d 100644
--- a/api/admin/createParentBusiness.cfm
+++ b/api/admin/createParentBusiness.cfm
@@ -12,7 +12,7 @@
*
* POST body:
* {
- * "BusinessName": "Century Casino",
+ * "Name": "Century Casino",
* "UserID": 1,
* "ChildBusinessIDs": [47, 48] // Optional: link existing businesses as children
* }
@@ -36,13 +36,13 @@ response = { "OK": false };
try {
data = readJsonBody();
- BusinessName = structKeyExists(data, "BusinessName") ? trim(data.BusinessName) : "";
+ Name = structKeyExists(data, "Name") ? trim(data.Name) : "";
UserID = structKeyExists(data, "UserID") ? val(data.UserID) : 0;
ChildBusinessIDs = structKeyExists(data, "ChildBusinessIDs") && isArray(data.ChildBusinessIDs) ? data.ChildBusinessIDs : [];
- if (!len(BusinessName)) {
+ if (!len(Name)) {
response["ERROR"] = "missing_name";
- response["MESSAGE"] = "BusinessName is required";
+ response["MESSAGE"] = "Name is required";
writeOutput(serializeJSON(response));
abort;
}
@@ -56,7 +56,7 @@ try {
// Create minimal address record (just a placeholder)
queryExecute("
- INSERT INTO Addresses (AddressLine1, AddressUserID, AddressTypeID, AddressAddedOn)
+ INSERT INTO Addresses (Line1, UserID, AddressTypeID, AddedOn)
VALUES ('Parent Business - No Physical Location', :userID, 2, NOW())
", {
userID: UserID
@@ -67,10 +67,10 @@ try {
// Create parent business (no menu, no hours, just a shell)
queryExecute("
- INSERT INTO Businesses (BusinessName, BusinessUserID, BusinessAddressID, BusinessParentBusinessID, BusinessDeliveryZipCodes, BusinessAddedOn)
+ INSERT INTO Businesses (Name, UserID, AddressID, ParentBusinessID, BusinessDeliveryZipCodes, AddedOn)
VALUES (:name, :userId, :addressId, NULL, '', NOW())
", {
- name: BusinessName,
+ name: Name,
userId: UserID,
addressId: addressId
}, { datasource = "payfrit" });
@@ -80,7 +80,7 @@ try {
// Link address back to business
queryExecute("
- UPDATE Addresses SET AddressBusinessID = :bizId WHERE AddressID = :addrId
+ UPDATE Addresses SET BusinessID = :bizId WHERE ID = :addrId
", {
bizId: newBusinessID,
addrId: addressId
@@ -92,7 +92,7 @@ try {
childID = val(childID);
if (childID > 0) {
queryExecute("
- UPDATE Businesses SET BusinessParentBusinessID = :parentId WHERE BusinessID = :childId
+ UPDATE Businesses SET ParentBusinessID = :parentId WHERE ID = :childId
", {
parentId: newBusinessID,
childId: childID
@@ -103,7 +103,7 @@ try {
response["OK"] = true;
response["BusinessID"] = newBusinessID;
- response["BusinessName"] = BusinessName;
+ response["Name"] = Name;
response["MESSAGE"] = "Parent business created";
if (arrayLen(linkedChildren) > 0) {
response["LinkedChildren"] = linkedChildren;
diff --git a/api/admin/debugBigDeansDeactivated.cfm b/api/admin/debugBigDeansDeactivated.cfm
index 02881ce..f77a444 100644
--- a/api/admin/debugBigDeansDeactivated.cfm
+++ b/api/admin/debugBigDeansDeactivated.cfm
@@ -9,22 +9,22 @@ bizId = 27;
deactivatedIds = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204, 11212, 11220, 11259];
qDeactivated = queryExecute("
- SELECT i.ItemID, i.ItemName, i.ItemParentItemID, i.ItemIsActive, i.ItemIsCollapsible,
- (SELECT COUNT(*) FROM Items c WHERE c.ItemParentItemID = i.ItemID) as ChildCount,
- (SELECT GROUP_CONCAT(c.ItemName) FROM Items c WHERE c.ItemParentItemID = i.ItemID) as Children
+ SELECT i.ID, i.Name, i.ParentItemID, i.IsActive, i.IsCollapsible,
+ (SELECT COUNT(*) FROM Items c WHERE c.ParentItemID = i.ID) as ChildCount,
+ (SELECT GROUP_CONCAT(c.Name) FROM Items c WHERE c.ParentItemID = i.ID) as Children
FROM Items i
- WHERE i.ItemID IN (:ids)
- ORDER BY i.ItemID
+ WHERE i.ID IN (:ids)
+ ORDER BY i.ID
", { ids: { value: arrayToList(deactivatedIds), list: true } }, { datasource: "payfrit" });
items = [];
for (row in qDeactivated) {
arrayAppend(items, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
- "ParentID": row.ItemParentItemID,
- "IsActive": row.ItemIsActive,
- "IsCollapsible": row.ItemIsCollapsible,
+ "ItemID": row.ID,
+ "Name": row.Name,
+ "ParentID": row.ParentItemID,
+ "IsActive": row.IsActive,
+ "IsCollapsible": row.IsCollapsible,
"ChildCount": row.ChildCount,
"Children": row.Children
});
diff --git a/api/admin/debugBigDeansLinks.cfm b/api/admin/debugBigDeansLinks.cfm
index 0ba3294..708d78e 100644
--- a/api/admin/debugBigDeansLinks.cfm
+++ b/api/admin/debugBigDeansLinks.cfm
@@ -9,24 +9,24 @@ bizId = 27;
qLinks = queryExecute("
SELECT
tl.ItemID as MenuItemID,
- mi.ItemName as MenuItemName,
- mi.ItemParentItemID,
+ mi.Name as MenuName,
+ mi.ParentItemID,
tl.TemplateItemID,
- t.ItemName as TemplateName,
+ t.Name as TemplateName,
tl.SortOrder
- FROM ItemTemplateLinks tl
- JOIN Items mi ON mi.ItemID = tl.ItemID
+ FROM lt_ItemID_TemplateItemID tl
+ JOIN Items mi ON mi.ID = tl.ItemID
JOIN Items t ON t.ItemID = tl.TemplateItemID
- WHERE mi.ItemBusinessID = :bizId
- ORDER BY mi.ItemParentItemID, mi.ItemName, tl.SortOrder
+ WHERE mi.BusinessID = :bizId
+ ORDER BY mi.ParentItemID, mi.Name, tl.SortOrder
", { bizId: bizId }, { datasource: "payfrit" });
links = [];
for (row in qLinks) {
arrayAppend(links, {
"MenuItemID": row.MenuItemID,
- "MenuItemName": row.MenuItemName,
- "ParentItemID": row.ItemParentItemID,
+ "MenuName": row.MenuName,
+ "ParentItemID": row.ParentItemID,
"TemplateItemID": row.TemplateItemID,
"TemplateName": row.TemplateName
});
@@ -34,20 +34,20 @@ for (row in qLinks) {
// Get burgers specifically (parent = 11271)
qBurgers = queryExecute("
- SELECT ItemID, ItemName FROM Items
- WHERE ItemBusinessID = :bizId AND ItemParentItemID = 11271 AND ItemIsActive = 1
- ORDER BY ItemSortOrder
+ SELECT ID, Name FROM Items
+ WHERE BusinessID = :bizId AND ParentItemID = 11271 AND IsActive = 1
+ ORDER BY SortOrder
", { bizId: bizId }, { datasource: "payfrit" });
burgers = [];
for (row in qBurgers) {
// Get templates for this burger
qBurgerTemplates = queryExecute("
- SELECT tl.TemplateItemID, t.ItemName as TemplateName
- FROM ItemTemplateLinks tl
+ SELECT tl.TemplateItemID, t.Name as TemplateName
+ FROM lt_ItemID_TemplateItemID tl
JOIN Items t ON t.ItemID = tl.TemplateItemID
WHERE tl.ItemID = :itemId
- ", { itemId: row.ItemID }, { datasource: "payfrit" });
+ ", { itemId: row.ID }, { datasource: "payfrit" });
templates = [];
for (t in qBurgerTemplates) {
@@ -55,8 +55,8 @@ for (row in qBurgers) {
}
arrayAppend(burgers, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
+ "ItemID": row.ID,
+ "Name": row.Name,
"Templates": templates
});
}
diff --git a/api/admin/debugBigDeansMenu.cfm b/api/admin/debugBigDeansMenu.cfm
index 749cfe2..884353e 100644
--- a/api/admin/debugBigDeansMenu.cfm
+++ b/api/admin/debugBigDeansMenu.cfm
@@ -9,38 +9,38 @@ businessID = 27;
qCategories = queryExecute("
SELECT DISTINCT
p.ItemID as CategoryID,
- p.ItemName as CategoryName,
- p.ItemSortOrder
+ p.Name as Name,
+ p.SortOrder
FROM Items p
- INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
- WHERE p.ItemBusinessID = :businessID
- AND p.ItemParentItemID = 0
- AND p.ItemIsActive = 1
+ INNER JOIN Items c ON c.ParentItemID = p.ItemID
+ WHERE p.BusinessID = :businessID
+ AND p.ParentItemID = 0
+ AND p.IsActive = 1
AND NOT EXISTS (
- SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
+ SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ItemID
)
- ORDER BY p.ItemSortOrder, p.ItemName
+ ORDER BY p.SortOrder, p.Name
", { businessID: businessID });
cats = [];
for (c in qCategories) {
arrayAppend(cats, {
- "CategoryID": c.CategoryID,
- "CategoryName": c.CategoryName
+ "CategoryID": c.ID,
+ "Name": c.Name
});
}
// Also check raw counts
rawCount = queryExecute("
SELECT COUNT(*) as cnt FROM Items
- WHERE ItemBusinessID = :bizId AND ItemParentItemID = 0 AND ItemIsActive = 1
+ WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsActive = 1
", { bizId: businessID });
childrenCount = queryExecute("
- SELECT COUNT(DISTINCT c.ItemParentItemID) as cnt
+ SELECT COUNT(DISTINCT c.ParentItemID) as cnt
FROM Items c
- INNER JOIN Items p ON p.ItemID = c.ItemParentItemID
- WHERE p.ItemBusinessID = :bizId AND p.ItemParentItemID = 0
+ INNER JOIN Items p ON p.ItemID = c.ParentItemID
+ WHERE p.BusinessID = :bizId AND p.ParentItemID = 0
", { bizId: businessID });
writeOutput(serializeJSON({
diff --git a/api/admin/debugBigDeansTemplates.cfm b/api/admin/debugBigDeansTemplates.cfm
index b7011bb..35c2603 100644
--- a/api/admin/debugBigDeansTemplates.cfm
+++ b/api/admin/debugBigDeansTemplates.cfm
@@ -9,24 +9,24 @@ bizId = 27;
qLinks = queryExecute("
SELECT
tl.ItemID as MenuItemID,
- mi.ItemName as MenuItemName,
- mi.ItemParentItemID as MenuItemParentID,
+ mi.Name as MenuName,
+ mi.ParentItemID as MenuItemParentID,
tl.TemplateItemID,
- t.ItemName as TemplateName,
- t.ItemIsActive as TemplateActive,
+ t.Name as TemplateName,
+ t.IsActive as TemplateActive,
tl.SortOrder
- FROM ItemTemplateLinks tl
- JOIN Items mi ON mi.ItemID = tl.ItemID
+ FROM lt_ItemID_TemplateItemID tl
+ JOIN Items mi ON mi.ID = tl.ItemID
JOIN Items t ON t.ItemID = tl.TemplateItemID
- WHERE mi.ItemBusinessID = :bizId
- ORDER BY mi.ItemName, tl.SortOrder
+ WHERE mi.BusinessID = :bizId
+ ORDER BY mi.Name, tl.SortOrder
", { bizId: bizId }, { datasource: "payfrit" });
links = [];
for (row in qLinks) {
arrayAppend(links, {
"MenuItemID": row.MenuItemID,
- "MenuItemName": row.MenuItemName,
+ "MenuName": row.MenuName,
"MenuItemParentID": row.MenuItemParentID,
"TemplateItemID": row.TemplateItemID,
"TemplateName": row.TemplateName,
@@ -37,20 +37,20 @@ for (row in qLinks) {
// Get all templates that exist for this business
qTemplates = queryExecute("
- SELECT ItemID, ItemName, ItemIsActive, ItemParentItemID
+ SELECT ID, Name, IsActive, ParentItemID
FROM Items
- WHERE ItemBusinessID = :bizId
- AND ItemIsCollapsible = 1
- ORDER BY ItemName
+ WHERE BusinessID = :bizId
+ AND IsCollapsible = 1
+ ORDER BY Name
", { bizId: bizId }, { datasource: "payfrit" });
templates = [];
for (row in qTemplates) {
arrayAppend(templates, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
- "IsActive": row.ItemIsActive,
- "ParentID": row.ItemParentItemID
+ "ItemID": row.ID,
+ "Name": row.Name,
+ "IsActive": row.IsActive,
+ "ParentID": row.ParentItemID
});
}
diff --git a/api/admin/debugBigDeansTemplates2.cfm b/api/admin/debugBigDeansTemplates2.cfm
index b40b05e..b61e913 100644
--- a/api/admin/debugBigDeansTemplates2.cfm
+++ b/api/admin/debugBigDeansTemplates2.cfm
@@ -5,67 +5,67 @@
bizId = 27;
-// Check the template items themselves (IDs from ItemTemplateLinks)
+// Check the template items themselves (IDs from lt_ItemID_TemplateItemID)
templateIds = "11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227";
qTemplates = queryExecute("
- SELECT ItemID, ItemName, ItemIsCollapsible, ItemIsActive, ItemParentItemID, ItemBusinessID
+ SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID
FROM Items
- WHERE ItemID IN (#templateIds#)
- ORDER BY ItemName
+ WHERE ID IN (#templateIds#)
+ ORDER BY Name
", {}, { datasource: "payfrit" });
templates = [];
for (row in qTemplates) {
arrayAppend(templates, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
- "IsCollapsible": row.ItemIsCollapsible,
- "IsActive": row.ItemIsActive,
- "ParentID": row.ItemParentItemID,
- "BusinessID": row.ItemBusinessID
+ "ItemID": row.ID,
+ "Name": row.Name,
+ "IsCollapsible": row.IsCollapsible,
+ "IsActive": row.IsActive,
+ "ParentID": row.ParentItemID,
+ "BusinessID": row.BusinessID
});
}
// Also check what other templates might exist for burgers
-// Look for items that are in ItemTemplateLinks but NOT linked to burgers
+// Look for items that are in lt_ItemID_TemplateItemID but NOT linked to burgers
qMissingTemplates = queryExecute("
- SELECT DISTINCT t.ItemID, t.ItemName, t.ItemIsCollapsible, t.ItemIsActive
+ SELECT DISTINCT t.ItemID, t.Name, t.IsCollapsible, t.IsActive
FROM Items t
- WHERE t.ItemBusinessID = :bizId
- AND t.ItemParentItemID = 0
+ WHERE t.BusinessID = :bizId
+ AND t.ParentItemID = 0
AND t.ItemID NOT IN (
- SELECT i.ItemID FROM Items i WHERE i.ItemBusinessID = :bizId AND i.ItemCategoryID > 0
+ SELECT i.ID FROM Items i WHERE i.BusinessID = :bizId AND i.CategoryID > 0
)
- AND EXISTS (SELECT 1 FROM Items child WHERE child.ItemParentItemID = t.ItemID)
- ORDER BY t.ItemName
+ AND EXISTS (SELECT 1 FROM Items child WHERE child.ParentItemID = t.ItemID)
+ ORDER BY t.Name
", { bizId: bizId }, { datasource: "payfrit" });
potentialTemplates = [];
for (row in qMissingTemplates) {
arrayAppend(potentialTemplates, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
- "IsCollapsible": row.ItemIsCollapsible,
- "IsActive": row.ItemIsActive
+ "ItemID": row.ID,
+ "Name": row.Name,
+ "IsCollapsible": row.IsCollapsible,
+ "IsActive": row.IsActive
});
}
// What templates SHOULD burgers have? Let's see all templates used by ANY item
qAllTemplateUsage = queryExecute("
- SELECT t.ItemID, t.ItemName, COUNT(tl.ItemID) as UsageCount
- FROM ItemTemplateLinks tl
+ SELECT t.ItemID, t.Name, COUNT(tl.ItemID) as UsageCount
+ FROM lt_ItemID_TemplateItemID tl
JOIN Items t ON t.ItemID = tl.TemplateItemID
- JOIN Items mi ON mi.ItemID = tl.ItemID AND mi.ItemBusinessID = :bizId
- GROUP BY t.ItemID, t.ItemName
- ORDER BY t.ItemName
+ JOIN Items mi ON mi.ID = tl.ItemID AND mi.BusinessID = :bizId
+ GROUP BY t.ItemID, t.Name
+ ORDER BY t.Name
", { bizId: bizId }, { datasource: "payfrit" });
allTemplates = [];
for (row in qAllTemplateUsage) {
arrayAppend(allTemplates, {
- "TemplateID": row.ItemID,
- "TemplateName": row.ItemName,
+ "TemplateID": row.ID,
+ "TemplateName": row.Name,
"UsageCount": row.UsageCount
});
}
diff --git a/api/admin/debugBigDeansTemplates3.cfm b/api/admin/debugBigDeansTemplates3.cfm
index a5526b0..66b34ca 100644
--- a/api/admin/debugBigDeansTemplates3.cfm
+++ b/api/admin/debugBigDeansTemplates3.cfm
@@ -7,41 +7,41 @@ bizId = 27;
// Get the template items themselves
qTemplates = queryExecute("
- SELECT ItemID, ItemName, ItemIsCollapsible, ItemIsActive, ItemParentItemID, ItemBusinessID
+ SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID
FROM Items
- WHERE ItemID IN (11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227)
- ORDER BY ItemName
+ WHERE ID IN (11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227)
+ ORDER BY Name
", {}, { datasource: "payfrit" });
templates = [];
for (row in qTemplates) {
arrayAppend(templates, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
- "IsCollapsible": row.ItemIsCollapsible,
- "IsActive": row.ItemIsActive,
- "ParentID": row.ItemParentItemID,
- "BusinessID": row.ItemBusinessID
+ "ItemID": row.ID,
+ "Name": row.Name,
+ "IsCollapsible": row.IsCollapsible,
+ "IsActive": row.IsActive,
+ "ParentID": row.ParentItemID,
+ "BusinessID": row.BusinessID
});
}
// What templates are used by burgers vs all items?
qBurgerLinks = queryExecute("
- SELECT mi.ItemID, mi.ItemName, GROUP_CONCAT(t.ItemName ORDER BY tl.SortOrder) as Templates
+ SELECT mi.ID, mi.Name, GROUP_CONCAT(t.Name ORDER BY tl.SortOrder) as Templates
FROM Items mi
- JOIN ItemTemplateLinks tl ON tl.ItemID = mi.ItemID
+ JOIN lt_ItemID_TemplateItemID tl ON tl.ItemID = mi.ID
JOIN Items t ON t.ItemID = tl.TemplateItemID
- WHERE mi.ItemBusinessID = :bizId
- AND mi.ItemParentItemID = 11271
- GROUP BY mi.ItemID, mi.ItemName
- ORDER BY mi.ItemName
+ WHERE mi.BusinessID = :bizId
+ AND mi.ParentItemID = 11271
+ GROUP BY mi.ID, mi.Name
+ ORDER BY mi.Name
", { bizId: bizId }, { datasource: "payfrit" });
burgerLinks = [];
for (row in qBurgerLinks) {
arrayAppend(burgerLinks, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
+ "ItemID": row.ID,
+ "Name": row.Name,
"Templates": row.Templates
});
}
@@ -49,20 +49,20 @@ for (row in qBurgerLinks) {
// Also check: are there templates that SHOULD be linked to burgers?
// (e.g., Add Cheese, etc.)
qCheeseTemplate = queryExecute("
- SELECT ItemID, ItemName, ItemParentItemID, ItemIsActive
+ SELECT ID, Name, ParentItemID, IsActive
FROM Items
- WHERE ItemBusinessID = :bizId
- AND ItemName LIKE '%Cheese%'
- ORDER BY ItemName
+ WHERE BusinessID = :bizId
+ AND Name LIKE '%Cheese%'
+ ORDER BY Name
", { bizId: bizId }, { datasource: "payfrit" });
cheeseItems = [];
for (row in qCheeseTemplate) {
arrayAppend(cheeseItems, {
- "ItemID": row.ItemID,
- "ItemName": row.ItemName,
- "ParentID": row.ItemParentItemID,
- "IsActive": row.ItemIsActive
+ "ItemID": row.ID,
+ "Name": row.Name,
+ "ParentID": row.ParentItemID,
+ "IsActive": row.IsActive
});
}
diff --git a/api/admin/debugBusinesses.cfm b/api/admin/debugBusinesses.cfm
index 7f7e302..e4251ed 100644
--- a/api/admin/debugBusinesses.cfm
+++ b/api/admin/debugBusinesses.cfm
@@ -26,36 +26,36 @@
+
@@ -39,7 +39,7 @@
@@ -47,12 +47,12 @@
-// Switch all beacons from one business to another
+// Switch beacon mapping from one business to another via join table.
+// Beacons.BusinessID (owner) is NOT touched.
fromBiz = 17; // In-N-Out
toBiz = 27; // Big Dean's
+// Remove mapping for source business
queryExecute("
- UPDATE lt_Beacon_Businesses_ServicePoints
- SET BusinessID = :toBiz
- WHERE BusinessID = :fromBiz
+ DELETE FROM lt_BeaconsID_BusinessesID
+ WHERE BusinessID = :fromBiz
+", { fromBiz: fromBiz }, { datasource: "payfrit" });
+
+// Add mapping for target business (for beacons owned by source)
+queryExecute("
+ INSERT INTO lt_BeaconsID_BusinessesID (BeaconID, BusinessID)
+ SELECT ID, :toBiz FROM Beacons WHERE BusinessID = :fromBiz
+ ON DUPLICATE KEY UPDATE ID = ID
", { toBiz: toBiz, fromBiz: fromBiz }, { datasource: "payfrit" });
+// Clear ServicePoints.BeaconID for source business (no longer valid)
+queryExecute("
+ UPDATE ServicePoints
+ SET BeaconID = NULL, AssignedByUserID = NULL
+ WHERE BusinessID = :fromBiz AND BeaconID IS NOT NULL
+", { fromBiz: fromBiz }, { datasource: "payfrit" });
+
// Get current state
q = queryExecute("
- SELECT lt.*, b.BusinessName
- FROM lt_Beacon_Businesses_ServicePoints lt
- JOIN Businesses b ON b.BusinessID = lt.BusinessID
+ SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
+ b.Name AS BeaconName, biz.Name AS BusinessName,
+ sp.Name AS ServicePointName
+ FROM ServicePoints sp
+ JOIN Beacons b ON b.ID = sp.BeaconID
+ JOIN Businesses biz ON biz.ID = sp.BusinessID
+ WHERE sp.BeaconID IS NOT NULL
", {}, { datasource: "payfrit" });
rows = [];
for (row in q) {
- arrayAppend(rows, {
- "BeaconID": row.BeaconID,
- "BusinessID": row.BusinessID,
- "BusinessName": row.BusinessName,
- "ServicePointID": row.ServicePointID
- });
+ arrayAppend(rows, {
+ "BeaconID": row.BeaconID,
+ "BeaconName": row.BeaconName,
+ "BusinessID": row.BusinessID,
+ "BusinessName": row.BusinessName,
+ "ServicePointID": row.ServicePointID,
+ "ServicePointName": row.ServicePointName
+ });
}
writeOutput(serializeJSON({
- "OK": true,
- "MESSAGE": "Switched beacons from BusinessID #fromBiz# to #toBiz#",
- "MAPPINGS": rows
+ "OK": true,
+ "MESSAGE": "Switched beacons from BusinessID #fromBiz# to #toBiz#",
+ "MAPPINGS": rows
}));
diff --git a/api/admin/testTaskInsert.cfm b/api/admin/testTaskInsert.cfm
index f3ee706..3784189 100644
--- a/api/admin/testTaskInsert.cfm
+++ b/api/admin/testTaskInsert.cfm
@@ -7,10 +7,10 @@
qTask = queryExecute("
- SELECT TaskID, TaskTypeID, TaskClaimedByUserID, TaskCompletedOn
+ SELECT ID, TaskTypeID, ClaimedByUserID, CompletedOn
FROM Tasks
- WHERE TaskID = 57
+ WHERE ID = 57
", [], { datasource: "payfrit" });
writeOutput(serializeJSON({
"OK": true,
- "TaskID": qTask.TaskID,
+ "TaskID": qTask.ID,
"TaskTypeID": qTask.TaskTypeID,
- "TaskClaimedByUserID": qTask.TaskClaimedByUserID,
- "TaskCompletedOn": qTask.TaskCompletedOn
+ "ClaimedByUserID": qTask.ClaimedByUserID,
+ "CompletedOn": qTask.CompletedOn
}));
diff --git a/api/admin/updateBeaconMapping.cfm b/api/admin/updateBeaconMapping.cfm
index 6669685..5c5221a 100644
--- a/api/admin/updateBeaconMapping.cfm
+++ b/api/admin/updateBeaconMapping.cfm
@@ -3,50 +3,65 @@
-// Update Beacon 2 to point to In-N-Out (BusinessID 17)
+// Update beacon mapping via join table. Owner (Beacons.BusinessID) is NOT changed.
beaconId = 2;
+oldBusinessId = 37; // previous mapping
newBusinessId = 17;
+// Remove old mapping
queryExecute("
- UPDATE lt_Beacon_Businesses_ServicePoints
- SET BusinessID = :newBizId
- WHERE BeaconID = :beaconId
-", { newBizId: newBusinessId, beaconId: beaconId }, { datasource: "payfrit" });
+ DELETE FROM lt_BeaconsID_BusinessesID
+ WHERE BeaconID = :beaconId AND BusinessID = :oldBizId
+", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" });
+
+// Add new mapping
+queryExecute("
+ INSERT INTO lt_BeaconsID_BusinessesID (BeaconID, BusinessID)
+ VALUES (:beaconId, :newBizId)
+ ON DUPLICATE KEY UPDATE ID = ID
+", { beaconId: beaconId, newBizId: newBusinessId }, { datasource: "payfrit" });
+
+// Clear ServicePoints.BeaconID for old business where this beacon was assigned
+queryExecute("
+ UPDATE ServicePoints
+ SET BeaconID = NULL, AssignedByUserID = NULL
+ WHERE BeaconID = :beaconId AND BusinessID = :oldBizId
+", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" });
// Get current state
q = queryExecute("
- SELECT
- b.BeaconID,
- b.BeaconUUID,
- b.BeaconName,
- lt.BusinessID,
- lt.ServicePointID,
- biz.BusinessName,
- sp.ServicePointName
- FROM Beacons b
- LEFT JOIN lt_Beacon_Businesses_ServicePoints lt ON lt.BeaconID = b.BeaconID
- LEFT JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
- WHERE b.BeaconIsActive = 1
- ORDER BY b.BeaconID
+ SELECT
+ b.ID AS BeaconID,
+ b.UUID,
+ b.Name AS BeaconName,
+ b.BusinessID AS BeaconBusinessID,
+ sp.ID AS ServicePointID,
+ sp.Name AS ServicePointName,
+ sp.BusinessID AS ServicePointBusinessID,
+ biz.Name AS BusinessName
+ FROM Beacons b
+ LEFT JOIN ServicePoints sp ON sp.BeaconID = b.ID
+ LEFT JOIN Businesses biz ON biz.ID = b.BusinessID
+ WHERE b.IsActive = 1
+ ORDER BY b.ID
", {}, { datasource: "payfrit" });
rows = [];
for (row in q) {
- arrayAppend(rows, {
- "BeaconID": row.BeaconID,
- "BeaconUUID": row.BeaconUUID,
- "BeaconName": row.BeaconName ?: "",
- "BusinessID": row.BusinessID ?: 0,
- "BusinessName": row.BusinessName ?: "",
- "ServicePointID": row.ServicePointID ?: 0,
- "ServicePointName": row.ServicePointName ?: ""
- });
+ arrayAppend(rows, {
+ "BeaconID": row.BeaconID,
+ "UUID": row.UUID,
+ "BeaconName": row.BeaconName,
+ "BeaconBusinessID": row.BeaconBusinessID,
+ "BusinessName": row.BusinessName,
+ "ServicePointID": row.ServicePointID ?: 0,
+ "ServicePointName": row.ServicePointName ?: ""
+ });
}
writeOutput(serializeJSON({
- "OK": true,
- "MESSAGE": "Updated beacon #beaconId# to BusinessID #newBusinessId#",
- "BEACONS": rows
+ "OK": true,
+ "MESSAGE": "Updated beacon #beaconId# to BusinessID #newBusinessId#",
+ "BEACONS": rows
}));
diff --git a/api/admin/updateBigDeans.cfm b/api/admin/updateBigDeans.cfm
index fcb672a..94558bb 100644
--- a/api/admin/updateBigDeans.cfm
+++ b/api/admin/updateBigDeans.cfm
@@ -6,72 +6,68 @@
// Update Big Dean's business info
businessId = 27;
-// Big Dean's actual address and hours
-address = "1615 Ocean Front Walk, Santa Monica, CA 90401";
+// Big Dean's actual info
phone = "(310) 393-2666";
hours = "Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm";
try {
- // First get column names from INFORMATION_SCHEMA
- cols = queryExecute("
- SELECT COLUMN_NAME
- FROM INFORMATION_SCHEMA.COLUMNS
- WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'Businesses'
- ORDER BY ORDINAL_POSITION
- ");
-
- colNames = [];
- for (c in cols) {
- arrayAppend(colNames, c.COLUMN_NAME);
- }
-
- // Check if we have the columns we need
- hasAddress = arrayFindNoCase(colNames, "BusinessAddress") > 0;
- hasPhone = arrayFindNoCase(colNames, "BusinessPhone") > 0;
- hasHours = arrayFindNoCase(colNames, "BusinessHours") > 0;
-
- // Add columns if missing
- if (!hasAddress) {
- queryExecute("ALTER TABLE Businesses ADD COLUMN BusinessAddress VARCHAR(255)");
- }
- if (!hasPhone) {
- queryExecute("ALTER TABLE Businesses ADD COLUMN BusinessPhone VARCHAR(50)");
- }
- if (!hasHours) {
- queryExecute("ALTER TABLE Businesses ADD COLUMN BusinessHours VARCHAR(255)");
- }
-
- // Update with new info
+ // Update phone and hours on Businesses table
queryExecute("
UPDATE Businesses
- SET BusinessAddress = :address,
- BusinessPhone = :phone,
- BusinessHours = :hours
- WHERE BusinessID = :bizId
+ SET Phone = :phone,
+ Hours = :hours
+ WHERE ID = :bizId
", {
- address: address,
phone: phone,
hours: hours,
bizId: businessId
- });
+ }, { datasource: "payfrit" });
+
+ // Update or insert address in Addresses table
+ qAddr = queryExecute("
+ SELECT ID FROM Addresses
+ WHERE BusinessID = :bizId AND IsDeleted = 0
+ LIMIT 1
+ ", { bizId: businessId }, { datasource: "payfrit" });
+
+ if (qAddr.recordCount > 0) {
+ queryExecute("
+ UPDATE Addresses
+ SET Line1 = :line1, City = :city, ZIPCode = :zip
+ WHERE ID = :addrId
+ ", {
+ line1: "1615 Ocean Front Walk",
+ city: "Santa Monica",
+ zip: "90401",
+ addrId: qAddr.ID
+ }, { datasource: "payfrit" });
+ } else {
+ queryExecute("
+ INSERT INTO Addresses (BusinessID, UserID, AddressTypeID, Line1, City, ZIPCode, AddedOn)
+ VALUES (:bizId, 0, 'business', :line1, :city, :zip, NOW())
+ ", {
+ bizId: businessId,
+ line1: "1615 Ocean Front Walk",
+ city: "Santa Monica",
+ zip: "90401"
+ }, { datasource: "payfrit" });
+ }
// Get updated record
updated = queryExecute("
- SELECT BusinessID, BusinessName, BusinessAddress, BusinessPhone, BusinessHours
+ SELECT ID, Name, Phone, Hours
FROM Businesses
- WHERE BusinessID = :bizId
- ", { bizId: businessId });
+ WHERE ID = :bizId
+ ", { bizId: businessId }, { datasource: "payfrit" });
writeOutput(serializeJSON({
"OK": true,
"MESSAGE": "Updated Big Dean's info",
- "COLUMNS_EXISTED": { "address": hasAddress, "phone": hasPhone, "hours": hasHours },
"BUSINESS": {
- "BusinessID": updated.BusinessID,
- "BusinessName": updated.BusinessName,
- "BusinessAddress": updated.BusinessAddress,
- "BusinessPhone": updated.BusinessPhone,
- "BusinessHours": updated.BusinessHours
+ "BusinessID": updated.ID,
+ "Name": updated.Name,
+ "Phone": updated.Phone,
+ "Hours": updated.Hours
}
}));
diff --git a/api/assignments/delete.cfm b/api/assignments/delete.cfm
index 2f6d9be..5c75628 100644
--- a/api/assignments/delete.cfm
+++ b/api/assignments/delete.cfm
@@ -34,28 +34,20 @@ if (!structKeyExists(request,"BusinessID") || !isNumeric(request.BusinessID) ||
/* ---------- INPUT ---------- */
data = readJsonBody();
-if (
- !structKeyExists(data,"lt_Beacon_Businesses_ServicePointID")
- || !isNumeric(data.lt_Beacon_Businesses_ServicePointID)
- || int(data.lt_Beacon_Businesses_ServicePointID) LTE 0
-){
- apiAbort({OK=false,ERROR="missing_lt_Beacon_Businesses_ServicePointID"});
+if (!structKeyExists(data,"ServicePointID") || !isNumeric(data.ServicePointID) || int(data.ServicePointID) LTE 0){
+ apiAbort({OK=false,ERROR="missing_ServicePointID"});
}
-RelID = int(data.lt_Beacon_Businesses_ServicePointID);
+ServicePointID = int(data.ServicePointID);
-
+
- SELECT
- lt_Beacon_Businesses_ServicePointID,
- BeaconID,
- ServicePointID
- FROM lt_Beacon_Businesses_ServicePoints
- WHERE lt_Beacon_Businesses_ServicePointID =
-
- AND BusinessID =
-
+ SELECT ID, BeaconID
+ FROM ServicePoints
+ WHERE ID =
+ AND BusinessID =
+ AND BeaconID IS NOT NULL
LIMIT 1
@@ -63,28 +55,28 @@ RelID = int(data.lt_Beacon_Businesses_ServicePointID);
#serializeJSON({
"OK"=false,
"ERROR"="not_found",
- "lt_Beacon_Businesses_ServicePointID"=RelID,
+ "ServicePointID"=ServicePointID,
"BusinessID"=(request.BusinessID & "")
})#
-
+
+
+
- DELETE FROM lt_Beacon_Businesses_ServicePoints
- WHERE lt_Beacon_Businesses_ServicePointID =
-
- AND BusinessID =
-
- LIMIT 1
+ UPDATE ServicePoints
+ SET BeaconID = NULL,
+ AssignedByUserID = NULL
+ WHERE ID =
+ AND BusinessID =
#serializeJSON({
"OK"=true,
"ERROR"="",
- "ACTION"="deleted",
- "lt_Beacon_Businesses_ServicePointID"=RelID,
- "BeaconID"=qFind.BeaconID,
- "ServicePointID"=qFind.ServicePointID,
+ "ACTION"="unassigned",
+ "ServicePointID"=ServicePointID,
+ "BeaconID"=removedBeaconID,
"BusinessID"=(request.BusinessID & "")
})#
diff --git a/api/assignments/list.cfm b/api/assignments/list.cfm
index ab2083d..6b3c97a 100644
--- a/api/assignments/list.cfm
+++ b/api/assignments/list.cfm
@@ -17,32 +17,29 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) ||
SELECT
- lt.lt_Beacon_Businesses_ServicePointID,
- lt.BeaconID,
- lt.BusinessID,
- lt.ServicePointID,
- lt.lt_Beacon_Businesses_ServicePointNotes,
- b.BeaconName,
- b.BeaconUUID,
- sp.ServicePointName
- FROM lt_Beacon_Businesses_ServicePoints lt
- JOIN Beacons b ON b.BeaconID = lt.BeaconID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
- WHERE lt.BusinessID =
- ORDER BY b.BeaconName, sp.ServicePointName
+ sp.ID AS ServicePointID,
+ sp.BeaconID,
+ sp.BusinessID,
+ sp.AssignedByUserID,
+ b.Name AS BeaconName,
+ b.UUID,
+ sp.Name AS ServicePointName
+ FROM ServicePoints sp
+ JOIN Beacons b ON b.ID = sp.BeaconID
+ WHERE sp.BusinessID =
+ AND sp.BeaconID IS NOT NULL
+ ORDER BY b.Name, sp.Name
diff --git a/api/assignments/save.cfm b/api/assignments/save.cfm
index 44b58d9..735db83 100644
--- a/api/assignments/save.cfm
+++ b/api/assignments/save.cfm
@@ -26,11 +26,6 @@ function readJsonBody(){
return parsed;
}
-function normStr(v){
- if (isNull(v)) return "";
- return trim(toString(v));
-}
-
/* ---------- AUTH CONTEXT ---------- */
if (!structKeyExists(request,"BusinessID") || !isNumeric(request.BusinessID) || request.BusinessID LTE 0){
apiAbort({OK=false,ERROR="no_business_selected"});
@@ -48,43 +43,45 @@ if (!structKeyExists(data,"ServicePointID") || !isNumeric(data.ServicePointID) |
BeaconID = int(data.BeaconID);
ServicePointID = int(data.ServicePointID);
-Notes = "";
-if (structKeyExists(data,"Notes")){
- Notes = left(normStr(data.Notes), 255);
-}
-
+
- SELECT BusinessID, BusinessParentBusinessID
+ SELECT ID, ParentBusinessID
FROM Businesses
- WHERE BusinessID =
+ WHERE ID =
LIMIT 1
- SELECT BeaconID
- FROM Beacons
- WHERE BeaconID =
+ SELECT b.ID
+ FROM Beacons b
+ WHERE b.ID =
AND (
- BeaconBusinessID =
-
- OR BeaconBusinessID =
+ b.BusinessID =
+
+ OR b.BusinessID =
+ OR EXISTS (
+ SELECT 1 FROM lt_BeaconsID_BusinessesID lt
+ WHERE lt.BeaconID = b.ID
+ AND lt.BusinessID =
+ )
)
LIMIT 1
- #serializeJSON({OK=false,ERROR="beacon_not_found_for_business"})#
+ #serializeJSON({OK=false,ERROR="beacon_not_allowed"})#
- SELECT ServicePointID
+ SELECT ID
FROM ServicePoints
- WHERE ServicePointID =
- AND ServicePointBusinessID =
+ WHERE ID =
+ AND BusinessID =
LIMIT 1
@@ -92,14 +89,12 @@ if (structKeyExists(data,"Notes")){
-
-
+
- SELECT lt_Beacon_Businesses_ServicePointID
- FROM lt_Beacon_Businesses_ServicePoints
- WHERE BusinessID =
+ SELECT ID
+ FROM ServicePoints
+ WHERE ID =
AND BeaconID =
- AND ServicePointID =
LIMIT 1
@@ -107,31 +102,19 @@ if (structKeyExists(data,"Notes")){
-
+
- INSERT INTO lt_Beacon_Businesses_ServicePoints
- (BusinessID, BeaconID, ServicePointID,
- lt_Beacon_Businesses_ServicePointAssignedByUserID,
- lt_Beacon_Businesses_ServicePointNotes)
- VALUES
- (
- ,
- ,
- ,
- ,
-
- )
-
-
-
- SELECT LAST_INSERT_ID() AS NewID
+ UPDATE ServicePoints
+ SET BeaconID = ,
+ AssignedByUserID =
+ WHERE ID =
+ AND BusinessID =
#serializeJSON({
"OK"=true,
- "ACTION"="inserted",
- "lt_Beacon_Businesses_ServicePointID"=qID.NewID,
- "BeaconID"=BeaconID,
+ "ACTION"="assigned",
"ServicePointID"=ServicePointID,
+ "BeaconID"=BeaconID,
"BusinessID"=(request.BusinessID & "")
})#
diff --git a/api/auth/completeProfile.cfm b/api/auth/completeProfile.cfm
index 53221ad..0ab846f 100644
--- a/api/auth/completeProfile.cfm
+++ b/api/auth/completeProfile.cfm
@@ -71,9 +71,9 @@ try {
// Check if email is already used by another verified account
qEmailCheck = queryExecute("
- SELECT UserID FROM Users
- WHERE UserEmailAddress = :email
- AND UserIsEmailVerified = 1
+ SELECT ID FROM Users
+ WHERE EmailAddress = :email
+ AND IsEmailVerified = 1
AND UserID != :userId
LIMIT 1
", {
@@ -87,19 +87,19 @@ try {
// Get current user UUID for email confirmation link
qUser = queryExecute("
- SELECT UserUUID FROM Users WHERE UserID = :userId
+ SELECT UUID FROM Users WHERE ID = :userId
", { userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
// Update user profile AND mark account as verified/active
// This completes the signup process
queryExecute("
UPDATE Users
- SET UserFirstName = :firstName,
- UserLastName = :lastName,
- UserEmailAddress = :email,
- UserIsEmailVerified = 0,
- UserIsContactVerified = 1,
- UserIsActive = 1
+ SET FirstName = :firstName,
+ LastName = :lastName,
+ EmailAddress = :email,
+ IsEmailVerified = 0,
+ IsContactVerified = 1,
+ IsActive = 1
WHERE UserID = :userId
", {
firstName: { value: firstName, cfsqltype: "cf_sql_varchar" },
@@ -109,7 +109,7 @@ try {
}, { datasource: "payfrit" });
// Send confirmation email (non-blocking - don't fail if mail fails)
- confirmLink = "https://biz.payfrit.com/confirm_email.cfm?UUID=" & qUser.UserUUID;
+ confirmLink = "https://biz.payfrit.com/confirm_email.cfm?UUID=" & qUser.UUID;
emailBody = "
Welcome to Payfrit, #firstName#!
Please click the link below to confirm your email address:
diff --git a/api/auth/login.cfm b/api/auth/login.cfm
index 63a0fb2..c5c4926 100644
--- a/api/auth/login.cfm
+++ b/api/auth/login.cfm
@@ -12,7 +12,7 @@
{ "username": "...", "password": "..." }
OUTPUT (JSON):
- { OK:true, ERROR:"", UserID:123, UserFirstName:"...", Token:"..." }
+ { OK:true, ERROR:"", UserID:123, FirstName:"...", Token:"..." }
Uses existing UserTokens table:
TokenID (auto), UserID, Token, CreatedAt (DEFAULT CURRENT_TIMESTAMP)
@@ -55,16 +55,16 @@ if (!len(username) || !len(password)) {
try {
q = queryExecute(
"
- SELECT UserID, UserFirstName
+ SELECT ID, FirstName
FROM Users
WHERE
(
- (UserEmailAddress = ?) OR
- (UserContactNumber = ?)
+ (EmailAddress = ?) OR
+ (ContactNumber = ?)
)
- AND UserPassword = ?
- AND UserIsEmailVerified = 1
- AND UserIsContactVerified > 0
+ AND Password = ?
+ AND IsEmailVerified = 1
+ AND IsContactVerified > 0
LIMIT 1
",
[
@@ -84,7 +84,7 @@ try {
queryExecute(
"INSERT INTO UserTokens (UserID, Token) VALUES (?, ?)",
[
- { value = q.UserID, cfsqltype = "cf_sql_integer" },
+ { value = q.ID, cfsqltype = "cf_sql_integer" },
{ value = token, cfsqltype = "cf_sql_varchar" }
],
{ datasource = "payfrit" }
@@ -92,15 +92,15 @@ try {
// Optional: also set session for browser tools
lock timeout="15" throwontimeout="yes" type="exclusive" scope="session" {
- session.UserID = q.UserID;
+ session.UserID = q.ID;
}
- request.UserID = q.UserID;
+ request.UserID = q.ID;
writeOutput(serializeJSON({
"OK": true,
"ERROR": "",
- "UserID": q.UserID,
- "UserFirstName": q.UserFirstName,
+ "UserID": q.ID,
+ "FirstName": q.FirstName,
"Token": token
}));
abort;
diff --git a/api/auth/loginOTP.cfm b/api/auth/loginOTP.cfm
index 0241c56..5151238 100644
--- a/api/auth/loginOTP.cfm
+++ b/api/auth/loginOTP.cfm
@@ -53,10 +53,10 @@ try {
// Find verified account with this phone
qUser = queryExecute("
- SELECT UserID, UserUUID
+ SELECT ID, UUID
FROM Users
- WHERE UserContactNumber = :phone
- AND UserIsContactVerified = 1
+ WHERE ContactNumber = :phone
+ AND IsContactVerified = 1
LIMIT 1
", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
@@ -65,14 +65,14 @@ try {
}
// If user has no UUID (legacy account), generate one
- userUUID = qUser.UserUUID;
+ userUUID = qUser.UUID;
if (!len(trim(userUUID))) {
userUUID = replace(createUUID(), "-", "", "all");
queryExecute("
- UPDATE Users SET UserUUID = :uuid WHERE UserID = :userId
+ UPDATE Users SET UUID = :uuid WHERE UserID = :userId
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
- userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" }
+ userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
}
@@ -80,11 +80,11 @@ try {
otp = generateOTP();
queryExecute("
UPDATE Users
- SET UserMobileVerifyCode = :otp
+ SET MobileVerifyCode = :otp
WHERE UserID = :userId
", {
otp: { value: otp, cfsqltype: "cf_sql_varchar" },
- userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" }
+ userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
// Send OTP via Twilio (skip on dev server)
diff --git a/api/auth/profile.cfm b/api/auth/profile.cfm
index 2c9a6b8..e4fa5cb 100644
--- a/api/auth/profile.cfm
+++ b/api/auth/profile.cfm
@@ -59,13 +59,13 @@ if (cgi.REQUEST_METHOD == "GET") {
try {
qUser = queryExecute("
SELECT
- UserID,
- UserFirstName,
- UserLastName,
- UserEmailAddress,
- UserContactNumber
+ ID,
+ FirstName,
+ LastName,
+ EmailAddress,
+ ContactNumber
FROM Users
- WHERE UserID = :userId
+ WHERE ID = :userId
LIMIT 1
", { userId: { value = userId, cfsqltype = "cf_sql_integer" } });
@@ -76,11 +76,11 @@ if (cgi.REQUEST_METHOD == "GET") {
writeOutput(serializeJSON({
"OK": true,
"USER": {
- "UserID": qUser.UserID,
- "FirstName": qUser.UserFirstName ?: "",
- "LastName": qUser.UserLastName ?: "",
- "Email": qUser.UserEmailAddress ?: "",
- "Phone": qUser.UserContactNumber ?: ""
+ "UserID": qUser.ID,
+ "FirstName": qUser.FirstName ?: "",
+ "LastName": qUser.LastName ?: "",
+ "Email": qUser.EmailAddress ?: "",
+ "Phone": qUser.ContactNumber ?: ""
}
}));
abort;
@@ -110,12 +110,12 @@ if (cgi.REQUEST_METHOD == "POST") {
params = { userId: { value = userId, cfsqltype = "cf_sql_integer" } };
if (structKeyExists(data, "firstName")) {
- arrayAppend(updates, "UserFirstName = :firstName");
+ arrayAppend(updates, "FirstName = :firstName");
params.firstName = { value = data.firstName, cfsqltype = "cf_sql_varchar" };
}
if (structKeyExists(data, "lastName")) {
- arrayAppend(updates, "UserLastName = :lastName");
+ arrayAppend(updates, "LastName = :lastName");
params.lastName = { value = data.lastName, cfsqltype = "cf_sql_varchar" };
}
@@ -133,13 +133,13 @@ if (cgi.REQUEST_METHOD == "POST") {
// Return updated profile
qUser = queryExecute("
SELECT
- UserID,
- UserFirstName,
- UserLastName,
- UserEmailAddress,
- UserContactNumber
+ ID,
+ FirstName,
+ LastName,
+ EmailAddress,
+ ContactNumber
FROM Users
- WHERE UserID = :userId
+ WHERE ID = :userId
LIMIT 1
", { userId: { value = userId, cfsqltype = "cf_sql_integer" } });
@@ -147,11 +147,11 @@ if (cgi.REQUEST_METHOD == "POST") {
"OK": true,
"MESSAGE": "Profile updated",
"USER": {
- "UserID": qUser.UserID,
- "FirstName": qUser.UserFirstName ?: "",
- "LastName": qUser.UserLastName ?: "",
- "Email": qUser.UserEmailAddress ?: "",
- "Phone": qUser.UserContactNumber ?: ""
+ "UserID": qUser.ID,
+ "FirstName": qUser.FirstName ?: "",
+ "LastName": qUser.LastName ?: "",
+ "Email": qUser.EmailAddress ?: "",
+ "Phone": qUser.ContactNumber ?: ""
}
}));
abort;
diff --git a/api/auth/sendOTP.cfm b/api/auth/sendOTP.cfm
index c558d60..b10e36c 100644
--- a/api/auth/sendOTP.cfm
+++ b/api/auth/sendOTP.cfm
@@ -57,12 +57,12 @@ try {
// Check if phone already has a COMPLETE account (verified AND has profile info)
// An account is only "complete" if they have a first name (meaning they finished signup)
qExisting = queryExecute("
- SELECT UserID, UserUUID, UserFirstName
+ SELECT ID, UUID, FirstName
FROM Users
- WHERE UserContactNumber = :phone
- AND UserIsContactVerified > 0
- AND UserFirstName IS NOT NULL
- AND LENGTH(TRIM(UserFirstName)) > 0
+ WHERE ContactNumber = :phone
+ AND IsContactVerified > 0
+ AND FirstName IS NOT NULL
+ AND LENGTH(TRIM(FirstName)) > 0
LIMIT 1
", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
@@ -73,10 +73,10 @@ try {
// Check for incomplete account with this phone (verified but no profile, OR unverified)
// These accounts can be reused for signup
qIncomplete = queryExecute("
- SELECT UserID, UserUUID
+ SELECT ID, UUID
FROM Users
- WHERE UserContactNumber = :phone
- AND (UserIsContactVerified = 0 OR UserFirstName IS NULL OR LENGTH(TRIM(UserFirstName)) = 0)
+ WHERE ContactNumber = :phone
+ AND (IsContactVerified = 0 OR FirstName IS NULL OR LENGTH(TRIM(FirstName)) = 0)
LIMIT 1
", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
@@ -85,12 +85,12 @@ try {
if (qIncomplete.recordCount > 0) {
// Update existing incomplete record with new OTP and reset for re-registration
- userUUID = qIncomplete.UserUUID;
+ userUUID = qIncomplete.UUID;
queryExecute("
UPDATE Users
- SET UserMobileVerifyCode = :otp,
- UserIsContactVerified = 0,
- UserIsActive = 0
+ SET MobileVerifyCode = :otp,
+ IsContactVerified = 0,
+ IsActive = 0
WHERE UserID = :userId
", {
otp: { value: otp, cfsqltype: "cf_sql_varchar" },
@@ -101,15 +101,15 @@ try {
userUUID = replace(createUUID(), "-", "", "all");
queryExecute("
INSERT INTO Users (
- UserContactNumber,
- UserUUID,
- UserMobileVerifyCode,
- UserIsContactVerified,
- UserIsEmailVerified,
- UserIsActive,
- UserAddedOn,
- UserPassword,
- UserPromoCode
+ ContactNumber,
+ UUID,
+ MobileVerifyCode,
+ IsContactVerified,
+ IsEmailVerified,
+ IsActive,
+ AddedOn,
+ Password,
+ PromoCode
) VALUES (
:phone,
:uuid,
diff --git a/api/auth/validateToken.cfm b/api/auth/validateToken.cfm
index a6d587e..ca668a7 100644
--- a/api/auth/validateToken.cfm
+++ b/api/auth/validateToken.cfm
@@ -32,10 +32,10 @@ try {
}
// Look up the token
- qToken = queryTimed("
- SELECT ut.UserID, u.UserFirstName, u.UserLastName
+ qToken = queryExecute("
+ SELECT ut.UserID, u.FirstName, u.LastName
FROM UserTokens ut
- JOIN Users u ON u.UserID = ut.UserID
+ JOIN Users u ON u.ID = ut.UserID
WHERE ut.Token = :token
LIMIT 1
", { token: { value: token, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
@@ -47,20 +47,19 @@ try {
userID = qToken.UserID;
// Determine if user is a worker (has any active employment)
- qWorker = queryTimed("
+ qWorker = queryExecute("
SELECT COUNT(*) as cnt
- FROM lt_Users_Businesses_Employees
- WHERE UserID = :userID AND EmployeeIsActive = 1
+ FROM Employees
+ WHERE UserID = :userID AND IsActive = 1
", { userID: { value: userID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
userType = qWorker.cnt > 0 ? "worker" : "customer";
- logPerf();
apiAbort({
"OK": true,
"UserID": userID,
"UserType": userType,
- "UserName": trim(qToken.UserFirstName & " " & qToken.UserLastName)
+ "UserName": trim(qToken.FirstName & " " & qToken.LastName)
});
} catch (any e) {
diff --git a/api/auth/verifyLoginOTP.cfm b/api/auth/verifyLoginOTP.cfm
index 67f6261..df7082f 100644
--- a/api/auth/verifyLoginOTP.cfm
+++ b/api/auth/verifyLoginOTP.cfm
@@ -9,7 +9,7 @@
*
* POST: { "uuid": "...", "otp": "123456" }
*
- * Returns: { OK: true, UserID: 123, Token: "...", UserFirstName: "..." }
+ * Returns: { OK: true, UserID: 123, Token: "...", FirstName: "..." }
*/
function apiAbort(required struct payload) {
@@ -46,21 +46,21 @@ try {
// Find verified user with matching UUID and OTP (or magic OTP)
if (isMagicOTP) {
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName
+ SELECT ID, FirstName, LastName
FROM Users
- WHERE UserUUID = :uuid
- AND UserIsContactVerified = 1
+ WHERE UUID = :uuid
+ AND IsContactVerified = 1
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
} else {
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName
+ SELECT ID, FirstName, LastName
FROM Users
- WHERE UserUUID = :uuid
- AND UserMobileVerifyCode = :otp
- AND UserIsContactVerified = 1
+ WHERE UUID = :uuid
+ AND MobileVerifyCode = :otp
+ AND IsContactVerified = 1
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
@@ -71,7 +71,7 @@ try {
if (qUser.recordCount == 0) {
// Check if UUID exists but OTP is wrong
qCheck = queryExecute("
- SELECT UserID FROM Users WHERE UserUUID = :uuid AND UserIsContactVerified = 1
+ SELECT ID FROM Users WHERE UUID = :uuid AND IsContactVerified = 1
", { uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
if (qCheck.recordCount > 0) {
@@ -84,24 +84,24 @@ try {
// Clear the OTP (one-time use)
queryExecute("
UPDATE Users
- SET UserMobileVerifyCode = ''
+ SET MobileVerifyCode = ''
WHERE UserID = :userId
- ", { userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
+ ", { userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
// Create auth token
token = replace(createUUID(), "-", "", "all");
queryExecute("
INSERT INTO UserTokens (UserID, Token) VALUES (:userId, :token)
", {
- userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" },
+ userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" },
token: { value: token, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
writeOutput(serializeJSON({
"OK": true,
- "UserID": qUser.UserID,
+ "UserID": qUser.ID,
"Token": token,
- "UserFirstName": qUser.UserFirstName ?: ""
+ "FirstName": qUser.FirstName ?: ""
}));
} catch (any e) {
diff --git a/api/auth/verifyOTP.cfm b/api/auth/verifyOTP.cfm
index 13bdab1..c9154b8 100644
--- a/api/auth/verifyOTP.cfm
+++ b/api/auth/verifyOTP.cfm
@@ -49,21 +49,21 @@ try {
// Find unverified user with matching UUID and OTP (or magic OTP)
if (isMagicOTP) {
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName, UserEmailAddress, UserIsEmailVerified
+ SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified
FROM Users
- WHERE UserUUID = :uuid
- AND UserIsContactVerified = 0
+ WHERE UUID = :uuid
+ AND IsContactVerified = 0
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
} else {
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName, UserEmailAddress, UserIsEmailVerified
+ SELECT ID, FirstName, LastName, EmailAddress, IsEmailVerified
FROM Users
- WHERE UserUUID = :uuid
- AND UserMobileVerifyCode = :otp
- AND UserIsContactVerified = 0
+ WHERE UUID = :uuid
+ AND MobileVerifyCode = :otp
+ AND IsContactVerified = 0
LIMIT 1
", {
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
@@ -74,7 +74,7 @@ try {
if (qUser.recordCount == 0) {
// Check if UUID exists but OTP is wrong
qCheck = queryExecute("
- SELECT UserID FROM Users WHERE UserUUID = :uuid AND UserIsContactVerified = 0
+ SELECT ID FROM Users WHERE UUID = :uuid AND IsContactVerified = 0
", { uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
if (qCheck.recordCount > 0) {
@@ -88,30 +88,30 @@ try {
// Account will be marked verified after profile completion
queryExecute("
UPDATE Users
- SET UserMobileVerifyCode = ''
+ SET MobileVerifyCode = ''
WHERE UserID = :userId
- ", { userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
+ ", { userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
// Create auth token (needed for completeProfile call)
token = replace(createUUID(), "-", "", "all");
queryExecute("
INSERT INTO UserTokens (UserID, Token) VALUES (:userId, :token)
", {
- userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" },
+ userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" },
token: { value: token, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
// Check if profile is complete (has first name)
// For new signups, this will always be true
- needsProfile = !len(trim(qUser.UserFirstName));
+ needsProfile = !len(trim(qUser.FirstName));
writeOutput(serializeJSON({
"OK": true,
- "UserID": qUser.UserID,
+ "UserID": qUser.ID,
"Token": token,
"NeedsProfile": needsProfile,
- "UserFirstName": qUser.UserFirstName ?: "",
- "IsEmailVerified": qUser.UserIsEmailVerified == 1
+ "FirstName": qUser.FirstName ?: "",
+ "IsEmailVerified": qUser.IsEmailVerified == 1
}));
} catch (any e) {
diff --git a/api/beacons/delete.cfm b/api/beacons/delete.cfm
index eccf40b..52fe7dc 100644
--- a/api/beacons/delete.cfm
+++ b/api/beacons/delete.cfm
@@ -49,17 +49,31 @@ beaconId = int(data.BeaconID);
UPDATE Beacons
- SET BeaconIsActive = 0
- WHERE BeaconID =
- AND BeaconBusinessID =
+ SET IsActive = 0
+ WHERE ID =
+ AND (
+ BusinessID =
+ OR ID IN (
+ SELECT lt.BeaconID FROM lt_BeaconsID_BusinessesID lt
+ WHERE lt.BeaconID =
+ AND lt.BusinessID =
+ )
+ )
- SELECT BeaconID, BeaconIsActive
+ SELECT ID, IsActive
FROM Beacons
- WHERE BeaconID =
- AND BeaconBusinessID =
+ WHERE ID =
+ AND (
+ BusinessID =
+ OR EXISTS (
+ SELECT 1 FROM lt_BeaconsID_BusinessesID lt
+ WHERE lt.BeaconID =
+ AND lt.BusinessID =
+ )
+ )
LIMIT 1
diff --git a/api/beacons/get.cfm b/api/beacons/get.cfm
index 766817d..8111185 100644
--- a/api/beacons/get.cfm
+++ b/api/beacons/get.cfm
@@ -37,14 +37,21 @@ beaconId = int(data.BeaconID);
SELECT
- BeaconID,
- BeaconBusinessID,
- BeaconName,
- BeaconUUID,
- BeaconIsActive
- FROM Beacons
- WHERE BeaconID =
- AND BeaconBusinessID =
+ b.ID,
+ b.BusinessID,
+ b.Name,
+ b.UUID,
+ b.IsActive
+ FROM Beacons b
+ WHERE b.ID =
+ AND (
+ b.BusinessID =
+ OR EXISTS (
+ SELECT 1 FROM lt_BeaconsID_BusinessesID lt
+ WHERE lt.BeaconID = b.ID
+ AND lt.BusinessID =
+ )
+ )
LIMIT 1
@@ -54,11 +61,11 @@ beaconId = int(data.BeaconID);
#serializeJSON({ OK=true, ERROR="", BEACON=beacon })#
diff --git a/api/beacons/getBusinessFromBeacon.cfm b/api/beacons/getBusinessFromBeacon.cfm
index 4ba78db..25a8b3a 100644
--- a/api/beacons/getBusinessFromBeacon.cfm
+++ b/api/beacons/getBusinessFromBeacon.cfm
@@ -33,10 +33,10 @@ beaconId = int(data.BeaconID);
- SELECT BeaconID, BeaconName, BeaconUUID, BeaconBusinessID
+ SELECT ID, Name, UUID, BusinessID
FROM Beacons
- WHERE BeaconID =
- AND BeaconIsActive = 1
+ WHERE ID =
+ AND IsActive = 1
LIMIT 1
@@ -45,20 +45,36 @@ beaconId = int(data.BeaconID);
-
+
+ SELECT
+ sp.BusinessID,
+ sp.ID AS ServicePointID,
+ biz.Name AS BusinessName,
+ biz.ParentBusinessID,
+ sp.Name AS ServicePointName
+ FROM ServicePoints sp
+ INNER JOIN Businesses biz ON biz.ID = sp.BusinessID
+ WHERE sp.BeaconID =
+ AND sp.IsActive = 1
+
+ UNION
+
SELECT
lt.BusinessID,
- lt.ServicePointID,
- biz.BusinessName,
- biz.BusinessParentBusinessID,
- sp.ServicePointName
- FROM lt_Beacon_Businesses_ServicePoints lt
- INNER JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
- INNER JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
+ 0 AS ServicePointID,
+ biz.Name AS BusinessName,
+ biz.ParentBusinessID,
+ '' AS ServicePointName
+ FROM lt_BeaconsID_BusinessesID lt
+ INNER JOIN Businesses biz ON biz.ID = lt.BusinessID
WHERE lt.BeaconID =
- AND sp.ServicePointIsActive = 1
- ORDER BY biz.BusinessParentBusinessID IS NULL DESC, biz.BusinessName ASC
+ AND lt.BusinessID NOT IN (
+ SELECT sp2.BusinessID FROM ServicePoints sp2
+ WHERE sp2.BeaconID = AND sp2.IsActive = 1
+ )
+
+ ORDER BY ParentBusinessID IS NULL DESC, BusinessName ASC
@@ -67,7 +83,7 @@ beaconId = int(data.BeaconID);
SELECT COUNT(*) as cnt FROM Businesses
- WHERE BusinessParentBusinessID =
+ WHERE ParentBusinessID =
@@ -82,24 +98,24 @@ beaconId = int(data.BeaconID);
- SELECT BusinessName, BusinessHeaderImageExtension
+ SELECT Name, HeaderImageExtension
FROM Businesses
- WHERE BusinessID =
+ WHERE ID =
SELECT
- BusinessID,
- BusinessName,
- BusinessParentBusinessID,
- BusinessHeaderImageExtension
+ ID,
+ Name,
+ ParentBusinessID,
+ HeaderImageExtension
FROM Businesses
- WHERE BusinessParentBusinessID =
- ORDER BY BusinessName ASC
+ WHERE ParentBusinessID =
+ ORDER BY Name ASC
@@ -123,16 +139,16 @@ beaconId = int(data.BeaconID);
"OK" = true,
"ERROR" = "",
"BEACON" = {
- "BeaconID" = qBeacon.BeaconID,
- "BeaconName" = qBeacon.BeaconName,
- "UUID" = qBeacon.BeaconUUID
+ "BeaconID" = qBeacon.ID,
+ "Name" = qBeacon.Name,
+ "UUID" = qBeacon.UUID
},
"BUSINESSES" = businesses,
"BUSINESS" = arrayLen(businesses) GT 0 ? businesses[1] : {},
"SERVICEPOINT" = arrayLen(businesses) GT 0 ? {
"ServicePointID" = businesses[1].ServicePointID,
- "ServicePointName" = businesses[1].ServicePointName,
- "ServicePointIsActive" = true
+ "Name" = businesses[1].ServicePointName,
+ "IsActive" = true
} : {}
}>
@@ -140,8 +156,8 @@ beaconId = int(data.BeaconID);
diff --git a/api/beacons/list.cfm b/api/beacons/list.cfm
index 2aaf6a9..22a1623 100644
--- a/api/beacons/list.cfm
+++ b/api/beacons/list.cfm
@@ -56,30 +56,35 @@ if (structKeyExists(data, "onlyActive")) {
- SELECT
- BeaconID,
- BeaconBusinessID,
- BeaconName,
- BeaconUUID,
- BeaconIsActive
- FROM Beacons
- WHERE BeaconBusinessID =
+ SELECT DISTINCT
+ b.ID,
+ b.BusinessID,
+ b.Name,
+ b.UUID,
+ b.IsActive
+ FROM Beacons b
+ WHERE (
+ b.BusinessID =
+ OR b.ID IN (
+ SELECT lt.BeaconID FROM lt_BeaconsID_BusinessesID lt
+ WHERE lt.BusinessID =
+ )
+ )
- AND BeaconIsActive = 1
+ AND b.IsActive = 1
- ORDER BY BeaconName, BeaconID
+ ORDER BY b.Name, b.ID
-
#serializeJSON({ OK=true, ERROR="", BusinessID=bizId, COUNT=arrayLen(beacons), BEACONS=beacons })#
diff --git a/api/beacons/list_all.cfm b/api/beacons/list_all.cfm
index 0d01104..54308ef 100644
--- a/api/beacons/list_all.cfm
+++ b/api/beacons/list_all.cfm
@@ -15,18 +15,18 @@ function apiAbort(obj) {
SELECT
- BeaconID,
- BeaconUUID
+ ID,
+ UUID
FROM Beacons
- WHERE BeaconIsActive = 1
- ORDER BY BeaconID
+ WHERE IsActive = 1
+ ORDER BY ID
diff --git a/api/beacons/lookup.cfm b/api/beacons/lookup.cfm
index 515cc98..3a41d7a 100644
--- a/api/beacons/lookup.cfm
+++ b/api/beacons/lookup.cfm
@@ -16,13 +16,13 @@
* {
* UUID: "...",
* BeaconID: int,
- * BeaconName: string,
+ * Name: string,
* BusinessID: int,
- * BusinessName: string,
+ * Name: string,
* ServicePointID: int,
- * ServicePointName: string,
+ * Name: string,
* ParentBusinessID: int (if applicable),
- * ParentBusinessName: string (if applicable),
+ * ParentName: string (if applicable),
* HasChildren: boolean
* }
* ]
@@ -60,28 +60,28 @@ try {
}
// Query for matching beacons with business info
- // Beacons link to ServicePoints via lt_Beacon_Businesses_ServicePoints
+ // Beacons resolve to businesses via: ServicePoints, join table, or owner
qBeacons = queryExecute("
SELECT
- b.BeaconID,
- b.BeaconName,
- b.BeaconUUID,
- COALESCE(link.ServicePointID, 0) AS ServicePointID,
- COALESCE(sp.ServicePointName, '') AS ServicePointName,
- COALESCE(link.BusinessID, b.BeaconBusinessID) AS BusinessID,
- biz.BusinessName,
- biz.BusinessParentBusinessID,
- parent.BusinessName AS ParentBusinessName,
- (SELECT COUNT(*) FROM Businesses WHERE BusinessParentBusinessID = biz.BusinessID) AS ChildCount
+ b.ID,
+ b.Name,
+ b.UUID,
+ COALESCE(sp.ID, 0) AS ServicePointID,
+ COALESCE(sp.Name, '') AS Name,
+ COALESCE(sp.BusinessID, lt.BusinessID, b.BusinessID) AS BusinessID,
+ biz.Name,
+ biz.ParentBusinessID,
+ parent.Name AS ParentName,
+ (SELECT COUNT(*) FROM Businesses WHERE ParentBusinessID = biz.ID) AS ChildCount
FROM Beacons b
- LEFT JOIN lt_Beacon_Businesses_ServicePoints link ON b.BeaconID = link.BeaconID
- LEFT JOIN ServicePoints sp ON link.ServicePointID = sp.ServicePointID
- INNER JOIN Businesses biz ON COALESCE(link.BusinessID, b.BeaconBusinessID) = biz.BusinessID
- LEFT JOIN Businesses parent ON biz.BusinessParentBusinessID = parent.BusinessID
- WHERE b.BeaconUUID IN (:uuids)
- AND b.BeaconIsActive = 1
- AND biz.BusinessIsDemo = 0
- AND biz.BusinessIsPrivate = 0
+ LEFT JOIN ServicePoints sp ON sp.BeaconID = b.ID
+ LEFT JOIN lt_BeaconsID_BusinessesID lt ON lt.BeaconID = b.ID
+ INNER JOIN Businesses biz ON COALESCE(sp.BusinessID, lt.BusinessID, b.BusinessID) = biz.ID
+ LEFT JOIN Businesses parent ON biz.ParentBusinessID = parent.ID
+ WHERE b.UUID IN (:uuids)
+ AND b.IsActive = 1
+ AND biz.IsDemo = 0
+ AND biz.IsPrivate = 0
", {
uuids: { value: arrayToList(cleanUUIDs), cfsqltype: "cf_sql_varchar", list: true }
}, { datasource: "payfrit" });
@@ -89,15 +89,15 @@ try {
beacons = [];
for (row in qBeacons) {
arrayAppend(beacons, {
- "UUID": row.BeaconUUID,
- "BeaconID": row.BeaconID,
- "BeaconName": row.BeaconName,
+ "UUID": row.UUID,
+ "BeaconID": row.ID,
+ "Name": row.Name,
"BusinessID": row.BusinessID,
- "BusinessName": row.BusinessName,
+ "Name": row.Name,
"ServicePointID": row.ServicePointID,
- "ServicePointName": row.ServicePointName,
- "ParentBusinessID": val(row.BusinessParentBusinessID),
- "ParentBusinessName": row.ParentBusinessName ?: "",
+ "Name": row.Name,
+ "ParentBusinessID": val(row.ParentBusinessID),
+ "ParentName": row.ParentName ?: "",
"HasChildren": row.ChildCount > 0
});
}
diff --git a/api/beacons/reassign_all.cfm b/api/beacons/reassign_all.cfm
index e9e2b09..46d26cf 100644
--- a/api/beacons/reassign_all.cfm
+++ b/api/beacons/reassign_all.cfm
@@ -7,11 +7,11 @@
UPDATE Beacons
- SET BeaconBusinessID =
+ SET BusinessID =
- SELECT COUNT(*) AS cnt FROM Beacons WHERE BeaconBusinessID =
+ SELECT COUNT(*) AS cnt FROM Beacons WHERE BusinessID =
#serializeJSON({ "OK": true, "MESSAGE": "All beacons reassigned to BusinessID #targetBusinessID#", "COUNT": qCount.cnt })#
diff --git a/api/beacons/save.cfm b/api/beacons/save.cfm
index 615f2e5..6083941 100644
--- a/api/beacons/save.cfm
+++ b/api/beacons/save.cfm
@@ -36,7 +36,7 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) ||
// Verify the business exists
qBiz = queryExecute(
- "SELECT BusinessID FROM Businesses WHERE BusinessID = ? LIMIT 1",
+ "SELECT ID FROM Businesses WHERE ID = ? LIMIT 1",
[ { value=request.BusinessID, cfsqltype="cf_sql_integer" } ],
{ datasource="payfrit" }
);
@@ -44,8 +44,8 @@ if (qBiz.recordCount EQ 0) {
apiAbort({ OK=false, ERROR="invalid_business", MESSAGE="Business ID #request.BusinessID# does not exist. Please log out and log back in." });
}
-if (!structKeyExists(data, "BeaconName") || len(normStr(data.BeaconName)) EQ 0) {
- apiAbort({ OK=false, ERROR="missing_beacon_name", MESSAGE="BeaconName is required" });
+if (!structKeyExists(data, "Name") || len(normStr(data.Name)) EQ 0) {
+ apiAbort({ OK=false, ERROR="missing_beacon_name", MESSAGE="Name is required" });
}
beaconId = 0;
@@ -53,7 +53,7 @@ if (structKeyExists(data, "BeaconID") && isNumeric(data.BeaconID) && int(data.Be
beaconId = int(data.BeaconID);
}
-beaconName = normStr(data.BeaconName);
+beaconName = normStr(data.Name);
uuid = structKeyExists(data, "UUID") ? normStr(data.UUID) : "";
isActive = 1;
@@ -66,12 +66,12 @@ if (structKeyExists(data, "IsActive")) {
// App is authoritative: if UUID exists, treat as update (overwrite)
if (beaconId EQ 0 && len(uuid) GT 0) {
qExisting = queryExecute(
- "SELECT BeaconID FROM Beacons WHERE BeaconUUID = ? LIMIT 1",
+ "SELECT ID FROM Beacons WHERE UUID = ? LIMIT 1",
[ { value=uuid, cfsqltype="cf_sql_varchar" } ],
{ datasource="payfrit" }
);
if (qExisting.recordCount GT 0) {
- beaconId = qExisting.BeaconID;
+ beaconId = qExisting.ID;
}
}
@@ -81,59 +81,41 @@ if (beaconId EQ 0 && len(uuid) GT 0) {
UPDATE Beacons
SET
- BeaconBusinessID = ,
- BeaconName = ,
- BeaconUUID = ,
- BeaconIsActive =
- WHERE BeaconID =
+ BusinessID = ,
+ Name = ,
+ UUID = ,
+ IsActive =
+ WHERE ID =
- SELECT ServicePointID FROM lt_Beacon_Businesses_ServicePoints
+ SELECT ID FROM ServicePoints
WHERE BeaconID =
LIMIT 1
UPDATE ServicePoints
- SET ServicePointName = ,
- ServicePointBusinessID =
- WHERE ServicePointID =
-
-
-
- UPDATE lt_Beacon_Businesses_ServicePoints
- SET BusinessID =
+ SET Name = ,
+ BusinessID =
WHERE BeaconID =
-
+
INSERT INTO ServicePoints (
- ServicePointBusinessID,
- ServicePointName,
- ServicePointTypeID,
- ServicePointIsActive
+ BusinessID,
+ Name,
+ TypeID,
+ IsActive,
+ BeaconID
) VALUES (
,
,
1,
- 1
- )
-
-
- SELECT LAST_INSERT_ID() AS ServicePointID
-
-
- INSERT INTO lt_Beacon_Businesses_ServicePoints (
- BusinessID,
- BeaconID,
- ServicePointID
- ) VALUES (
- ,
- ,
-
+ 1,
+
)
@@ -142,10 +124,10 @@ if (beaconId EQ 0 && len(uuid) GT 0) {
INSERT INTO Beacons (
- BeaconBusinessID,
- BeaconName,
- BeaconUUID,
- BeaconIsActive
+ BusinessID,
+ Name,
+ UUID,
+ IsActive
) VALUES (
,
,
@@ -155,40 +137,24 @@ if (beaconId EQ 0 && len(uuid) GT 0) {
- SELECT LAST_INSERT_ID() AS BeaconID
+ SELECT LAST_INSERT_ID() AS ID
-
+
-
+
INSERT INTO ServicePoints (
- ServicePointBusinessID,
- ServicePointName,
- ServicePointTypeID,
- ServicePointIsActive
+ BusinessID,
+ Name,
+ TypeID,
+ IsActive,
+ BeaconID
) VALUES (
,
,
1,
- 1
- )
-
-
-
- SELECT LAST_INSERT_ID() AS ServicePointID
-
-
-
-
-
- INSERT INTO lt_Beacon_Businesses_ServicePoints (
- BusinessID,
- BeaconID,
- ServicePointID
- ) VALUES (
- ,
- ,
-
+ 1,
+
)
@@ -196,23 +162,23 @@ if (beaconId EQ 0 && len(uuid) GT 0) {
SELECT
- BeaconID,
- BeaconBusinessID,
- BeaconName,
- BeaconUUID,
- BeaconIsActive
+ ID,
+ BusinessID,
+ Name,
+ UUID,
+ IsActive
FROM Beacons
- WHERE BeaconID =
- AND BeaconBusinessID =
+ WHERE ID =
+ AND BusinessID =
LIMIT 1
#serializeJSON({ OK=true, ERROR="", BEACON=beacon })#
diff --git a/api/businesses/get.cfm b/api/businesses/get.cfm
index c142359..7bc4e08 100644
--- a/api/businesses/get.cfm
+++ b/api/businesses/get.cfm
@@ -32,28 +32,20 @@ try {
abort;
}
- // Check cache (5 minute TTL)
- cached = appCacheGet("biz_" & businessID, 300);
- if (!isNull(cached)) {
- logPerf();
- writeOutput(cached);
- abort;
- }
-
// Get business details
- q = queryTimed("
+ q = queryExecute("
SELECT
- BusinessID,
- BusinessName,
- BusinessPhone,
- BusinessStripeAccountID,
- BusinessStripeOnboardingComplete,
- BusinessIsHiring,
- BusinessHeaderImageExtension,
- BusinessTaxRate,
- BusinessBrandColor
+ ID,
+ Name,
+ Phone,
+ StripeAccountID,
+ StripeOnboardingComplete,
+ IsHiring,
+ HeaderImageExtension,
+ TaxRate,
+ BrandColor
FROM Businesses
- WHERE BusinessID = :businessID
+ WHERE ID = :businessID
", { businessID: businessID }, { datasource: "payfrit" });
if (q.recordCount == 0) {
@@ -62,13 +54,13 @@ try {
abort;
}
- // Get address from Addresses table (either linked via AddressBusinessID or via Businesses.BusinessAddressID)
- qAddr = queryTimed("
- SELECT a.AddressLine1, a.AddressLine2, a.AddressCity, a.AddressZIPCode, s.tt_StateAbbreviation
+ // Get address from Addresses table (either linked via BusinessID or via Businesses.AddressID)
+ qAddr = queryExecute("
+ SELECT a.Line1, a.Line2, a.City, a.ZIPCode, s.Abbreviation
FROM Addresses a
- LEFT JOIN tt_States s ON s.tt_StateID = a.AddressStateID
- WHERE (a.AddressBusinessID = :businessID OR a.AddressID = (SELECT BusinessAddressID FROM Businesses WHERE BusinessID = :businessID))
- AND a.AddressIsDeleted = 0
+ LEFT JOIN tt_States s ON s.ID = a.StateID
+ WHERE (a.BusinessID = :businessID OR a.ID = (SELECT AddressID FROM Businesses WHERE ID = :businessID))
+ AND a.IsDeleted = 0
LIMIT 1
", { businessID: businessID }, { datasource: "payfrit" });
@@ -78,29 +70,29 @@ try {
addressState = "";
addressZip = "";
if (qAddr.recordCount > 0) {
- addressLine1 = qAddr.AddressLine1;
- addressCity = qAddr.AddressCity;
- addressState = qAddr.tt_StateAbbreviation;
- addressZip = qAddr.AddressZIPCode;
+ addressLine1 = qAddr.Line1;
+ addressCity = qAddr.City;
+ addressState = qAddr.Abbreviation;
+ addressZip = qAddr.ZIPCode;
addressParts = [];
- if (len(qAddr.AddressLine1)) arrayAppend(addressParts, qAddr.AddressLine1);
- if (len(qAddr.AddressLine2)) arrayAppend(addressParts, qAddr.AddressLine2);
+ if (len(qAddr.Line1)) arrayAppend(addressParts, qAddr.Line1);
+ if (len(qAddr.Line2)) arrayAppend(addressParts, qAddr.Line2);
cityStateZip = [];
- if (len(qAddr.AddressCity)) arrayAppend(cityStateZip, qAddr.AddressCity);
- if (len(qAddr.tt_StateAbbreviation)) arrayAppend(cityStateZip, qAddr.tt_StateAbbreviation);
- if (len(qAddr.AddressZIPCode)) arrayAppend(cityStateZip, qAddr.AddressZIPCode);
+ if (len(qAddr.City)) arrayAppend(cityStateZip, qAddr.City);
+ if (len(qAddr.Abbreviation)) arrayAppend(cityStateZip, qAddr.Abbreviation);
+ if (len(qAddr.ZIPCode)) arrayAppend(cityStateZip, qAddr.ZIPCode);
if (arrayLen(cityStateZip) > 0) arrayAppend(addressParts, arrayToList(cityStateZip, ", "));
addressStr = arrayToList(addressParts, ", ");
}
// Get hours from Hours table
- qHours = queryTimed("
- SELECT h.HoursDayID, h.HoursOpenTime, h.HoursClosingTime, d.tt_DayAbbrev
+ qHours = queryExecute("
+ SELECT h.DayID, h.OpenTime, h.ClosingTime, d.Abbrev
FROM Hours h
- JOIN tt_Days d ON d.tt_DayID = h.HoursDayID
- WHERE h.HoursBusinessID = :businessID
- ORDER BY h.HoursDayID
+ JOIN tt_Days d ON d.ID = h.DayID
+ WHERE h.BusinessID = :businessID
+ ORDER BY h.DayID
", { businessID: businessID }, { datasource: "payfrit" });
hoursArr = [];
@@ -108,10 +100,10 @@ try {
if (qHours.recordCount > 0) {
for (h in qHours) {
arrayAppend(hoursArr, {
- "day": h.tt_DayAbbrev,
- "dayId": h.HoursDayID,
- "open": timeFormat(h.HoursOpenTime, "h:mm tt"),
- "close": timeFormat(h.HoursClosingTime, "h:mm tt")
+ "day": h.Abbrev,
+ "dayId": h.DayID,
+ "open": timeFormat(h.OpenTime, "h:mm tt"),
+ "close": timeFormat(h.ClosingTime, "h:mm tt")
});
}
// Build readable hours string (group similar days)
@@ -133,44 +125,36 @@ try {
}
// Build business object
- taxRate = isNumeric(q.BusinessTaxRate) ? q.BusinessTaxRate : 0;
+ taxRate = isNumeric(q.TaxRate) ? q.TaxRate : 0;
business = {
- "BusinessID": q.BusinessID,
- "BusinessName": q.BusinessName,
- "BusinessAddress": addressStr,
- "AddressLine1": addressLine1,
- "AddressCity": addressCity,
+ "BusinessID": q.ID,
+ "Name": q.Name,
+ "Address": addressStr,
+ "Line1": addressLine1,
+ "City": addressCity,
"AddressState": addressState,
"AddressZip": addressZip,
- "BusinessPhone": q.BusinessPhone,
- "BusinessHours": hoursStr,
- "BusinessHoursDetail": hoursArr,
- "StripeConnected": (len(q.BusinessStripeAccountID) > 0 && q.BusinessStripeOnboardingComplete == 1),
- "IsHiring": q.BusinessIsHiring == 1,
+ "Phone": q.Phone,
+ "Hours": hoursStr,
+ "HoursDetail": hoursArr,
+ "StripeConnected": (len(q.StripeAccountID) > 0 && q.StripeOnboardingComplete == 1),
+ "IsHiring": q.IsHiring == 1,
"TaxRate": taxRate,
"TaxRatePercent": taxRate * 100,
- "BrandColor": len(q.BusinessBrandColor) ? (left(q.BusinessBrandColor, 1) == chr(35) ? q.BusinessBrandColor : chr(35) & q.BusinessBrandColor) : ""
+ "BrandColor": len(q.BrandColor) ? (left(q.BrandColor, 1) == chr(35) ? q.BrandColor : chr(35) & q.BrandColor) : ""
};
// Add header image URL if extension exists
- if (len(q.BusinessHeaderImageExtension)) {
- business["HeaderImageURL"] = "https://biz.payfrit.com/uploads/headers/" & q.BusinessID & "." & q.BusinessHeaderImageExtension;
+ if (len(q.HeaderImageExtension)) {
+ business["HeaderImageURL"] = "https://biz.payfrit.com/uploads/headers/" & q.ID & "." & q.HeaderImageExtension;
}
response["OK"] = true;
response["BUSINESS"] = business;
- // Cache successful response
- jsonResponse = serializeJSON(response);
- appCachePut("biz_" & businessID, jsonResponse);
- logPerf();
- writeOutput(jsonResponse);
- abort;
-
} catch (any e) {
response["ERROR"] = e.message;
}
-logPerf();
writeOutput(serializeJSON(response));
diff --git a/api/businesses/getChildren.cfm b/api/businesses/getChildren.cfm
index cbf0b8a..4e11011 100644
--- a/api/businesses/getChildren.cfm
+++ b/api/businesses/getChildren.cfm
@@ -41,11 +41,11 @@ try {
q = queryExecute(
"
SELECT
- BusinessID,
- BusinessName
+ ID,
+ Name
FROM Businesses
- WHERE BusinessParentBusinessID = :parentId
- ORDER BY BusinessName
+ WHERE ParentBusinessID = :parentId
+ ORDER BY Name
",
{ parentId = { value = parentBusinessId, cfsqltype = "cf_sql_integer" } },
{ datasource = "payfrit" }
@@ -54,8 +54,8 @@ try {
rows = [];
for (i = 1; i <= q.recordCount; i++) {
arrayAppend(rows, {
- "BusinessID": q.BusinessID[i],
- "BusinessName": q.BusinessName[i]
+ "BusinessID": q.ID[i],
+ "Name": q.Name[i]
});
}
diff --git a/api/businesses/list.cfm b/api/businesses/list.cfm
index e3f263e..86d2ca3 100644
--- a/api/businesses/list.cfm
+++ b/api/businesses/list.cfm
@@ -48,17 +48,17 @@ try {
q = queryExecute(
"
SELECT
- b.BusinessID,
- b.BusinessName,
- a.AddressLat,
- a.AddressLng,
- a.AddressCity,
- a.AddressLine1
+ b.ID,
+ b.Name,
+ a.Latitude,
+ a.Longitude,
+ a.City,
+ a.Line1
FROM Businesses b
- LEFT JOIN Addresses a ON b.BusinessAddressID = a.AddressID
- WHERE (b.BusinessIsDemo = 0 OR b.BusinessIsDemo IS NULL)
- AND (b.BusinessIsPrivate = 0 OR b.BusinessIsPrivate IS NULL)
- ORDER BY b.BusinessName
+ LEFT JOIN Addresses a ON b.AddressID = a.ID
+ WHERE (b.IsDemo = 0 OR b.IsDemo IS NULL)
+ AND (b.IsPrivate = 0 OR b.IsPrivate IS NULL)
+ ORDER BY b.Name
",
[],
{ datasource = "payfrit" }
@@ -68,15 +68,15 @@ try {
rows = [];
for (i = 1; i <= q.recordCount; i++) {
row = {
- "BusinessID": q.BusinessID[i],
- "BusinessName": q.BusinessName[i],
- "AddressCity": isNull(q.AddressCity[i]) ? "" : q.AddressCity[i],
- "AddressLine1": isNull(q.AddressLine1[i]) ? "" : q.AddressLine1[i]
+ "BusinessID": q.ID[i],
+ "Name": q.Name[i],
+ "City": isNull(q.City[i]) ? "" : q.City[i],
+ "Line1": isNull(q.Line1[i]) ? "" : q.Line1[i]
};
// Calculate distance if we have both user location and business location
- bizLat = isNull(q.AddressLat[i]) ? 0 : val(q.AddressLat[i]);
- bizLng = isNull(q.AddressLng[i]) ? 0 : val(q.AddressLng[i]);
+ bizLat = isNull(q.Latitude[i]) ? 0 : val(q.Latitude[i]);
+ bizLng = isNull(q.Longitude[i]) ? 0 : val(q.Longitude[i]);
if (hasUserLocation AND bizLat != 0 AND bizLng != 0) {
row["DistanceMiles"] = haversineDistance(userLat, userLng, bizLat, bizLng);
diff --git a/api/businesses/saveBrandColor.cfm b/api/businesses/saveBrandColor.cfm
index 92503d3..12b278c 100644
--- a/api/businesses/saveBrandColor.cfm
+++ b/api/businesses/saveBrandColor.cfm
@@ -54,14 +54,13 @@ if (len(brandColor) GT 0) {
// Update the database
queryExecute("
UPDATE Businesses
- SET BusinessBrandColor = :color
+ SET BrandColor = :color
WHERE BusinessID = :bizId
", {
color: { value: brandColor, cfsqltype: "cf_sql_varchar" },
bizId: { value: bizId, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
-appCacheInvalidate("biz_" & bizId);
writeOutput(serializeJSON({
"OK": true,
"ERROR": "",
diff --git a/api/businesses/setHiring.cfm b/api/businesses/setHiring.cfm
index b204cb6..8447ed1 100644
--- a/api/businesses/setHiring.cfm
+++ b/api/businesses/setHiring.cfm
@@ -45,7 +45,7 @@ if (isHiring == -1) {
try {
queryExecute("
UPDATE Businesses
- SET BusinessIsHiring = ?
+ SET IsHiring = ?
WHERE BusinessID = ?
", [
{ value: isHiring, cfsqltype: "cf_sql_tinyint" },
diff --git a/api/businesses/update.cfm b/api/businesses/update.cfm
index cc5ef55..e60a7d7 100644
--- a/api/businesses/update.cfm
+++ b/api/businesses/update.cfm
@@ -9,9 +9,9 @@
* POST JSON:
* {
* "BusinessID": 37,
- * "BusinessName": "My Business",
- * "BusinessPhone": "(555) 123-4567",
- * "AddressLine1": "123 Main St",
+ * "Name": "My Business",
+ * "Phone": "(555) 123-4567",
+ * "Line1": "123 Main St",
* "City": "Los Angeles",
* "State": "CA",
* "Zip": "90001"
@@ -34,8 +34,8 @@ try {
}
// Update business name, phone, and tax rate
- bizName = structKeyExists(data, "BusinessName") && isSimpleValue(data.BusinessName) ? trim(data.BusinessName) : "";
- bizPhone = structKeyExists(data, "BusinessPhone") && isSimpleValue(data.BusinessPhone) ? trim(data.BusinessPhone) : "";
+ bizName = structKeyExists(data, "Name") && isSimpleValue(data.Name) ? trim(data.Name) : "";
+ bizPhone = structKeyExists(data, "Phone") && isSimpleValue(data.Phone) ? trim(data.Phone) : "";
// Handle tax rate (accept either TaxRatePercent like 8.25, or TaxRate like 0.0825)
taxRate = "";
@@ -48,7 +48,7 @@ try {
if (len(bizName)) {
if (isNumeric(taxRate)) {
queryExecute("
- UPDATE Businesses SET BusinessName = :name, BusinessPhone = :phone, BusinessTaxRate = :taxRate
+ UPDATE Businesses SET Name = :name, Phone = :phone, TaxRate = :taxRate
WHERE BusinessID = :id
", {
name: bizName,
@@ -58,7 +58,7 @@ try {
}, { datasource: "payfrit" });
} else {
queryExecute("
- UPDATE Businesses SET BusinessName = :name, BusinessPhone = :phone
+ UPDATE Businesses SET Name = :name, Phone = :phone
WHERE BusinessID = :id
", {
name: bizName,
@@ -69,7 +69,7 @@ try {
}
// Update or create address
- addressLine1 = structKeyExists(data, "AddressLine1") && isSimpleValue(data.AddressLine1) ? trim(data.AddressLine1) : "";
+ addressLine1 = structKeyExists(data, "Line1") && isSimpleValue(data.Line1) ? trim(data.Line1) : "";
city = structKeyExists(data, "City") && isSimpleValue(data.City) ? trim(data.City) : "";
state = structKeyExists(data, "State") && isSimpleValue(data.State) ? trim(data.State) : "";
zip = structKeyExists(data, "Zip") && isSimpleValue(data.Zip) ? trim(data.Zip) : "";
@@ -81,7 +81,7 @@ try {
stateID = 0;
if (len(state)) {
qState = queryExecute("
- SELECT tt_StateID FROM tt_States WHERE tt_StateAbbreviation = :abbr
+ SELECT tt_StateID FROM tt_States WHERE Abbreviation = :abbr
", { abbr: uCase(state) }, { datasource: "payfrit" });
if (qState.recordCount > 0) {
stateID = qState.tt_StateID;
@@ -90,8 +90,8 @@ try {
// Check if business has an address
qAddr = queryExecute("
- SELECT AddressID FROM Addresses
- WHERE AddressBusinessID = :bizID AND AddressUserID = 0 AND AddressIsDeleted = 0
+ SELECT ID FROM Addresses
+ WHERE BusinessID = :bizID AND UserID = 0 AND IsDeleted = 0
LIMIT 1
", { bizID: businessId }, { datasource: "payfrit" });
@@ -99,11 +99,11 @@ try {
// Update existing address
queryExecute("
UPDATE Addresses SET
- AddressLine1 = :line1,
- AddressCity = :city,
- AddressStateID = :stateID,
- AddressZIPCode = :zip
- WHERE AddressID = :addrID
+ Line1 = :line1,
+ City = :city,
+ StateID = :stateID,
+ ZIPCode = :zip
+ WHERE ID = :addrID
", {
line1: addressLine1,
city: city,
@@ -114,7 +114,7 @@ try {
} else {
// Create new address
queryExecute("
- INSERT INTO Addresses (AddressLine1, AddressCity, AddressStateID, AddressZIPCode, AddressBusinessID, AddressUserID, AddressTypeID, AddressAddedOn)
+ INSERT INTO Addresses (Line1, City, StateID, ZIPCode, BusinessID, UserID, AddressTypeID, AddedOn)
VALUES (:line1, :city, :stateID, :zip, :bizID, 0, 2, NOW())
", {
line1: addressLine1,
@@ -126,7 +126,6 @@ try {
}
response.OK = true;
- appCacheInvalidate("biz_" & businessId);
} catch (any e) {
response.ERROR = e.message;
diff --git a/api/businesses/updateHours.cfm b/api/businesses/updateHours.cfm
index b3411ce..ffb6fcc 100644
--- a/api/businesses/updateHours.cfm
+++ b/api/businesses/updateHours.cfm
@@ -38,7 +38,7 @@ try {
// Delete all existing hours for this business
queryExecute("
- DELETE FROM Hours WHERE HoursBusinessID = :bizID
+ DELETE FROM Hours WHERE BusinessID = :bizID
", { bizID: businessId }, { datasource: "payfrit" });
// Insert new hours
@@ -55,7 +55,7 @@ try {
if (len(closeTime) == 5) closeTime = closeTime & ":00";
queryExecute("
- INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime)
+ INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime)
VALUES (:bizID, :dayID, :openTime, :closeTime)
", {
bizID: businessId,
@@ -68,7 +68,6 @@ try {
response.OK = true;
response.hoursUpdated = arrayLen(hours);
- appCacheInvalidate("biz_" & businessId);
} catch (any e) {
response.ERROR = e.message;
diff --git a/api/chat/closeChat.cfm b/api/chat/closeChat.cfm
index ef56fb9..d5012d0 100644
--- a/api/chat/closeChat.cfm
+++ b/api/chat/closeChat.cfm
@@ -34,10 +34,10 @@ try {
// Mark the task as completed
queryExecute("
UPDATE Tasks
- SET TaskCompletedOn = NOW()
+ SET CompletedOn = NOW()
WHERE TaskID = :taskID
AND TaskTypeID = 2
- AND TaskCompletedOn IS NULL
+ AND CompletedOn IS NULL
", {
taskID: { value: taskID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
diff --git a/api/chat/getActiveChat.cfm b/api/chat/getActiveChat.cfm
index 23e0c9c..54d2302 100644
--- a/api/chat/getActiveChat.cfm
+++ b/api/chat/getActiveChat.cfm
@@ -45,17 +45,17 @@ try {
// Look for any active chat task at this service point
// TaskTypeID = 2 (Chat), not completed, at this service point
qChat = queryExecute("
- SELECT t.TaskID, t.TaskTitle,
- (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.TaskID) as LastMessageTime
+ SELECT t.ID, t.Title,
+ (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.ID) as LastMessageTime
FROM Tasks t
- WHERE t.TaskBusinessID = :businessID
+ WHERE t.BusinessID = :businessID
AND t.TaskTypeID = 2
- AND t.TaskCompletedOn IS NULL
- AND t.TaskSourceType = 'servicepoint'
- AND t.TaskSourceID = :servicePointID
+ AND t.CompletedOn IS NULL
+ AND t.SourceType = 'servicepoint'
+ AND t.SourceID = :servicePointID
ORDER BY
- CASE WHEN t.TaskClaimedByUserID > 0 THEN 0 ELSE 1 END,
- t.TaskAddedOn DESC
+ CASE WHEN t.ClaimedByUserID > 0 THEN 0 ELSE 1 END,
+ t.CreatedOn DESC
LIMIT 1
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" },
@@ -67,7 +67,7 @@ try {
"OK": true,
"HAS_ACTIVE_CHAT": true,
"TASK_ID": qChat.TaskID,
- "TASK_TITLE": qChat.TaskTitle
+ "TASK_TITLE": qChat.Title
});
} else {
apiAbort({
diff --git a/api/chat/getMessages.cfm b/api/chat/getMessages.cfm
index 90aea84..10f6ce4 100644
--- a/api/chat/getMessages.cfm
+++ b/api/chat/getMessages.cfm
@@ -36,17 +36,17 @@ try {
if (afterMessageID > 0) {
qMessages = queryExecute("
SELECT
- m.MessageID,
+ m.ID,
m.TaskID,
m.SenderUserID,
m.SenderType,
- m.MessageText,
+ m.MessageBody,
m.IsRead,
m.CreatedOn,
- u.UserFirstName as SenderName
+ u.FirstName as SenderName
FROM ChatMessages m
- LEFT JOIN Users u ON u.UserID = m.SenderUserID
- WHERE m.TaskID = :taskID AND m.MessageID > :afterID
+ LEFT JOIN Users u ON u.ID = m.SenderUserID
+ WHERE m.TaskID = :taskID AND m.ID > :afterID
ORDER BY m.CreatedOn ASC
", {
taskID: { value: taskID, cfsqltype: "cf_sql_integer" },
@@ -55,16 +55,16 @@ try {
} else {
qMessages = queryExecute("
SELECT
- m.MessageID,
+ m.ID,
m.TaskID,
m.SenderUserID,
m.SenderType,
- m.MessageText,
+ m.MessageBody,
m.IsRead,
m.CreatedOn,
- u.UserFirstName as SenderName
+ u.FirstName as SenderName
FROM ChatMessages m
- LEFT JOIN Users u ON u.UserID = m.SenderUserID
+ LEFT JOIN Users u ON u.ID = m.SenderUserID
WHERE m.TaskID = :taskID
ORDER BY m.CreatedOn ASC
", {
@@ -75,12 +75,12 @@ try {
messages = [];
for (msg in qMessages) {
arrayAppend(messages, {
- "MessageID": msg.MessageID,
+ "MessageID": msg.ID,
"TaskID": msg.TaskID,
"SenderUserID": msg.SenderUserID,
"SenderType": msg.SenderType,
"SenderName": len(trim(msg.SenderName)) ? msg.SenderName : (msg.SenderType == "customer" ? "Customer" : "Staff"),
- "Text": msg.MessageText,
+ "Text": msg.MessageBody,
"IsRead": msg.IsRead == 1,
"CreatedOn": dateFormat(msg.CreatedOn, "yyyy-mm-dd") & "T" & timeFormat(msg.CreatedOn, "HH:mm:ss")
});
@@ -88,11 +88,11 @@ try {
// Check if chat/task is closed (completed)
qTask = queryExecute("
- SELECT TaskCompletedOn FROM Tasks WHERE TaskID = :taskID
+ SELECT CompletedOn FROM Tasks WHERE ID = :taskID
", { taskID: { value: taskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
chatClosed = false;
- if (qTask.recordCount > 0 && len(trim(qTask.TaskCompletedOn)) > 0) {
+ if (qTask.recordCount > 0 && len(trim(qTask.CompletedOn)) > 0) {
chatClosed = true;
}
diff --git a/api/chat/sendMessage.cfm b/api/chat/sendMessage.cfm
index db3acca..c4cf327 100644
--- a/api/chat/sendMessage.cfm
+++ b/api/chat/sendMessage.cfm
@@ -54,7 +54,7 @@ try {
// Verify task exists and is still open
taskQuery = queryExecute("
- SELECT TaskID, TaskClaimedByUserID, TaskCompletedOn FROM Tasks WHERE TaskID = :taskID
+ SELECT ID, ClaimedByUserID, CompletedOn FROM Tasks WHERE ID = :taskID
", { taskID: { value: taskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
if (taskQuery.recordCount == 0) {
@@ -62,13 +62,13 @@ try {
}
// Check if chat has been closed
- if (len(trim(taskQuery.TaskCompletedOn)) > 0) {
+ if (len(trim(taskQuery.CompletedOn)) > 0) {
apiAbort({ "OK": false, "ERROR": "chat_closed", "MESSAGE": "This chat has ended" });
}
// Insert message
queryExecute("
- INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageText)
+ INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageBody)
VALUES (:taskID, :userID, :senderType, :message)
", {
taskID: { value: taskID, cfsqltype: "cf_sql_integer" },
diff --git a/api/config/environment.cfm b/api/config/environment.cfm
index 8451937..c9c325d 100644
--- a/api/config/environment.cfm
+++ b/api/config/environment.cfm
@@ -116,142 +116,6 @@ function apiError(message, detail = "", statusCode = 500) {
return response;
}
-// ============================================
-// PERFORMANCE PROFILING
-// ============================================
-application.perfEnabled = true; // Toggle profiling on/off
-
-// Initialize perf buffer (once per application start)
-if (!structKeyExists(application, "perfBuffer")) {
- application.perfBuffer = [];
-}
-
-/**
- * Drop-in replacement for queryExecute that tracks query count and time.
- * Usage: queryTimed("SELECT ...", [...], { datasource: "payfrit" })
- */
-function queryTimed(required string sql, any params = [], struct options = {}) {
- var t = getTickCount();
- var result = queryExecute(arguments.sql, arguments.params, arguments.options);
- var elapsed = getTickCount() - t;
- request._perf_queryCount++;
- request._perf_queryTimeMs += elapsed;
- return result;
-}
-
-/**
- * Flush the in-memory perf buffer to the api_perf_log MySQL table.
- * Called automatically when buffer reaches 100 entries.
- */
-function flushPerfBuffer() {
- var batch = [];
- lock name="payfrit_perfBuffer" timeout="2" type="exclusive" {
- batch = duplicate(application.perfBuffer);
- application.perfBuffer = [];
- }
- if (arrayLen(batch) == 0) return;
-
- try {
- var sql = "INSERT INTO api_perf_log (Endpoint, TotalMs, DbMs, AppMs, QueryCount, ResponseBytes, BusinessID, UserID, LoggedAt) VALUES ";
- var rows = [];
- for (var m in batch) {
- arrayAppend(rows,
- "('" & replace(m.endpoint, "'", "''", "all") & "',"
- & m.totalMs & "," & m.dbMs & "," & m.appMs & ","
- & m.queryCount & "," & m.responseBytes & ","
- & m.businessId & "," & m.userId & ",'"
- & m.loggedAt & "')"
- );
- }
- sql &= arrayToList(rows, ",");
- queryExecute(sql, {}, { datasource: "payfrit" });
-
- // Cleanup: delete rows older than 30 days (run occasionally)
- if (randRange(1, 100) == 1) {
- queryExecute(
- "DELETE FROM api_perf_log WHERE LoggedAt < DATE_SUB(NOW(), INTERVAL 30 DAY)",
- {}, { datasource: "payfrit" }
- );
- }
- } catch (any e) {
- // Silent fail - never break the app for profiling
- }
-}
-
-/**
- * Log performance metrics for the current request.
- * Call this at the end of any instrumented endpoint, before the final writeOutput/abort.
- */
-function logPerf(numeric responseBytes = 0) {
- if (!structKeyExists(application, "perfEnabled") || !application.perfEnabled) return;
-
- var totalMs = getTickCount() - request._perf_start;
- var dbMs = request._perf_queryTimeMs;
-
- var metric = {
- endpoint: structKeyExists(request, "_api_path") ? request._api_path : "unknown",
- totalMs: totalMs,
- dbMs: dbMs,
- appMs: totalMs - dbMs,
- queryCount: request._perf_queryCount,
- responseBytes: arguments.responseBytes,
- businessId: structKeyExists(request, "BusinessID") ? val(request.BusinessID) : 0,
- userId: structKeyExists(request, "UserID") ? val(request.UserID) : 0,
- loggedAt: dateTimeFormat(now(), "yyyy-mm-dd HH:nn:ss")
- };
-
- lock name="payfrit_perfBuffer" timeout="1" type="exclusive" {
- arrayAppend(application.perfBuffer, metric);
- if (arrayLen(application.perfBuffer) >= 100) {
- thread name="perfFlush_#createUUID()#" {
- flushPerfBuffer();
- }
- }
- }
-}
-
-// ============================================
-// APPLICATION-SCOPE CACHE
-// ============================================
-if (!structKeyExists(application, "cache")) {
- application.cache = {};
-}
-
-/**
- * Get a cached value. Returns null if not found or expired.
- * Usage: cached = cacheGet("menu_123", 120);
- * if (!isNull(cached)) { use it } else { query and cachePut }
- */
-function appCacheGet(required string key, numeric ttlSeconds = 300) {
- if (structKeyExists(application.cache, arguments.key)) {
- var entry = application.cache[arguments.key];
- if (dateDiff("s", entry.cachedAt, now()) < arguments.ttlSeconds) {
- return entry.data;
- }
- structDelete(application.cache, arguments.key);
- }
- return javaCast("null", "");
-}
-
-/**
- * Store a value in cache.
- */
-function appCachePut(required string key, required any data) {
- application.cache[arguments.key] = { data: arguments.data, cachedAt: now() };
-}
-
-/**
- * Invalidate all cache keys starting with the given prefix.
- */
-function appCacheInvalidate(required string keyPrefix) {
- var keys = structKeyArray(application.cache);
- for (var k in keys) {
- if (findNoCase(arguments.keyPrefix, k) == 1) {
- structDelete(application.cache, k);
- }
- }
-}
-
// Store in application scope
application.isDevEnvironment = isDevEnvironment;
application.isDev = isDev;
diff --git a/api/config/stripe.cfm b/api/config/stripe.cfm
index 87dbd09..057daf1 100644
--- a/api/config/stripe.cfm
+++ b/api/config/stripe.cfm
@@ -41,4 +41,8 @@ application.payfritCustomerFeePercent = 0.05; // 5% customer pays to Payfrit
application.payfritBusinessFeePercent = 0.05; // 5% business pays to Payfrit
application.cardFeePercent = 0.029; // 2.9% Stripe fee
application.cardFeeFixed = 0.30; // $0.30 Stripe fixed fee
+
+// Activation (Cost Recovery) Configuration
+application.activationCapCentsDefault = 2500; // $25.00
+application.activationWithholdIncrementCents = 100; // $1.00 per payout
diff --git a/api/debug/checkTask.cfm b/api/debug/checkTask.cfm
index 43afad8..bea65ab 100644
--- a/api/debug/checkTask.cfm
+++ b/api/debug/checkTask.cfm
@@ -16,11 +16,11 @@
@@ -30,18 +30,18 @@
diff --git a/api/debug/checkToken.cfm b/api/debug/checkToken.cfm
index 8531314..ca2591a 100644
--- a/api/debug/checkToken.cfm
+++ b/api/debug/checkToken.cfm
@@ -28,18 +28,18 @@ result = {
if (len(userToken)) {
try {
qTok = queryExecute(
- "SELECT UserID, Token FROM UserTokens WHERE Token = ? LIMIT 1",
+ "SELECT ID, Token FROM UserTokens WHERE Token = ? LIMIT 1",
[ { value = userToken, cfsqltype = "cf_sql_varchar" } ],
{ datasource = "payfrit" }
);
result.dbLookupRecords = qTok.recordCount;
if (qTok.recordCount > 0) {
- result.foundUserId = qTok.UserID;
+ result.foundUserId = qTok.ID;
}
// Also check with LIKE to see if partial match exists
qPartial = queryExecute(
- "SELECT UserID, Token FROM UserTokens WHERE Token LIKE ? LIMIT 5",
+ "SELECT ID, Token FROM UserTokens WHERE Token LIKE ? LIMIT 5",
[ { value = left(userToken, 8) & "%", cfsqltype = "cf_sql_varchar" } ],
{ datasource = "payfrit" }
);
@@ -53,14 +53,14 @@ if (len(userToken)) {
// Also list recent tokens
try {
qRecent = queryExecute(
- "SELECT UserID, LEFT(Token, 8) as TokenPrefix, LENGTH(Token) as TokenLen FROM UserTokens ORDER BY UserID DESC LIMIT 5",
+ "SELECT ID, LEFT(Token, 8) as TokenPrefix, LENGTH(Token) as TokenLen FROM UserTokens ORDER BY ID DESC LIMIT 5",
[],
{ datasource = "payfrit" }
);
result.recentTokens = [];
for (row in qRecent) {
arrayAppend(result.recentTokens, {
- "userId": row.UserID,
+ "userId": row.ID,
"prefix": row.TokenPrefix,
"length": row.TokenLen
});
diff --git a/api/dev/seedData.cfm b/api/dev/seedData.cfm
index df1c7e7..47125d7 100644
--- a/api/dev/seedData.cfm
+++ b/api/dev/seedData.cfm
@@ -44,17 +44,17 @@ function createTestUser(phone, firstName, lastName, isVerified = true) {
queryExecute("
INSERT INTO Users (
- UserContactNumber,
- UserUUID,
- UserFirstName,
- UserLastName,
- UserIsContactVerified,
- UserIsEmailVerified,
- UserIsActive,
- UserAddedOn,
- UserPassword,
- UserPromoCode,
- UserMobileVerifyCode
+ ContactNumber,
+ UUID,
+ FirstName,
+ LastName,
+ IsContactVerified,
+ IsEmailVerified,
+ IsActive,
+ AddedOn,
+ Password,
+ PromoCode,
+ MobileVerifyCode
) VALUES (
:phone,
:uuid,
@@ -127,7 +127,7 @@ function resetTestData() {
// Delete test users (by phone prefix 555)
queryExecute("
DELETE FROM Users
- WHERE UserContactNumber LIKE '555%'
+ WHERE ContactNumber LIKE '555%'
", {}, { datasource: "payfrit" });
return seedTestData();
@@ -135,20 +135,20 @@ function resetTestData() {
function getTestDataInfo() {
var qUsers = queryExecute("
- SELECT UserID, UserContactNumber, UserFirstName, UserLastName,
- UserIsContactVerified, UserUUID
+ SELECT ID, ContactNumber, FirstName, LastName,
+ IsContactVerified, UUID
FROM Users
- WHERE UserContactNumber LIKE '555%'
- ORDER BY UserContactNumber
+ WHERE ContactNumber LIKE '555%'
+ ORDER BY ContactNumber
", {}, { datasource: "payfrit" });
var users = [];
for (var row in qUsers) {
arrayAppend(users, {
- "phone": row.UserContactNumber,
- "name": trim(row.UserFirstName & " " & row.UserLastName),
- "verified": row.UserIsContactVerified == 1,
- "uuid": row.UserUUID
+ "phone": row.ContactNumber,
+ "name": trim(row.FirstName & " " & row.LastName),
+ "verified": row.IsContactVerified == 1,
+ "uuid": row.UUID
});
}
diff --git a/api/dev/timeTravel.cfm b/api/dev/timeTravel.cfm
index 12c728a..b41652c 100644
--- a/api/dev/timeTravel.cfm
+++ b/api/dev/timeTravel.cfm
@@ -79,7 +79,7 @@ try {
queryExecute("
UPDATE Users
- SET UserAddedOn = DATE_SUB(NOW(), INTERVAL :days DAY)
+ SET AddedOn = DATE_SUB(NOW(), INTERVAL :days DAY)
WHERE UserID = :userId
", {
userId: { value: data.userId, cfsqltype: "cf_sql_integer" },
@@ -95,7 +95,7 @@ try {
case "clearotps":
// Clear all OTPs (force re-request)
queryExecute("
- UPDATE Users SET UserMobileVerifyCode = ''
+ UPDATE Users SET MobileVerifyCode = ''
", {}, { datasource: "payfrit" });
writeOutput(serializeJSON({
@@ -112,12 +112,12 @@ try {
queryExecute("
UPDATE Users
- SET UserIsContactVerified = 0,
- UserIsActive = 0,
- UserFirstName = NULL,
- UserLastName = NULL,
- UserMobileVerifyCode = '123456'
- WHERE UserContactNumber = :phone
+ SET IsContactVerified = 0,
+ IsActive = 0,
+ FirstName = NULL,
+ LastName = NULL,
+ MobileVerifyCode = '123456'
+ WHERE ContactNumber = :phone
", {
phone: { value: data.phone, cfsqltype: "cf_sql_varchar" }
}, { datasource: "payfrit" });
diff --git a/api/import/crimson_menu.cfm b/api/import/crimson_menu.cfm
index 8812b63..ef08c60 100644
--- a/api/import/crimson_menu.cfm
+++ b/api/import/crimson_menu.cfm
@@ -14,7 +14,7 @@ try {
// Check if business already exists by name
qCheck = queryExecute("
- SELECT BusinessID FROM Businesses WHERE BusinessName = :name
+ SELECT ID FROM Businesses WHERE Name = :name
", { name: "Crimson Mediterranean Cookhouse" }, { datasource: "payfrit" });
if (qCheck.recordCount > 0) {
@@ -22,7 +22,7 @@ try {
response.steps.append("Business already exists with ID: " & BusinessID);
} else {
queryExecute("
- INSERT INTO Businesses (BusinessName, BusinessOwnerUserID)
+ INSERT INTO Businesses (Name, BusinessOwnerUserID)
VALUES (:name, :ownerID)
", {
name: "Crimson Mediterranean Cookhouse",
@@ -54,15 +54,15 @@ try {
for (cat in categories) {
// Check if exists
qCat = queryExecute("
- SELECT CategoryID FROM Categories
- WHERE CategoryBusinessID = :bizID AND CategoryName = :name
+ SELECT ID FROM Categories
+ WHERE BusinessID = :bizID AND Name = :name
", { bizID: BusinessID, name: cat.name }, { datasource: "payfrit" });
if (qCat.recordCount > 0) {
categoryMap[cat.id] = qCat.CategoryID;
} else {
queryExecute("
- INSERT INTO Categories (CategoryBusinessID, CategoryName, CategorySortOrder)
+ INSERT INTO Categories (BusinessID, Name, SortOrder)
VALUES (:bizID, :name, :sortOrder)
", {
bizID: BusinessID,
@@ -87,8 +87,8 @@ try {
function createModifierGroup(categoryID, parentItemID, groupName, groupID, options, required, maxSelect) {
// Check if group exists
var qMod = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = :parentID
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = :parentID
", { catID: categoryID, name: groupName, parentID: parentItemID }, { datasource: "payfrit" });
var groupItemID = 0;
@@ -96,8 +96,8 @@ try {
groupItemID = qMod.ItemID;
} else {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemParentItemID, ItemPrice, ItemIsActive,
- ItemRequiresChildSelection, ItemMaxNumSelectionReq, ItemIsCollapsible, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, ParentItemID, Price, IsActive,
+ RequiresChildSelection, MaxNumSelectionReq, IsCollapsible, SortOrder)
VALUES (:catID, :name, :parentID, 0, 1, :required, :maxSelect, 1, :sortOrder)
", {
catID: categoryID,
@@ -116,15 +116,15 @@ try {
var optionOrder = 1;
for (var opt in options) {
var qOpt = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = :parentID
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = :parentID
", { catID: categoryID, name: opt.name, parentID: groupItemID }, { datasource: "payfrit" });
if (qOpt.recordCount == 0) {
var isDefault = (optionOrder == 1 && required) ? 1 : 0;
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemParentItemID, ItemPrice, ItemIsActive,
- ItemIsCheckedByDefault, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, ParentItemID, Price, IsActive,
+ IsCheckedByDefault, SortOrder)
VALUES (:catID, :name, :parentID, :price, 1, :isDefault, :sortOrder)
", {
catID: categoryID,
@@ -159,14 +159,14 @@ try {
itemOrder = 1;
for (item in grillItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: grillCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemRequiresChildSelection, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, RequiresChildSelection, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :reqChild, :sortOrder)
", {
catID: grillCatID,
@@ -199,14 +199,14 @@ try {
itemOrder = 1;
for (item in wrapItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: wrapsCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: wrapsCatID,
@@ -235,14 +235,14 @@ try {
itemOrder = 1;
for (item in saladItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: saladsCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: saladsCatID,
@@ -277,14 +277,14 @@ try {
itemOrder = 1;
for (item in sideItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: sidesCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: sidesCatID,
@@ -318,14 +318,14 @@ try {
itemOrder = 1;
for (item in hotCoffeeItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: hotCoffeeCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: hotCoffeeCatID,
@@ -356,14 +356,14 @@ try {
itemOrder = 1;
for (item in icedCoffeeItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: icedCoffeeCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: icedCoffeeCatID,
@@ -392,14 +392,14 @@ try {
itemOrder = 1;
for (item in hotTeaItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: hotTeaCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: hotTeaCatID,
@@ -429,14 +429,14 @@ try {
itemOrder = 1;
for (item in icedTeaItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: icedTeaCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: icedTeaCatID,
@@ -467,14 +467,14 @@ try {
itemOrder = 1;
for (item in bevItems) {
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemCategoryID = :catID AND ItemName = :name AND ItemParentItemID = 0
+ SELECT ID FROM Items
+ WHERE CategoryID = :catID AND Name = :name AND ParentItemID = 0
", { catID: bevCatID, name: item.name }, { datasource: "payfrit" });
if (qItem.recordCount == 0) {
queryExecute("
- INSERT INTO Items (ItemCategoryID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder)
+ INSERT INTO Items (CategoryID, Name, Description, ParentItemID, Price,
+ IsActive, SortOrder)
VALUES (:catID, :name, :desc, 0, :price, 1, :sortOrder)
", {
catID: bevCatID,
@@ -490,8 +490,8 @@ try {
// Count total items
qCount = queryExecute("
SELECT COUNT(*) as cnt FROM Items i
- INNER JOIN Categories c ON c.CategoryID = i.ItemCategoryID
- WHERE c.CategoryBusinessID = :bizID
+ INNER JOIN Categories c ON c.ID = i.CategoryID
+ WHERE c.BusinessID = :bizID
", { bizID: BusinessID }, { datasource: "payfrit" });
response.OK = true;
diff --git a/api/menu/clearAllData.cfm b/api/menu/clearAllData.cfm
index 22649f1..654593e 100644
--- a/api/menu/clearAllData.cfm
+++ b/api/menu/clearAllData.cfm
@@ -22,10 +22,10 @@ try {
// Get counts before deletion
qItemCount = queryExecute("SELECT COUNT(*) as cnt FROM Items", {}, { datasource: "payfrit" });
qCatCount = queryExecute("SELECT COUNT(*) as cnt FROM Categories", {}, { datasource: "payfrit" });
- qLinkCount = queryExecute("SELECT COUNT(*) as cnt FROM ItemTemplateLinks", {}, { datasource: "payfrit" });
+ qLinkCount = queryExecute("SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" });
// Delete in correct order (foreign key constraints)
- queryExecute("DELETE FROM ItemTemplateLinks", {}, { datasource: "payfrit" });
+ queryExecute("DELETE FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" });
queryExecute("DELETE FROM Items", {}, { datasource: "payfrit" });
queryExecute("DELETE FROM Categories", {}, { datasource: "payfrit" });
diff --git a/api/menu/clearBusinessData.cfm b/api/menu/clearBusinessData.cfm
index c06ac03..8e1bc98 100644
--- a/api/menu/clearBusinessData.cfm
+++ b/api/menu/clearBusinessData.cfm
@@ -24,30 +24,30 @@ try {
}
// Get counts before deletion
- qItemCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE ItemBusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
- qCatCount = queryExecute("SELECT COUNT(*) as cnt FROM Categories WHERE CategoryBusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
+ qItemCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
+ qCatCount = queryExecute("SELECT COUNT(*) as cnt FROM Categories WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
// Get item IDs for this business to delete template links
- qItemIds = queryExecute("SELECT ItemID FROM Items WHERE ItemBusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
+ qItemIds = queryExecute("SELECT ID FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
itemIds = [];
for (row in qItemIds) {
- arrayAppend(itemIds, row.ItemID);
+ arrayAppend(itemIds, row.ID);
}
deletedLinks = 0;
if (arrayLen(itemIds) > 0) {
// Delete template links for these items
- queryExecute("DELETE FROM ItemTemplateLinks WHERE ItemID IN (:ids) OR TemplateItemID IN (:ids)",
+ queryExecute("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID IN (:ids) OR TemplateItemID IN (:ids)",
{ ids: { value: arrayToList(itemIds), cfsqltype: "cf_sql_varchar", list: true } },
{ datasource: "payfrit" });
deletedLinks = arrayLen(itemIds);
}
// Delete all items for this business
- queryExecute("DELETE FROM Items WHERE ItemBusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Items WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
// Delete all categories for this business
- queryExecute("DELETE FROM Categories WHERE CategoryBusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
+ queryExecute("DELETE FROM Categories WHERE BusinessID = :bid", { bid: businessID }, { datasource: "payfrit" });
response = {
"OK": true,
diff --git a/api/menu/debug.cfm b/api/menu/debug.cfm
index 0d3b10c..0eb535a 100644
--- a/api/menu/debug.cfm
+++ b/api/menu/debug.cfm
@@ -8,58 +8,58 @@ response = {};
try {
// Get all businesses with items
qBusinesses = queryExecute("
- SELECT DISTINCT i.ItemBusinessID, COUNT(*) as ItemCount
+ SELECT DISTINCT i.BusinessID, COUNT(*) as ItemCount
FROM Items i
- WHERE i.ItemBusinessID > 0
- GROUP BY i.ItemBusinessID
+ WHERE i.BusinessID > 0
+ GROUP BY i.BusinessID
", {}, { datasource: "payfrit" });
response["businesses_with_items"] = [];
for (b in qBusinesses) {
arrayAppend(response["businesses_with_items"], {
- "businessID": b.ItemBusinessID,
+ "businessID": b.ID,
"itemCount": b.ItemCount
});
}
// Get categories
qCategories = queryExecute("
- SELECT CategoryBusinessID, COUNT(*) as cnt
+ SELECT ID, COUNT(*) as cnt
FROM Categories
- GROUP BY CategoryBusinessID
+ GROUP BY BusinessID
", {}, { datasource: "payfrit" });
response["categories_by_business"] = [];
for (c in qCategories) {
arrayAppend(response["categories_by_business"], {
- "businessID": c.CategoryBusinessID,
+ "businessID": c.BusinessID,
"count": c.cnt
});
}
// Get sample items
qItems = queryExecute("
- SELECT ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID, ItemName, ItemIsActive
+ SELECT ID, BusinessID, CategoryID, ParentItemID, Name, IsActive
FROM Items
- WHERE ItemIsActive = 1
+ WHERE IsActive = 1
LIMIT 20
", {}, { datasource: "payfrit" });
response["sample_items"] = [];
for (i in qItems) {
arrayAppend(response["sample_items"], {
- "id": i.ItemID,
- "businessID": i.ItemBusinessID,
- "categoryID": i.ItemCategoryID,
- "parentID": i.ItemParentItemID,
- "name": i.ItemName,
- "active": i.ItemIsActive
+ "id": i.ID,
+ "businessID": i.BusinessID,
+ "categoryID": i.CategoryID,
+ "parentID": i.ParentItemID,
+ "name": i.Name,
+ "active": i.IsActive
});
}
// Get template links
qLinks = queryExecute("
- SELECT COUNT(*) as cnt FROM ItemTemplateLinks
+ SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID
", {}, { datasource: "payfrit" });
response["template_link_count"] = qLinks.cnt;
diff --git a/api/menu/getForBuilder.cfm b/api/menu/getForBuilder.cfm
index 1d0271c..83e84ec 100644
--- a/api/menu/getForBuilder.cfm
+++ b/api/menu/getForBuilder.cfm
@@ -11,34 +11,24 @@
response = { "OK": false };
-// Pre-index query rows by parentId for O(1) lookup instead of O(n) scan per level
-function buildParentIndex(allOptions) {
- var byParent = {};
- for (var i = 1; i <= allOptions.recordCount; i++) {
- var pid = allOptions.ParentItemID[i];
- if (!structKeyExists(byParent, pid)) byParent[pid] = [];
- arrayAppend(byParent[pid], i);
- }
- return byParent;
-}
-
-// Recursive function to build nested options (uses pre-built index)
-function buildOptionsTree(allOptions, parentId, byParent) {
- if (!structKeyExists(byParent, parentId)) return [];
+// Recursive function to build nested options
+function buildOptionsTree(allOptions, parentId) {
var result = [];
- for (var idx in byParent[parentId]) {
- var children = buildOptionsTree(allOptions, allOptions.ItemID[idx], byParent);
- arrayAppend(result, {
- "id": "opt_" & allOptions.ItemID[idx],
- "dbId": allOptions.ItemID[idx],
- "name": allOptions.ItemName[idx],
- "price": allOptions.ItemPrice[idx],
- "isDefault": allOptions.IsDefault[idx] == 1 ? true : false,
- "sortOrder": allOptions.ItemSortOrder[idx],
- "requiresSelection": isNull(allOptions.RequiresSelection[idx]) ? false : (allOptions.RequiresSelection[idx] == 1),
- "maxSelections": isNull(allOptions.MaxSelections[idx]) ? 0 : allOptions.MaxSelections[idx],
- "options": children
- });
+ for (var i = 1; i <= allOptions.recordCount; i++) {
+ if (allOptions.ParentItemID[i] == parentId) {
+ var children = buildOptionsTree(allOptions, allOptions.ItemID[i]);
+ arrayAppend(result, {
+ "id": "opt_" & allOptions.ItemID[i],
+ "dbId": allOptions.ItemID[i],
+ "name": allOptions.Name[i],
+ "price": allOptions.Price[i],
+ "isDefault": allOptions.IsDefault[i] == 1 ? true : false,
+ "sortOrder": allOptions.SortOrder[i],
+ "requiresSelection": isNull(allOptions.RequiresSelection[i]) ? false : (allOptions.RequiresSelection[i] == 1),
+ "maxSelections": isNull(allOptions.MaxSelections[i]) ? 0 : allOptions.MaxSelections[i],
+ "options": children
+ });
+ }
}
if (arrayLen(result) > 1) {
arraySort(result, function(a, b) {
@@ -73,23 +63,23 @@ try {
// Get all menus for this business
allMenus = [];
try {
- qMenus = queryTimed("
- SELECT MenuID, MenuName, MenuDescription, MenuDaysActive,
- MenuStartTime, MenuEndTime, MenuSortOrder
+ qMenus = queryExecute("
+ SELECT ID, Name, Description, DaysActive,
+ StartTime, EndTime, SortOrder
FROM Menus
- WHERE MenuBusinessID = :businessID AND MenuIsActive = 1
- ORDER BY MenuSortOrder, MenuName
+ WHERE BusinessID = :businessID AND IsActive = 1
+ ORDER BY SortOrder, Name
", { businessID: businessID }, { datasource: "payfrit" });
for (m = 1; m <= qMenus.recordCount; m++) {
arrayAppend(allMenus, {
- "MenuID": qMenus.MenuID[m],
- "MenuName": qMenus.MenuName[m],
- "MenuDescription": isNull(qMenus.MenuDescription[m]) ? "" : qMenus.MenuDescription[m],
- "MenuDaysActive": qMenus.MenuDaysActive[m],
- "MenuStartTime": isNull(qMenus.MenuStartTime[m]) ? "" : timeFormat(qMenus.MenuStartTime[m], "HH:mm"),
- "MenuEndTime": isNull(qMenus.MenuEndTime[m]) ? "" : timeFormat(qMenus.MenuEndTime[m], "HH:mm"),
- "MenuSortOrder": qMenus.MenuSortOrder[m]
+ "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"),
+ "SortOrder": qMenus.SortOrder[m]
});
}
@@ -102,21 +92,21 @@ try {
for (m = 1; m <= qMenus.recordCount; m++) {
// Check if menu is active today (days bitmask)
- menuDays = qMenus.MenuDaysActive[m];
+ menuDays = qMenus.DaysActive[m];
if (bitAnd(menuDays, dayBit) == 0) continue;
// Check time range
- hasStart = !isNull(qMenus.MenuStartTime[m]);
- hasEnd = !isNull(qMenus.MenuEndTime[m]);
+ hasStart = !isNull(qMenus.StartTime[m]);
+ hasEnd = !isNull(qMenus.EndTime[m]);
if (hasStart && hasEnd) {
- startT = timeFormat(qMenus.MenuStartTime[m], "HH:mm");
- endT = timeFormat(qMenus.MenuEndTime[m], "HH:mm");
+ startT = timeFormat(qMenus.StartTime[m], "HH:mm");
+ endT = timeFormat(qMenus.EndTime[m], "HH:mm");
if (now >= startT && now <= endT) {
- arrayAppend(activeMenuIds, qMenus.MenuID[m]);
+ arrayAppend(activeMenuIds, qMenus.ID[m]);
}
} else {
// No time restriction = always active
- arrayAppend(activeMenuIds, qMenus.MenuID[m]);
+ arrayAppend(activeMenuIds, qMenus.ID[m]);
}
}
@@ -133,8 +123,8 @@ try {
// Check if Categories table has data for this business
hasCategoriesData = false;
try {
- qCatCheck = queryTimed("
- SELECT 1 FROM Categories WHERE CategoryBusinessID = :businessID LIMIT 1
+ qCatCheck = queryExecute("
+ SELECT 1 FROM Categories WHERE BusinessID = :businessID LIMIT 1
", { businessID: businessID }, { datasource: "payfrit" });
hasCategoriesData = (qCatCheck.recordCount > 0);
} catch (any e) {
@@ -147,149 +137,149 @@ try {
menuFilter = "";
menuParams = { businessID: businessID };
if (menuID > 0) {
- menuFilter = " AND CategoryMenuID = :menuID";
+ menuFilter = " AND MenuID = :menuID";
menuParams["menuID"] = menuID;
}
- qCategories = queryTimed("
+ qCategories = queryExecute("
SELECT
- CategoryID,
- CategoryName,
- CategorySortOrder as ItemSortOrder,
- CategoryMenuID
+ ID,
+ Name,
+ SortOrder as SortOrder,
+ MenuID
FROM Categories
- WHERE CategoryBusinessID = :businessID #menuFilter#
- ORDER BY CategorySortOrder, CategoryName
+ WHERE BusinessID = :businessID #menuFilter#
+ ORDER BY SortOrder, Name
", menuParams, { datasource: "payfrit" });
// Get menu items - items that belong to categories (not modifiers)
- qItems = queryTimed("
+ qItems = queryExecute("
SELECT
- i.ItemID,
- i.ItemCategoryID as CategoryItemID,
- i.ItemName,
- i.ItemDescription,
- i.ItemPrice,
- i.ItemSortOrder,
- i.ItemIsActive
+ i.ID,
+ i.CategoryID as CategoryItemID,
+ i.Name,
+ i.Description,
+ i.Price,
+ i.SortOrder,
+ i.IsActive
FROM Items i
- WHERE i.ItemBusinessID = :businessID
- AND i.ItemIsActive = 1
- AND i.ItemCategoryID > 0
- ORDER BY i.ItemSortOrder, i.ItemName
+ WHERE i.BusinessID = :businessID
+ AND i.IsActive = 1
+ AND i.CategoryID > 0
+ ORDER BY i.SortOrder, i.Name
", { businessID: businessID }, { datasource: "payfrit" });
// Get direct modifiers (items with ParentItemID pointing to menu items, not categories)
- qDirectModifiers = queryTimed("
+ qDirectModifiers = queryExecute("
SELECT
m.ItemID,
- m.ItemParentItemID as ParentItemID,
- m.ItemName,
- m.ItemPrice,
- m.ItemIsCheckedByDefault as IsDefault,
- m.ItemSortOrder,
- m.ItemRequiresChildSelection as RequiresSelection,
- m.ItemMaxNumSelectionReq as MaxSelections
+ m.ParentItemID as ParentItemID,
+ m.Name,
+ m.Price,
+ m.IsCheckedByDefault as IsDefault,
+ m.SortOrder,
+ m.RequiresChildSelection as RequiresSelection,
+ m.MaxNumSelectionReq as MaxSelections
FROM Items m
- WHERE m.ItemBusinessID = :businessID
- AND m.ItemIsActive = 1
- AND m.ItemParentItemID > 0
- AND (m.ItemCategoryID = 0 OR m.ItemCategoryID IS NULL)
- ORDER BY m.ItemSortOrder, m.ItemName
+ WHERE m.BusinessID = :businessID
+ AND m.IsActive = 1
+ AND m.ParentItemID > 0
+ AND (m.CategoryID = 0 OR m.CategoryID IS NULL)
+ ORDER BY m.SortOrder, m.Name
", { businessID: businessID }, { datasource: "payfrit" });
} else {
// NEW UNIFIED SCHEMA: Categories are Items at ParentID=0 with children
- qCategories = queryTimed("
+ qCategories = queryExecute("
SELECT DISTINCT
p.ItemID as CategoryID,
- p.ItemName as CategoryName,
- p.ItemSortOrder
+ p.Name as Name,
+ p.SortOrder
FROM Items p
- INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
- WHERE p.ItemBusinessID = :businessID
- AND p.ItemParentItemID = 0
- AND p.ItemIsActive = 1
+ INNER JOIN Items c ON c.ParentItemID = p.ItemID
+ WHERE p.BusinessID = :businessID
+ AND p.ParentItemID = 0
+ AND p.IsActive = 1
AND NOT EXISTS (
- SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
+ SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ItemID
)
- ORDER BY p.ItemSortOrder, p.ItemName
+ ORDER BY p.SortOrder, p.Name
", { businessID: businessID }, { datasource: "payfrit" });
- qItems = queryTimed("
+ qItems = queryExecute("
SELECT
- i.ItemID,
- i.ItemParentItemID as CategoryItemID,
- i.ItemName,
- i.ItemDescription,
- i.ItemPrice,
- i.ItemSortOrder,
- i.ItemIsActive
+ i.ID,
+ i.ParentItemID as CategoryItemID,
+ i.Name,
+ i.Description,
+ i.Price,
+ i.SortOrder,
+ i.IsActive
FROM Items i
- INNER JOIN Items cat ON cat.ItemID = i.ItemParentItemID
- WHERE i.ItemBusinessID = :businessID
- AND i.ItemIsActive = 1
- AND cat.ItemParentItemID = 0
+ INNER JOIN Items cat ON cat.ID = i.ParentItemID
+ WHERE i.BusinessID = :businessID
+ AND i.IsActive = 1
+ AND cat.ParentItemID = 0
AND NOT EXISTS (
- SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = cat.ItemID
+ SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = cat.ID
)
- ORDER BY i.ItemSortOrder, i.ItemName
+ ORDER BY i.SortOrder, i.Name
", { businessID: businessID }, { datasource: "payfrit" });
- qDirectModifiers = queryTimed("
+ qDirectModifiers = queryExecute("
SELECT
m.ItemID,
- m.ItemParentItemID as ParentItemID,
- m.ItemName,
- m.ItemPrice,
- m.ItemIsCheckedByDefault as IsDefault,
- m.ItemSortOrder,
- m.ItemRequiresChildSelection as RequiresSelection,
- m.ItemMaxNumSelectionReq as MaxSelections
+ m.ParentItemID as ParentItemID,
+ m.Name,
+ m.Price,
+ m.IsCheckedByDefault as IsDefault,
+ m.SortOrder,
+ m.RequiresChildSelection as RequiresSelection,
+ m.MaxNumSelectionReq as MaxSelections
FROM Items m
- WHERE m.ItemBusinessID = :businessID
- AND m.ItemIsActive = 1
- AND m.ItemParentItemID > 0
- ORDER BY m.ItemSortOrder, m.ItemName
+ WHERE m.BusinessID = :businessID
+ AND m.IsActive = 1
+ AND m.ParentItemID > 0
+ ORDER BY m.SortOrder, m.Name
", { businessID: businessID }, { datasource: "payfrit" });
}
// Collect menu item IDs for filtering template links
menuItemIds = [];
for (i = 1; i <= qItems.recordCount; i++) {
- arrayAppend(menuItemIds, qItems.ItemID[i]);
+ arrayAppend(menuItemIds, qItems.ID[i]);
}
// Get template links ONLY for this business's menu items
qTemplateLinks = queryNew("ParentItemID,TemplateItemID,SortOrder");
if (arrayLen(menuItemIds) > 0) {
- qTemplateLinks = queryTimed("
+ qTemplateLinks = queryExecute("
SELECT
tl.ItemID as ParentItemID,
tl.TemplateItemID,
tl.SortOrder
- FROM ItemTemplateLinks tl
+ FROM lt_ItemID_TemplateItemID tl
WHERE tl.ItemID IN (:itemIds)
ORDER BY tl.ItemID, tl.SortOrder
", { itemIds: { value: arrayToList(menuItemIds), cfsqltype: "cf_sql_varchar", list: true } }, { datasource: "payfrit" });
}
// Get templates for this business only
- qTemplates = queryTimed("
+ qTemplates = queryExecute("
SELECT DISTINCT
t.ItemID,
- t.ItemName,
- t.ItemPrice,
- t.ItemIsCheckedByDefault as IsDefault,
- t.ItemSortOrder,
- t.ItemRequiresChildSelection as RequiresSelection,
- t.ItemMaxNumSelectionReq as MaxSelections
+ t.Name,
+ t.Price,
+ t.IsCheckedByDefault as IsDefault,
+ t.SortOrder,
+ t.RequiresChildSelection as RequiresSelection,
+ t.MaxNumSelectionReq as MaxSelections
FROM Items t
- WHERE t.ItemBusinessID = :businessID
- AND (t.ItemCategoryID = 0 OR t.ItemCategoryID IS NULL)
- AND t.ItemParentItemID = 0
- AND t.ItemIsActive = 1
- ORDER BY t.ItemSortOrder, t.ItemName
+ WHERE t.BusinessID = :businessID
+ AND (t.CategoryID = 0 OR t.CategoryID IS NULL)
+ AND t.ParentItemID = 0
+ AND t.IsActive = 1
+ ORDER BY t.SortOrder, t.Name
", { businessID: businessID }, { datasource: "payfrit" });
// Get template children (options within templates)
@@ -298,38 +288,37 @@ try {
arrayAppend(templateIds, qTemplates.ItemID[i]);
}
- qTemplateChildren = queryNew("ItemID,ParentItemID,ItemName,ItemPrice,IsDefault,ItemSortOrder,RequiresSelection,MaxSelections");
+ qTemplateChildren = queryNew("ItemID,ParentItemID,Name,Price,IsDefault,SortOrder,RequiresSelection,MaxSelections");
if (arrayLen(templateIds) > 0) {
- qTemplateChildren = queryTimed("
+ qTemplateChildren = queryExecute("
SELECT
c.ItemID,
- c.ItemParentItemID as ParentItemID,
- c.ItemName,
- c.ItemPrice,
- c.ItemIsCheckedByDefault as IsDefault,
- c.ItemSortOrder,
- c.ItemRequiresChildSelection as RequiresSelection,
- c.ItemMaxNumSelectionReq as MaxSelections
+ c.ParentItemID as ParentItemID,
+ c.Name,
+ c.Price,
+ c.IsCheckedByDefault as IsDefault,
+ c.SortOrder,
+ c.RequiresChildSelection as RequiresSelection,
+ c.MaxNumSelectionReq as MaxSelections
FROM Items c
- WHERE c.ItemParentItemID IN (:templateIds)
- AND c.ItemIsActive = 1
- ORDER BY c.ItemSortOrder, c.ItemName
+ WHERE c.ParentItemID IN (:templateIds)
+ AND c.IsActive = 1
+ ORDER BY c.SortOrder, c.Name
", { templateIds: { value: arrayToList(templateIds), cfsqltype: "cf_sql_varchar", list: true } }, { datasource: "payfrit" });
}
- // Build templates lookup with their options (pre-index for fast tree building)
- templateChildrenIndex = buildParentIndex(qTemplateChildren);
+ // Build templates lookup with their options
templatesById = {};
for (i = 1; i <= qTemplates.recordCount; i++) {
templateID = qTemplates.ItemID[i];
- options = buildOptionsTree(qTemplateChildren, templateID, templateChildrenIndex);
+ options = buildOptionsTree(qTemplateChildren, templateID);
templatesById[templateID] = {
"id": "mod_" & qTemplates.ItemID[i],
"dbId": qTemplates.ItemID[i],
- "name": qTemplates.ItemName[i],
- "price": qTemplates.ItemPrice[i],
+ "name": qTemplates.Name[i],
+ "price": qTemplates.Price[i],
"isDefault": qTemplates.IsDefault[i] == 1 ? true : false,
- "sortOrder": qTemplates.ItemSortOrder[i],
+ "sortOrder": qTemplates.SortOrder[i],
"isTemplate": true,
"requiresSelection": isNull(qTemplates.RequiresSelection[i]) ? false : (qTemplates.RequiresSelection[i] == 1),
"maxSelections": isNull(qTemplates.MaxSelections[i]) ? 0 : qTemplates.MaxSelections[i],
@@ -354,11 +343,10 @@ try {
}
}
- // Build nested direct modifiers for each menu item (pre-index for fast tree building)
- directModifiersIndex = buildParentIndex(qDirectModifiers);
+ // Build nested direct modifiers for each menu item
directModsByItem = {};
for (itemId in menuItemIds) {
- options = buildOptionsTree(qDirectModifiers, itemId, directModifiersIndex);
+ options = buildOptionsTree(qDirectModifiers, itemId);
if (arrayLen(options) > 0) {
directModsByItem[itemId] = options;
}
@@ -372,7 +360,7 @@ try {
itemsByCategory[catID] = [];
}
- itemID = qItems.ItemID[i];
+ itemID = qItems.ID[i];
// Get template-linked modifiers
itemModifiers = structKeyExists(templateLinksByItem, itemID) ? duplicate(templateLinksByItem[itemID]) : [];
@@ -396,22 +384,22 @@ try {
itemImageUrl = "";
itemsDir = expandPath("/uploads/items");
for (ext in ["jpg","jpeg","png","gif","webp","JPG","JPEG","PNG","GIF","WEBP"]) {
- if (fileExists(itemsDir & "/" & qItems.ItemID[i] & "." & ext)) {
- itemImageUrl = "/uploads/items/" & qItems.ItemID[i] & "." & ext;
+ if (fileExists(itemsDir & "/" & qItems.ID[i] & "." & ext)) {
+ itemImageUrl = "/uploads/items/" & qItems.ID[i] & "." & ext;
break;
}
}
arrayAppend(itemsByCategory[catID], {
- "id": "item_" & qItems.ItemID[i],
- "dbId": qItems.ItemID[i],
- "name": qItems.ItemName[i],
- "description": isNull(qItems.ItemDescription[i]) ? "" : qItems.ItemDescription[i],
- "price": qItems.ItemPrice[i],
+ "id": "item_" & qItems.ID[i],
+ "dbId": qItems.ID[i],
+ "name": qItems.Name[i],
+ "description": isNull(qItems.Description[i]) ? "" : qItems.Description[i],
+ "price": qItems.Price[i],
"imageUrl": len(itemImageUrl) ? itemImageUrl : javaCast("null", ""),
"photoTaskId": javaCast("null", ""),
"modifiers": itemModifiers,
- "sortOrder": qItems.ItemSortOrder[i]
+ "sortOrder": qItems.SortOrder[i]
});
}
@@ -419,13 +407,13 @@ try {
categories = [];
catIndex = 0;
for (i = 1; i <= qCategories.recordCount; i++) {
- catID = qCategories.CategoryID[i];
+ catID = qCategories.ID[i];
catItems = structKeyExists(itemsByCategory, catID) ? itemsByCategory[catID] : [];
catStruct = {
- "id": "cat_" & qCategories.CategoryID[i],
- "dbId": qCategories.CategoryID[i],
- "name": qCategories.CategoryName[i],
+ "id": "cat_" & qCategories.ID[i],
+ "dbId": qCategories.ID[i],
+ "name": qCategories.Name[i],
"description": "",
"sortOrder": catIndex,
"items": catItems
@@ -434,7 +422,7 @@ try {
// Include MenuID if available (legacy schema with Categories table)
if (hasCategoriesData) {
try {
- catStruct["menuId"] = isNull(qCategories.CategoryMenuID[i]) ? 0 : val(qCategories.CategoryMenuID[i]);
+ catStruct["menuId"] = isNull(qCategories.MenuID[i]) ? 0 : val(qCategories.MenuID[i]);
} catch (any e) {
catStruct["menuId"] = 0;
}
@@ -453,11 +441,11 @@ try {
// Get business brand color
brandColor = "";
try {
- qBrand = queryTimed("
- SELECT BusinessBrandColor FROM Businesses WHERE BusinessID = :bizId
+ qBrand = queryExecute("
+ SELECT BrandColor FROM Businesses WHERE ID = :bizId
", { bizId: businessID }, { datasource: "payfrit" });
- if (qBrand.recordCount > 0 && len(trim(qBrand.BusinessBrandColor))) {
- brandColor = left(qBrand.BusinessBrandColor, 1) == chr(35) ? qBrand.BusinessBrandColor : chr(35) & qBrand.BusinessBrandColor;
+ if (qBrand.recordCount > 0 && len(trim(qBrand.BrandColor))) {
+ brandColor = left(qBrand.BrandColor, 1) == chr(35) ? qBrand.BrandColor : chr(35) & qBrand.BrandColor;
}
} catch (any e) {
// Column may not exist yet, ignore
@@ -486,6 +474,5 @@ try {
response["DETAIL"] = e.detail ?: "";
}
-logPerf();
writeOutput(serializeJSON(response));
diff --git a/api/menu/items.cfm b/api/menu/items.cfm
index 780f5a8..a793a44 100644
--- a/api/menu/items.cfm
+++ b/api/menu/items.cfm
@@ -48,27 +48,17 @@
-
-
-
-
-
-
- #cachedMenu#
-
-
-
-
+
- 0",
+ 0",
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" }
)>
@@ -80,12 +70,12 @@
-
+
-
@@ -96,17 +86,17 @@
-
+
-
-
+
@@ -134,42 +124,42 @@
- 0
+ OR FIND_IN_SET(:orderTypeId, OrderTypes) > 0
)
AND (
- CategoryScheduleStart IS NULL
- OR CategoryScheduleEnd IS NULL
+ ScheduleStart IS NULL
+ OR ScheduleEnd IS NULL
OR (
- TIME(:currentTime) >= CategoryScheduleStart
- AND TIME(:currentTime) <= CategoryScheduleEnd
+ TIME(:currentTime) >= ScheduleStart
+ AND TIME(:currentTime) <= ScheduleEnd
)
)
AND (
- CategoryScheduleDays IS NULL
- OR CategoryScheduleDays = ''
- OR FIND_IN_SET(:currentDay, CategoryScheduleDays) > 0
+ ScheduleDays IS NULL
+ OR ScheduleDays = ''
+ OR FIND_IN_SET(:currentDay, ScheduleDays) > 0
)
AND (
- CategoryMenuID IS NULL
- OR CategoryMenuID = 0
- #len(activeMenuIds) ? "OR CategoryMenuID IN (#activeMenuIds#)" : ""#
+ MenuID IS NULL
+ OR MenuID = 0
+ #len(activeMenuIds) ? "OR MenuID IN (#activeMenuIds#)" : ""#
)
- ORDER BY CategorySortOrder
+ ORDER BY SortOrder
",
{
bizId: { value = BusinessID, cfsqltype = "cf_sql_integer" },
@@ -184,94 +174,93 @@
-
+
-
- 0
- OR (i.ItemParentItemID = 0 AND i.ItemIsCollapsible = 0)
+ i.ParentItemID > 0
+ OR (i.ParentItemID = 0 AND i.IsCollapsible = 0)
)
- ORDER BY i.ItemParentItemID, i.ItemSortOrder, i.ItemID
+ ORDER BY i.ParentItemID, i.SortOrder, i.ID
",
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" }
@@ -279,31 +268,30 @@
-
-
-
+
+
-
+
@@ -352,72 +339,66 @@
-
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
@@ -485,21 +466,21 @@
@@ -509,21 +490,21 @@
@@ -533,20 +514,20 @@
-
-
-
+
+
-
-
-
-
- #menuResponse#
-
0) {
queryExecute("
- UPDATE Categories SET CategoryMenuID = 0
- WHERE CategoryMenuID = :menuID AND CategoryBusinessID = :businessID
+ UPDATE Categories SET MenuID = 0
+ WHERE MenuID = :menuID AND BusinessID = :businessID
", { menuID: menuID, businessID: businessID }, { datasource: "payfrit" });
}
// Soft-delete the menu
queryExecute("
- UPDATE Menus SET MenuIsActive = 0
- WHERE MenuID = :menuID AND MenuBusinessID = :businessID
+ UPDATE Menus SET IsActive = 0
+ WHERE ID = :menuID AND BusinessID = :businessID
", { menuID: menuID, businessID: businessID }, { datasource: "payfrit" });
response = {
@@ -227,8 +227,8 @@ try {
for (i = 1; i <= arrayLen(menuOrder); i++) {
queryExecute("
- UPDATE Menus SET MenuSortOrder = :sortOrder
- WHERE MenuID = :menuID AND MenuBusinessID = :businessID
+ UPDATE Menus SET SortOrder = :sortOrder
+ WHERE ID = :menuID AND BusinessID = :businessID
", {
menuID: val(menuOrder[i]),
businessID: businessID,
diff --git a/api/menu/saveCategory.cfm b/api/menu/saveCategory.cfm
index 5d8ee1d..3bc66c1 100644
--- a/api/menu/saveCategory.cfm
+++ b/api/menu/saveCategory.cfm
@@ -10,13 +10,13 @@
* POST body:
* {
* "CategoryID": 123, // Required for update
- * "CategoryBusinessID": 37, // Required for insert
- * "CategoryName": "Breakfast",
- * "CategorySortOrder": 1,
- * "CategoryOrderTypes": "1,2,3", // 1=Dine-In, 2=Takeaway, 3=Delivery
- * "CategoryScheduleStart": "06:00:00", // Optional, null = always available
- * "CategoryScheduleEnd": "11:00:00", // Optional
- * "CategoryScheduleDays": "2,3,4,5,6" // Optional, 1=Sun..7=Sat, null = all days
+ * "BusinessID": 37, // Required for insert
+ * "Name": "Breakfast",
+ * "SortOrder": 1,
+ * "OrderTypes": "1,2,3", // 1=Dine-In, 2=Takeaway, 3=Delivery
+ * "ScheduleStart": "06:00:00", // Optional, null = always available
+ * "ScheduleEnd": "11:00:00", // Optional
+ * "ScheduleDays": "2,3,4,5,6" // Optional, 1=Sun..7=Sat, null = all days
* }
*/
@@ -37,58 +37,58 @@ try {
data = readJsonBody();
CategoryID = structKeyExists(data, "CategoryID") ? val(data.CategoryID) : 0;
- CategoryBusinessID = structKeyExists(data, "CategoryBusinessID") ? val(data.CategoryBusinessID) : 0;
- CategoryName = structKeyExists(data, "CategoryName") ? left(trim(data.CategoryName), 30) : "";
- CategorySortOrder = structKeyExists(data, "CategorySortOrder") ? val(data.CategorySortOrder) : 0;
- CategoryOrderTypes = structKeyExists(data, "CategoryOrderTypes") ? trim(data.CategoryOrderTypes) : "1,2,3";
- CategoryScheduleStart = structKeyExists(data, "CategoryScheduleStart") && len(trim(data.CategoryScheduleStart))
- ? trim(data.CategoryScheduleStart) : javaCast("null", "");
- CategoryScheduleEnd = structKeyExists(data, "CategoryScheduleEnd") && len(trim(data.CategoryScheduleEnd))
- ? trim(data.CategoryScheduleEnd) : javaCast("null", "");
- CategoryScheduleDays = structKeyExists(data, "CategoryScheduleDays") && len(trim(data.CategoryScheduleDays))
- ? trim(data.CategoryScheduleDays) : javaCast("null", "");
+ BusinessID = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 0;
+ Name = structKeyExists(data, "Name") ? left(trim(data.Name), 30) : "";
+ SortOrder = structKeyExists(data, "SortOrder") ? val(data.SortOrder) : 0;
+ OrderTypes = structKeyExists(data, "OrderTypes") ? trim(data.OrderTypes) : "1,2,3";
+ ScheduleStart = structKeyExists(data, "ScheduleStart") && len(trim(data.ScheduleStart))
+ ? trim(data.ScheduleStart) : javaCast("null", "");
+ ScheduleEnd = structKeyExists(data, "ScheduleEnd") && len(trim(data.ScheduleEnd))
+ ? trim(data.ScheduleEnd) : javaCast("null", "");
+ ScheduleDays = structKeyExists(data, "ScheduleDays") && len(trim(data.ScheduleDays))
+ ? trim(data.ScheduleDays) : javaCast("null", "");
if (CategoryID > 0) {
// Update existing category
queryExecute("
UPDATE Categories SET
- CategoryName = :name,
- CategorySortOrder = :sortOrder,
- CategoryOrderTypes = :orderTypes,
- CategoryScheduleStart = :schedStart,
- CategoryScheduleEnd = :schedEnd,
- CategoryScheduleDays = :schedDays
- WHERE CategoryID = :catId
+ Name = :name,
+ SortOrder = :sortOrder,
+ OrderTypes = :orderTypes,
+ ScheduleStart = :schedStart,
+ ScheduleEnd = :schedEnd,
+ ScheduleDays = :schedDays
+ WHERE ID = :catId
", {
catId: CategoryID,
- name: CategoryName,
- sortOrder: CategorySortOrder,
- orderTypes: CategoryOrderTypes,
- schedStart: { value = CategoryScheduleStart, cfsqltype = "cf_sql_time", null = isNull(CategoryScheduleStart) },
- schedEnd: { value = CategoryScheduleEnd, cfsqltype = "cf_sql_time", null = isNull(CategoryScheduleEnd) },
- schedDays: { value = CategoryScheduleDays, cfsqltype = "cf_sql_varchar", null = isNull(CategoryScheduleDays) }
+ name: Name,
+ sortOrder: SortOrder,
+ orderTypes: OrderTypes,
+ schedStart: { value = ScheduleStart, cfsqltype = "cf_sql_time", null = isNull(ScheduleStart) },
+ schedEnd: { value = ScheduleEnd, cfsqltype = "cf_sql_time", null = isNull(ScheduleEnd) },
+ schedDays: { value = ScheduleDays, cfsqltype = "cf_sql_varchar", null = isNull(ScheduleDays) }
}, { datasource = "payfrit" });
response["OK"] = true;
response["CategoryID"] = CategoryID;
response["MESSAGE"] = "Category updated";
- } else if (CategoryBusinessID > 0 && len(CategoryName)) {
+ } else if (BusinessID > 0 && len(Name)) {
// Insert new category
queryExecute("
INSERT INTO Categories
- (CategoryBusinessID, CategoryName, CategorySortOrder, CategoryOrderTypes,
- CategoryScheduleStart, CategoryScheduleEnd, CategoryScheduleDays, CategoryAddedOn)
+ (BusinessID, Name, SortOrder, OrderTypes,
+ ScheduleStart, ScheduleEnd, ScheduleDays, AddedOn)
VALUES
(:bizId, :name, :sortOrder, :orderTypes, :schedStart, :schedEnd, :schedDays, NOW())
", {
- bizId: CategoryBusinessID,
- name: CategoryName,
- sortOrder: CategorySortOrder,
- orderTypes: CategoryOrderTypes,
- schedStart: { value = CategoryScheduleStart, cfsqltype = "cf_sql_time", null = isNull(CategoryScheduleStart) },
- schedEnd: { value = CategoryScheduleEnd, cfsqltype = "cf_sql_time", null = isNull(CategoryScheduleEnd) },
- schedDays: { value = CategoryScheduleDays, cfsqltype = "cf_sql_varchar", null = isNull(CategoryScheduleDays) }
+ bizId: BusinessID,
+ name: Name,
+ sortOrder: SortOrder,
+ orderTypes: OrderTypes,
+ schedStart: { value = ScheduleStart, cfsqltype = "cf_sql_time", null = isNull(ScheduleStart) },
+ schedEnd: { value = ScheduleEnd, cfsqltype = "cf_sql_time", null = isNull(ScheduleEnd) },
+ schedDays: { value = ScheduleDays, cfsqltype = "cf_sql_varchar", null = isNull(ScheduleDays) }
}, { datasource = "payfrit" });
qNew = queryExecute("SELECT LAST_INSERT_ID() as newId", {}, { datasource = "payfrit" });
@@ -98,7 +98,7 @@ try {
} else {
response["ERROR"] = "invalid_params";
- response["MESSAGE"] = "CategoryID required for update, or CategoryBusinessID and CategoryName for insert";
+ response["MESSAGE"] = "CategoryID required for update, or BusinessID and Name for insert";
}
} catch (any e) {
diff --git a/api/menu/saveFromBuilder.cfm b/api/menu/saveFromBuilder.cfm
index 2f6f215..dcbd92b 100644
--- a/api/menu/saveFromBuilder.cfm
+++ b/api/menu/saveFromBuilder.cfm
@@ -24,13 +24,13 @@ function saveOptionsRecursive(options, parentID, businessID) {
optionID = optDbId;
queryExecute("
UPDATE Items
- SET ItemName = :name,
- ItemPrice = :price,
- ItemIsCheckedByDefault = :isDefault,
- ItemSortOrder = :sortOrder,
- ItemRequiresChildSelection = :requiresSelection,
- ItemMaxNumSelectionReq = :maxSelections,
- ItemParentItemID = :parentID
+ SET Name = :name,
+ Price = :price,
+ IsCheckedByDefault = :isDefault,
+ SortOrder = :sortOrder,
+ RequiresChildSelection = :requiresSelection,
+ MaxNumSelectionReq = :maxSelections,
+ ParentItemID = :parentID
WHERE ItemID = :optID
", {
optID: optDbId,
@@ -45,9 +45,9 @@ function saveOptionsRecursive(options, parentID, businessID) {
} else {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemParentItemID, ItemName, ItemPrice,
- ItemIsCheckedByDefault, ItemSortOrder, ItemIsActive, ItemAddedOn,
- ItemRequiresChildSelection, ItemMaxNumSelectionReq, ItemCategoryID
+ BusinessID, ParentItemID, Name, Price,
+ IsCheckedByDefault, SortOrder, IsActive, AddedOn,
+ RequiresChildSelection, MaxNumSelectionReq, CategoryID
) VALUES (
:businessID, :parentID, :name, :price,
:isDefault, :sortOrder, 1, NOW(),
@@ -100,7 +100,7 @@ try {
try {
qCheck = queryExecute("
SELECT 1 FROM Items
- WHERE ItemBusinessID = :businessID AND ItemBusinessID > 0
+ WHERE BusinessID = :businessID AND BusinessID > 0
LIMIT 1
", { businessID: businessID });
newSchemaActive = (qCheck.recordCount > 0);
@@ -120,10 +120,10 @@ try {
categoryID = categoryDbId;
queryExecute("
UPDATE Items
- SET ItemName = :name,
- ItemSortOrder = :sortOrder
+ SET Name = :name,
+ SortOrder = :sortOrder
WHERE ItemID = :categoryID
- AND ItemBusinessID = :businessID
+ AND BusinessID = :businessID
", {
categoryID: categoryID,
businessID: businessID,
@@ -133,9 +133,9 @@ try {
} else {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemDescription,
- ItemParentItemID, ItemPrice, ItemIsActive,
- ItemSortOrder, ItemAddedOn, ItemCategoryID
+ BusinessID, Name, Description,
+ ParentItemID, Price, IsActive,
+ SortOrder, AddedOn, CategoryID
) VALUES (
:businessID, :name, '',
0, 0, 1,
@@ -159,9 +159,9 @@ try {
categoryID = categoryDbId;
queryExecute("
UPDATE Categories
- SET CategoryName = :name,
- CategorySortOrder = :sortOrder,
- CategoryMenuID = :menuId
+ SET Name = :name,
+ SortOrder = :sortOrder,
+ MenuID = :menuId
WHERE CategoryID = :categoryID
", {
categoryID: categoryID,
@@ -171,7 +171,7 @@ try {
});
} else {
queryExecute("
- INSERT INTO Categories (CategoryBusinessID, CategoryMenuID, CategoryName, CategorySortOrder, CategoryAddedOn)
+ INSERT INTO Categories (BusinessID, MenuID, Name, SortOrder, AddedOn)
VALUES (:businessID, :menuId, :name, :sortOrder, NOW())
", {
businessID: businessID,
@@ -198,11 +198,11 @@ try {
if (newSchemaActive) {
queryExecute("
UPDATE Items
- SET ItemName = :name,
- ItemDescription = :description,
- ItemPrice = :price,
- ItemParentItemID = :categoryID,
- ItemSortOrder = :sortOrder
+ SET Name = :name,
+ Description = :description,
+ Price = :price,
+ ParentItemID = :categoryID,
+ SortOrder = :sortOrder
WHERE ItemID = :itemID
", {
itemID: itemID,
@@ -215,11 +215,11 @@ try {
} else {
queryExecute("
UPDATE Items
- SET ItemName = :name,
- ItemDescription = :description,
- ItemPrice = :price,
- ItemCategoryID = :categoryID,
- ItemSortOrder = :sortOrder
+ SET Name = :name,
+ Description = :description,
+ Price = :price,
+ CategoryID = :categoryID,
+ SortOrder = :sortOrder
WHERE ItemID = :itemID
", {
itemID: itemID,
@@ -234,8 +234,8 @@ try {
if (newSchemaActive) {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemParentItemID, ItemName, ItemDescription,
- ItemPrice, ItemSortOrder, ItemIsActive, ItemAddedOn, ItemCategoryID
+ BusinessID, ParentItemID, Name, Description,
+ Price, SortOrder, IsActive, AddedOn, CategoryID
) VALUES (
:businessID, :categoryID, :name, :description,
:price, :sortOrder, 1, NOW(), 0
@@ -251,8 +251,8 @@ try {
} else {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemCategoryID, ItemName, ItemDescription,
- ItemPrice, ItemSortOrder, ItemIsActive, ItemParentItemID, ItemAddedOn
+ BusinessID, CategoryID, Name, Description,
+ Price, SortOrder, IsActive, ParentItemID, AddedOn
) VALUES (
:businessID, :categoryID, :name, :description,
:price, :sortOrder, 1, 0, NOW()
@@ -274,7 +274,7 @@ try {
// Handle modifiers
if (structKeyExists(item, "modifiers") && isArray(item.modifiers) && arrayLen(item.modifiers) > 0) {
// Clear existing template links for this item
- queryExecute("DELETE FROM ItemTemplateLinks WHERE ItemID = :itemID", { itemID: itemID });
+ queryExecute("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID = :itemID", { itemID: itemID });
modSortOrder = 0;
for (mod in item.modifiers) {
@@ -285,7 +285,7 @@ try {
if (structKeyExists(mod, "isTemplate") && mod.isTemplate && modDbId > 0) {
// This is a template reference - create link
queryExecute("
- INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
+ INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
VALUES (:itemID, :templateID, :sortOrder)
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
", {
@@ -297,8 +297,8 @@ try {
// Update template's selection rules
queryExecute("
UPDATE Items
- SET ItemRequiresChildSelection = :requiresSelection,
- ItemMaxNumSelectionReq = :maxSelections
+ SET RequiresChildSelection = :requiresSelection,
+ MaxNumSelectionReq = :maxSelections
WHERE ItemID = :modID
", {
modID: modDbId,
@@ -317,13 +317,13 @@ try {
// Direct modifier (not a template) - update it
queryExecute("
UPDATE Items
- SET ItemName = :name,
- ItemPrice = :price,
- ItemIsCheckedByDefault = :isDefault,
- ItemSortOrder = :sortOrder,
- ItemRequiresChildSelection = :requiresSelection,
- ItemMaxNumSelectionReq = :maxSelections,
- ItemParentItemID = :parentID
+ SET Name = :name,
+ Price = :price,
+ IsCheckedByDefault = :isDefault,
+ SortOrder = :sortOrder,
+ RequiresChildSelection = :requiresSelection,
+ MaxNumSelectionReq = :maxSelections,
+ ParentItemID = :parentID
WHERE ItemID = :modID
", {
modID: modDbId,
@@ -343,9 +343,9 @@ try {
// New direct modifier - insert it
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemParentItemID, ItemName, ItemPrice,
- ItemIsCheckedByDefault, ItemSortOrder, ItemIsActive, ItemAddedOn,
- ItemRequiresChildSelection, ItemMaxNumSelectionReq, ItemCategoryID
+ BusinessID, ParentItemID, Name, Price,
+ IsCheckedByDefault, SortOrder, IsActive, AddedOn,
+ RequiresChildSelection, MaxNumSelectionReq, CategoryID
) VALUES (
:businessID, :parentID, :name, :price,
:isDefault, :sortOrder, 1, NOW(),
@@ -379,9 +379,6 @@ try {
}
response = { "OK": true, "SCHEMA": newSchemaActive ? "unified" : "legacy" };
- // Invalidate menu cache for this business
- appCacheInvalidate("menu_" & businessID);
- appCacheInvalidate("menuBuilder_" & businessID);
} catch (any e) {
response = {
diff --git a/api/menu/updateStations.cfm b/api/menu/updateStations.cfm
index 2363302..a3d1b68 100644
--- a/api/menu/updateStations.cfm
+++ b/api/menu/updateStations.cfm
@@ -38,11 +38,11 @@
-
+
@@ -50,7 +50,7 @@
- SELECT BusinessHeaderImageExtension
+ SELECT HeaderImageExtension
FROM Businesses
- WHERE BusinessID =
+ WHERE ID =
-
-
+
+
@@ -75,7 +75,7 @@ if (bizId LTE 0) {
UPDATE Businesses
- SET BusinessHeaderImageExtension =
+ SET HeaderImageExtension =
WHERE BusinessID =
diff --git a/api/orders/abandonOrder.cfm b/api/orders/abandonOrder.cfm
index cf9794d..586a83a 100644
--- a/api/orders/abandonOrder.cfm
+++ b/api/orders/abandonOrder.cfm
@@ -37,7 +37,7 @@
@@ -46,20 +46,20 @@
-
+
diff --git a/api/orders/checkStatusUpdate.cfm b/api/orders/checkStatusUpdate.cfm
index edc5de6..cac62ec 100644
--- a/api/orders/checkStatusUpdate.cfm
+++ b/api/orders/checkStatusUpdate.cfm
@@ -30,15 +30,15 @@
SELECT
- OrderID,
- OrderStatusID,
- OrderLastEditedOn,
- OrderServicePointID,
- OrderBusinessID,
- OrderUserID
+ ID,
+ StatusID,
+ LastEditedOn,
+ ServicePointID,
+ BusinessID,
+ UserID
FROM Orders
- WHERE OrderID =
- AND OrderStatusID !=
+ WHERE ID =
+ AND StatusID !=
@@ -47,7 +47,7 @@
-
+
@@ -84,11 +84,11 @@
@@ -103,6 +103,5 @@
-
#serializeJSON(payload)#
diff --git a/api/orders/debugLineItems.cfm b/api/orders/debugLineItems.cfm
index 38b1caf..1529f7d 100644
--- a/api/orders/debugLineItems.cfm
+++ b/api/orders/debugLineItems.cfm
@@ -14,33 +14,33 @@
diff --git a/api/orders/getActiveCart.cfm b/api/orders/getActiveCart.cfm
index ae84140..c82cc9c 100644
--- a/api/orders/getActiveCart.cfm
+++ b/api/orders/getActiveCart.cfm
@@ -29,27 +29,27 @@ try {
// Get active cart (status = 0) for this user
qCart = queryExecute("
SELECT
- o.OrderID,
- o.OrderUUID,
- o.OrderBusinessID,
+ o.ID,
+ o.UUID,
+ o.BusinessID,
o.OrderTypeID,
- o.OrderStatusID,
- o.OrderServicePointID,
- o.OrderAddedOn,
- b.BusinessName,
- b.BusinessOrderTypes,
- sp.ServicePointName,
+ o.StatusID,
+ o.ServicePointID,
+ o.AddedOn,
+ b.Name,
+ b.OrderTypes,
+ sp.Name,
(SELECT COUNT(*)
FROM OrderLineItems oli
- WHERE oli.OrderLineItemOrderID = o.OrderID
- AND oli.OrderLineItemIsDeleted = 0
- AND oli.OrderLineItemParentOrderLineItemID = 0) as ItemCount
+ WHERE oli.OrderID = o.ID
+ AND oli.IsDeleted = 0
+ AND oli.ParentOrderLineItemID = 0) as ItemCount
FROM Orders o
- LEFT JOIN Businesses b ON b.BusinessID = o.OrderBusinessID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
- WHERE o.OrderUserID = :userId
- AND o.OrderStatusID = 0
- ORDER BY o.OrderID DESC
+ LEFT JOIN Businesses b ON b.ID = o.BusinessID
+ LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
+ WHERE o.UserID = :userId
+ AND o.StatusID = 0
+ ORDER BY o.ID DESC
LIMIT 1
", {
userId: { value: UserID, cfsqltype: "cf_sql_integer" }
@@ -65,23 +65,23 @@ try {
}
// Parse business order types (e.g., "1,2,3" -> array of ints)
- businessOrderTypes = len(trim(qCart.BusinessOrderTypes)) ? qCart.BusinessOrderTypes : "1,2,3";
+ businessOrderTypes = len(trim(qCart.OrderTypes)) ? qCart.OrderTypes : "1,2,3";
orderTypesArray = listToArray(businessOrderTypes, ",");
response["OK"] = true;
response["HAS_CART"] = true;
response["CART"] = {
"OrderID": val(qCart.OrderID),
- "OrderUUID": qCart.OrderUUID ?: "",
- "BusinessID": val(qCart.OrderBusinessID),
- "BusinessName": len(trim(qCart.BusinessName)) ? qCart.BusinessName : "",
- "BusinessOrderTypes": orderTypesArray,
+ "UUID": qCart.UUID ?: "",
+ "BusinessID": val(qCart.BusinessID),
+ "Name": len(trim(qCart.Name)) ? qCart.Name : "",
+ "OrderTypes": orderTypesArray,
"OrderTypeID": val(qCart.OrderTypeID),
"OrderTypeName": orderTypeName,
- "ServicePointID": val(qCart.OrderServicePointID),
- "ServicePointName": len(trim(qCart.ServicePointName)) ? qCart.ServicePointName : "",
+ "ServicePointID": val(qCart.ServicePointID),
+ "Name": len(trim(qCart.Name)) ? qCart.Name : "",
"ItemCount": val(qCart.ItemCount),
- "AddedOn": dateTimeFormat(qCart.OrderAddedOn, "yyyy-mm-dd HH:nn:ss")
+ "AddedOn": dateTimeFormat(qCart.AddedOn, "yyyy-mm-dd HH:nn:ss")
};
} else {
response["OK"] = true;
diff --git a/api/orders/getCart.cfm b/api/orders/getCart.cfm
index 5aad4ee..dd209d9 100644
--- a/api/orders/getCart.cfm
+++ b/api/orders/getCart.cfm
@@ -37,24 +37,24 @@
-
-
+
+
@@ -126,24 +126,24 @@
"OK": true,
"ERROR": "",
"ORDER": {
- "OrderID": val(qOrder.OrderID),
- "OrderUUID": qOrder.OrderUUID ?: "",
- "OrderUserID": val(qOrder.OrderUserID),
- "OrderBusinessID": val(qOrder.OrderBusinessID),
- "OrderBusinessDeliveryMultiplier": val(qOrder.OrderBusinessDeliveryMultiplier),
+ "OrderID": val(qOrder.ID),
+ "UUID": qOrder.UUID ?: "",
+ "UserID": val(qOrder.UserID),
+ "BusinessID": val(qOrder.BusinessID),
+ "DeliveryMultiplier": val(qOrder.DeliveryMultiplier),
"OrderTypeID": val(qOrder.OrderTypeID),
- "OrderDeliveryFee": val(qOrder.OrderDeliveryFee),
+ "DeliveryFee": val(qOrder.DeliveryFee),
"BusinessDeliveryFee": val(businessDeliveryFee),
- "BusinessOrderTypes": businessOrderTypesArray,
- "OrderStatusID": val(qOrder.OrderStatusID),
- "OrderAddressID": val(qOrder.OrderAddressID),
- "OrderPaymentID": val(qOrder.OrderPaymentID),
- "OrderPaymentStatus": qOrder.OrderPaymentStatus ?: "",
- "OrderRemarks": qOrder.OrderRemarks ?: "",
- "OrderAddedOn": qOrder.OrderAddedOn,
- "OrderLastEditedOn": qOrder.OrderLastEditedOn,
- "OrderSubmittedOn": qOrder.OrderSubmittedOn,
- "OrderServicePointID": val(qOrder.OrderServicePointID)
+ "OrderTypes": businessOrderTypesArray,
+ "StatusID": val(qOrder.StatusID),
+ "AddressID": val(qOrder.AddressID),
+ "PaymentID": val(qOrder.PaymentID),
+ "PaymentStatus": qOrder.PaymentStatus ?: "",
+ "Remarks": qOrder.Remarks ?: "",
+ "AddedOn": qOrder.AddedOn,
+ "LastEditedOn": qOrder.LastEditedOn,
+ "SubmittedOn": qOrder.SubmittedOn,
+ "ServicePointID": val(qOrder.ServicePointID)
},
"ORDERLINEITEMS": rows
})>
diff --git a/api/orders/getDetail.cfm b/api/orders/getDetail.cfm
index 3491ca6..bd0e744 100644
--- a/api/orders/getDetail.cfm
+++ b/api/orders/getDetail.cfm
@@ -42,32 +42,32 @@ try {
}
// Get order details
- qOrder = queryTimed("
+ qOrder = queryExecute("
SELECT
- o.OrderID,
- o.OrderBusinessID,
- o.OrderUserID,
- o.OrderServicePointID,
- o.OrderStatusID,
+ o.ID,
+ o.BusinessID,
+ o.UserID,
+ o.ServicePointID,
+ o.StatusID,
o.OrderTypeID,
- o.OrderRemarks,
- o.OrderAddedOn,
- o.OrderLastEditedOn,
- o.OrderSubmittedOn,
+ o.Remarks,
+ o.AddedOn,
+ o.LastEditedOn,
+ o.SubmittedOn,
o.OrderTipAmount,
- u.UserFirstName,
- u.UserLastName,
- u.UserContactNumber,
- u.UserEmailAddress,
- sp.ServicePointName,
- sp.ServicePointTypeID,
- b.BusinessName,
- b.BusinessTaxRate
+ u.FirstName,
+ u.LastName,
+ u.ContactNumber,
+ u.EmailAddress,
+ sp.Name,
+ sp.TypeID,
+ b.Name,
+ b.TaxRate
FROM Orders o
- LEFT JOIN Users u ON u.UserID = o.OrderUserID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
- LEFT JOIN Businesses b ON b.BusinessID = o.OrderBusinessID
- WHERE o.OrderID = :orderID
+ LEFT JOIN Users u ON u.ID = o.UserID
+ LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
+ LEFT JOIN Businesses b ON b.ID = o.BusinessID
+ WHERE o.ID = :orderID
", { orderID: orderID });
if (qOrder.recordCount == 0) {
@@ -78,22 +78,22 @@ try {
}
// Get line items (excluding deleted items)
- qItems = queryTimed("
+ qItems = queryExecute("
SELECT
- oli.OrderLineItemID,
- oli.OrderLineItemItemID,
- oli.OrderLineItemParentOrderLineItemID,
- oli.OrderLineItemQuantity,
- oli.OrderLineItemPrice,
- oli.OrderLineItemRemark,
- i.ItemName,
- i.ItemPrice,
- i.ItemIsCheckedByDefault
+ oli.ID,
+ oli.ItemID,
+ oli.ParentOrderLineItemID,
+ oli.Quantity,
+ oli.Price,
+ oli.Remark,
+ i.Name,
+ i.Price,
+ i.IsCheckedByDefault
FROM OrderLineItems oli
- INNER JOIN Items i ON i.ItemID = oli.OrderLineItemItemID
- WHERE oli.OrderLineItemOrderID = :orderID
- AND oli.OrderLineItemIsDeleted = 0
- ORDER BY oli.OrderLineItemID
+ INNER JOIN Items i ON i.ID = oli.ItemID
+ WHERE oli.OrderID = :orderID
+ AND oli.IsDeleted = 0
+ ORDER BY oli.ID
", { orderID: orderID });
// Build line items array with parent-child structure
@@ -103,22 +103,22 @@ try {
// First pass: create all items (use bracket notation to preserve key casing)
for (row in qItems) {
item = structNew("ordered");
- item["LineItemID"] = val(row.OrderLineItemID);
- item["ItemID"] = val(row.OrderLineItemItemID);
- item["ParentLineItemID"] = val(row.OrderLineItemParentOrderLineItemID);
- item["ItemName"] = row.ItemName ?: "";
- item["Quantity"] = val(row.OrderLineItemQuantity);
- item["UnitPrice"] = val(row.OrderLineItemPrice);
- item["Remarks"] = row.OrderLineItemRemark ?: "";
- item["IsDefault"] = (val(row.ItemIsCheckedByDefault) == 1);
+ item["LineItemID"] = val(row.ID);
+ item["ItemID"] = val(row.ID);
+ item["ParentLineItemID"] = val(row.ParentOrderLineItemID);
+ item["Name"] = row.Name ?: "";
+ item["Quantity"] = val(row.Quantity);
+ item["UnitPrice"] = val(row.Price);
+ item["Remarks"] = row.Remark ?: "";
+ item["IsDefault"] = (val(row.IsCheckedByDefault) == 1);
item["Modifiers"] = [];
- itemsById[row.OrderLineItemID] = item;
+ itemsById[row.ID] = item;
}
// Second pass: build hierarchy
for (row in qItems) {
- item = itemsById[row.OrderLineItemID];
- parentID = row.OrderLineItemParentOrderLineItemID;
+ item = itemsById[row.ID];
+ parentID = row.ParentOrderLineItemID;
if (parentID > 0 && structKeyExists(itemsById, parentID)) {
// This is a modifier - add to parent (use bracket notation)
@@ -141,7 +141,7 @@ try {
}
// Calculate tax using business tax rate or default 8.25%
- taxRate = isNumeric(qOrder.BusinessTaxRate) && qOrder.BusinessTaxRate > 0 ? qOrder.BusinessTaxRate : 0.0825;
+ taxRate = isNumeric(qOrder.TaxRate) && qOrder.TaxRate > 0 ? qOrder.TaxRate : 0.0825;
tax = subtotal * taxRate;
// Get tip from order
@@ -150,60 +150,64 @@ try {
// Calculate total
total = subtotal + tax + tip;
- // Get staff who worked on this order (LEFT JOIN instead of correlated subquery)
- qStaff = queryTimed("
- SELECT DISTINCT u.UserID, u.UserFirstName, r.TaskRatingAccessToken AS RatingToken
+ // Get staff who worked on this order (from Tasks table) with pending rating tokens
+ qStaff = queryExecute("
+ SELECT DISTINCT u.ID, u.FirstName,
+ (SELECT r.AccessToken
+ FROM TaskRatings r
+ INNER JOIN Tasks t2 ON t2.ID = r.TaskID
+ WHERE t2.OrderID = :orderID
+ AND r.ForUserID = u.ID
+ AND r.Direction = 'customer_rates_worker'
+ AND r.CompletedOn IS NULL
+ AND r.ExpiresOn > NOW()
+ LIMIT 1) AS RatingToken
FROM Tasks t
- INNER JOIN Users u ON u.UserID = t.TaskClaimedByUserID
- LEFT JOIN TaskRatings r ON r.TaskRatingTaskID = t.TaskID
- AND r.TaskRatingForUserID = u.UserID
- AND r.TaskRatingDirection = 'customer_rates_worker'
- AND r.TaskRatingCompletedOn IS NULL
- AND r.TaskRatingExpiresOn > NOW()
- WHERE t.TaskOrderID = :orderID
- AND t.TaskClaimedByUserID > 0
+ INNER JOIN Users u ON u.ID = t.ClaimedByUserID
+ WHERE t.OrderID = :orderID
+ AND t.ClaimedByUserID > 0
", { orderID: orderID });
// Build staff array with avatar URLs and rating tokens (use ordered structs)
staff = [];
for (row in qStaff) {
staffMember = structNew("ordered");
- staffMember["UserID"] = row.UserID;
- staffMember["FirstName"] = row.UserFirstName;
- staffMember["AvatarUrl"] = "https://biz.payfrit.com/uploads/users/" & row.UserID & ".jpg";
+ staffMember["UserID"] = row.ID;
+ staffMember["FirstName"] = row.FirstName;
+ staffMember["AvatarUrl"] = "https://biz.payfrit.com/uploads/users/" & row.ID & ".jpg";
staffMember["RatingToken"] = row.RatingToken ?: "";
arrayAppend(staff, staffMember);
}
// Build response (use ordered structs to preserve key casing)
customer = structNew("ordered");
- customer["UserID"] = qOrder.OrderUserID;
- customer["FirstName"] = qOrder.UserFirstName;
- customer["LastName"] = qOrder.UserLastName;
- customer["Phone"] = qOrder.UserContactNumber;
- customer["Email"] = qOrder.UserEmailAddress;
+ customer["UserID"] = qOrder.UserID;
+ customer["FirstName"] = qOrder.FirstName;
+ customer["LastName"] = qOrder.LastName;
+ customer["Phone"] = qOrder.ContactNumber;
+ customer["Email"] = qOrder.EmailAddress;
servicePoint = structNew("ordered");
- servicePoint["ServicePointID"] = qOrder.OrderServicePointID;
- servicePoint["Name"] = qOrder.ServicePointName;
- servicePoint["TypeID"] = qOrder.ServicePointTypeID;
+ servicePoint["ServicePointID"] = qOrder.ServicePointID;
+ servicePoint["Name"] = qOrder.Name;
+ servicePoint["TypeID"] = qOrder.TypeID;
order = structNew("ordered");
- order["OrderID"] = qOrder.OrderID;
- order["BusinessID"] = qOrder.OrderBusinessID;
- order["BusinessName"] = qOrder.BusinessName ?: "";
- order["Status"] = qOrder.OrderStatusID;
- order["StatusText"] = getStatusText(qOrder.OrderStatusID);
+ order["OrderID"] = qOrder.ID;
+ order["BusinessID"] = qOrder.BusinessID;
+ order["Name"] = qOrder.Name ?: "";
+ order["Status"] = qOrder.StatusID;
+ order["StatusText"] = getStatusText(qOrder.StatusID);
order["OrderTypeID"] = qOrder.OrderTypeID ?: 0;
order["OrderTypeName"] = getOrderTypeName(qOrder.OrderTypeID ?: 0);
order["Subtotal"] = subtotal;
order["Tax"] = tax;
order["Tip"] = tip;
order["Total"] = total;
- order["Notes"] = qOrder.OrderRemarks;
- order["CreatedOn"] = dateTimeFormat(qOrder.OrderAddedOn, "yyyy-mm-dd HH:nn:ss");
- order["SubmittedOn"] = len(qOrder.OrderSubmittedOn) ? dateTimeFormat(qOrder.OrderSubmittedOn, "yyyy-mm-dd HH:nn:ss") : "";
- order["UpdatedOn"] = len(qOrder.OrderLastEditedOn) ? dateTimeFormat(qOrder.OrderLastEditedOn, "yyyy-mm-dd HH:nn:ss") : "";
+ order["Notes"] = qOrder.Remarks;
+ order["CreatedOn"] = dateTimeFormat(qOrder.AddedOn, "yyyy-mm-dd HH:nn:ss");
+ order["SubmittedOn"] = len(qOrder.SubmittedOn) ? dateTimeFormat(qOrder.SubmittedOn, "yyyy-mm-dd HH:nn:ss") : "";
+ order["UpdatedOn"] = len(qOrder.LastEditedOn) ? dateTimeFormat(qOrder.LastEditedOn, "yyyy-mm-dd HH:nn:ss") : "";
order["Customer"] = customer;
order["ServicePoint"] = servicePoint;
order["LineItems"] = lineItems;
@@ -217,7 +221,6 @@ try {
response["MESSAGE"] = e.message;
}
-logPerf();
writeOutput(serializeJSON(response));
// Helper functions
diff --git a/api/orders/getOrCreateCart.cfm b/api/orders/getOrCreateCart.cfm
index 890be99..dfea049 100644
--- a/api/orders/getOrCreateCart.cfm
+++ b/api/orders/getOrCreateCart.cfm
@@ -33,23 +33,23 @@
-
+
@@ -143,16 +143,16 @@
-
+
-
+
-
+
@@ -168,20 +168,20 @@
-
+
-
+
@@ -205,33 +205,33 @@
-
+
-
+
@@ -262,21 +262,21 @@
-
+
diff --git a/api/orders/getPendingForUser.cfm b/api/orders/getPendingForUser.cfm
index 103fc11..5cfc0b1 100644
--- a/api/orders/getPendingForUser.cfm
+++ b/api/orders/getPendingForUser.cfm
@@ -39,26 +39,26 @@ try {
// These are orders that are paid but not yet completed/picked up
qOrders = queryExecute("
SELECT
- o.OrderID,
- o.OrderUUID,
+ o.ID,
+ o.UUID,
o.OrderTypeID,
- o.OrderStatusID,
- o.OrderSubmittedOn,
- o.OrderServicePointID,
- sp.ServicePointName,
- b.BusinessName,
- (SELECT COALESCE(SUM(oli.OrderLineItemPrice * oli.OrderLineItemQuantity), 0)
+ o.StatusID,
+ o.SubmittedOn,
+ o.ServicePointID,
+ sp.Name,
+ b.Name,
+ (SELECT COALESCE(SUM(oli.Price * oli.Quantity), 0)
FROM OrderLineItems oli
- WHERE oli.OrderLineItemOrderID = o.OrderID
- AND oli.OrderLineItemIsDeleted = 0
- AND oli.OrderLineItemParentOrderLineItemID = 0) as Subtotal
+ WHERE oli.OrderID = o.ID
+ AND oli.IsDeleted = 0
+ AND oli.ParentOrderLineItemID = 0) as Subtotal
FROM Orders o
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
- LEFT JOIN Businesses b ON b.BusinessID = o.OrderBusinessID
- WHERE o.OrderUserID = :userId
- AND o.OrderBusinessID = :businessId
- AND o.OrderStatusID IN (1, 2, 3)
- ORDER BY o.OrderSubmittedOn DESC
+ LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
+ LEFT JOIN Businesses b ON b.ID = o.BusinessID
+ WHERE o.UserID = :userId
+ AND o.BusinessID = :businessId
+ AND o.StatusID IN (1, 2, 3)
+ ORDER BY o.SubmittedOn DESC
LIMIT 5
", {
userId: { value: UserID, cfsqltype: "cf_sql_integer" },
@@ -68,7 +68,7 @@ try {
orders = [];
for (row in qOrders) {
statusName = "";
- switch (row.OrderStatusID) {
+ switch (row.StatusID) {
case 1: statusName = "Submitted"; break;
case 2: statusName = "Preparing"; break;
case 3: statusName = "Ready for Pickup"; break;
@@ -82,16 +82,16 @@ try {
}
arrayAppend(orders, {
- "OrderID": row.OrderID,
- "OrderUUID": row.OrderUUID,
+ "OrderID": row.ID,
+ "UUID": row.UUID,
"OrderTypeID": row.OrderTypeID,
"OrderTypeName": orderTypeName,
- "OrderStatusID": row.OrderStatusID,
+ "StatusID": row.StatusID,
"StatusName": statusName,
- "SubmittedOn": dateTimeFormat(row.OrderSubmittedOn, "yyyy-mm-dd HH:nn:ss"),
- "ServicePointID": row.OrderServicePointID,
- "ServicePointName": len(trim(row.ServicePointName)) ? row.ServicePointName : "",
- "BusinessName": len(trim(row.BusinessName)) ? row.BusinessName : "",
+ "SubmittedOn": dateTimeFormat(row.SubmittedOn, "yyyy-mm-dd HH:nn:ss"),
+ "ServicePointID": row.ServicePointID,
+ "Name": len(trim(row.Name)) ? row.Name : "",
+ "Name": len(trim(row.Name)) ? row.Name : "",
"Subtotal": row.Subtotal
});
}
diff --git a/api/orders/history.cfm b/api/orders/history.cfm
index 54325ff..1cc10bc 100644
--- a/api/orders/history.cfm
+++ b/api/orders/history.cfm
@@ -38,7 +38,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U
userToken = getHeader("X-User-Token");
if (len(userToken)) {
try {
- qTok = queryTimed(
+ qTok = queryExecute(
"SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1",
[ { value = userToken, cfsqltype = "cf_sql_varchar" } ],
{ datasource = "payfrit" }
@@ -63,23 +63,23 @@ if (offset < 0) offset = 0;
try {
// Get orders for this user (exclude carts - status 0)
- qOrders = queryTimed("
+ qOrders = queryExecute("
SELECT
- o.OrderID,
- o.OrderUUID,
- o.OrderBusinessID,
- o.OrderStatusID,
+ o.ID,
+ o.UUID,
+ o.BusinessID,
+ o.StatusID,
o.OrderTypeID,
- o.OrderAddedOn,
- o.OrderLastEditedOn,
- b.BusinessName,
- COALESCE(ot.tt_OrderTypeName, 'Unknown') as OrderTypeName
+ o.AddedOn,
+ o.LastEditedOn,
+ b.Name,
+ COALESCE(ot.Name, 'Unknown') as OrderTypeName
FROM Orders o
- LEFT JOIN Businesses b ON b.BusinessID = o.OrderBusinessID
- LEFT JOIN tt_OrderTypes ot ON ot.tt_OrderTypeID = o.OrderTypeID
- WHERE o.OrderUserID = :userId
- AND o.OrderStatusID > 0
- ORDER BY o.OrderAddedOn DESC
+ LEFT JOIN Businesses b ON b.ID = o.BusinessID
+ LEFT JOIN tt_OrderTypes ot ON ot.ID = o.OrderTypeID
+ WHERE o.UserID = :userId
+ AND o.StatusID > 0
+ ORDER BY o.AddedOn DESC
LIMIT :limit OFFSET :offset
", {
userId: { value = userId, cfsqltype = "cf_sql_integer" },
@@ -88,46 +88,35 @@ try {
});
// Get total count
- qCount = queryTimed("
+ qCount = queryExecute("
SELECT COUNT(*) as TotalCount
FROM Orders
- WHERE OrderUserID = :userId
- AND OrderStatusID > 0
+ WHERE UserID = :userId
+ AND StatusID > 0
", { userId: { value = userId, cfsqltype = "cf_sql_integer" } });
- // Batch fetch line item counts and totals for ALL orders (eliminates N+1)
- itemSummary = {};
- orderIds = valueList(qOrders.OrderID);
- if (len(orderIds)) {
- qAllItems = queryTimed("
- SELECT
- OrderLineItemOrderID,
- COUNT(*) as ItemCount,
- SUM(OrderLineItemQuantity * OrderLineItemPrice) as Subtotal
- FROM OrderLineItems
- WHERE OrderLineItemOrderID IN (:orderIds)
- AND OrderLineItemParentOrderLineItemID = 0
- AND (OrderLineItemIsDeleted = 0 OR OrderLineItemIsDeleted IS NULL)
- GROUP BY OrderLineItemOrderID
- ", { orderIds: { value = orderIds, cfsqltype = "cf_sql_varchar", list = true } });
-
- for (r in qAllItems) {
- itemSummary[r.OrderLineItemOrderID] = { count: r.ItemCount, subtotal: r.Subtotal };
- }
- }
-
- // Build orders array
+ // Build orders array with item counts and totals
orders = [];
for (row in qOrders) {
- summary = structKeyExists(itemSummary, row.OrderID) ? itemSummary[row.OrderID] : { count: 0, subtotal: 0 };
- itemCount = val(summary.count);
- subtotal = val(summary.subtotal);
+ // Get line item count and calculate total
+ qItems = queryExecute("
+ SELECT
+ COUNT(*) as ItemCount,
+ SUM(Quantity * Price) as Subtotal
+ FROM OrderLineItems
+ WHERE OrderID = :orderId
+ AND ParentOrderLineItemID = 0
+ AND (IsDeleted = 0 OR IsDeleted IS NULL)
+ ", { orderId: { value = row.ID, cfsqltype = "cf_sql_integer" } });
+
+ itemCount = val(qItems.ItemCount);
+ subtotal = val(qItems.Subtotal);
tax = subtotal * 0.0875;
total = subtotal + tax;
// Get status text
statusText = "";
- switch (row.OrderStatusID) {
+ switch (row.StatusID) {
case 1: statusText = "Submitted"; break;
case 2: statusText = "In Progress"; break;
case 3: statusText = "Ready"; break;
@@ -139,25 +128,25 @@ try {
// Safely format dates
createdAt = "";
try {
- if (!isNull(row.OrderAddedOn) && len(trim(row.OrderAddedOn))) {
- createdAt = dateTimeFormat(row.OrderAddedOn, "yyyy-mm-dd'T'HH:nn:ss");
+ if (!isNull(row.AddedOn) && len(trim(row.AddedOn))) {
+ createdAt = dateTimeFormat(row.AddedOn, "yyyy-mm-dd'T'HH:nn:ss");
}
} catch (any de) { createdAt = ""; }
completedAt = "";
try {
- if (row.OrderStatusID >= 4 && !isNull(row.OrderLastEditedOn) && len(trim(row.OrderLastEditedOn))) {
- completedAt = dateTimeFormat(row.OrderLastEditedOn, "yyyy-mm-dd'T'HH:nn:ss");
+ if (row.StatusID >= 4 && !isNull(row.LastEditedOn) && len(trim(row.LastEditedOn))) {
+ completedAt = dateTimeFormat(row.LastEditedOn, "yyyy-mm-dd'T'HH:nn:ss");
}
} catch (any de) { completedAt = ""; }
arrayAppend(orders, {
- "OrderID": val(row.OrderID),
- "OrderUUID": row.OrderUUID ?: "",
- "BusinessID": val(row.OrderBusinessID),
- "BusinessName": row.BusinessName ?: "Unknown",
+ "OrderID": val(row.ID),
+ "UUID": row.UUID ?: "",
+ "BusinessID": val(row.BusinessID),
+ "Name": row.Name ?: "Unknown",
"OrderTotal": round(val(total) * 100) / 100,
- "OrderStatusID": val(row.OrderStatusID),
+ "StatusID": val(row.StatusID),
"StatusName": statusText,
"OrderTypeID": val(row.OrderTypeID),
"TypeName": row.OrderTypeName ?: "Unknown",
@@ -167,7 +156,6 @@ try {
});
}
- logPerf();
writeOutput(serializeJSON({
"OK": true,
"ORDERS": orders,
diff --git a/api/orders/listForKDS.cfm b/api/orders/listForKDS.cfm
index b280430..82a9fdb 100644
--- a/api/orders/listForKDS.cfm
+++ b/api/orders/listForKDS.cfm
@@ -1,4 +1,4 @@
-
+
@@ -37,20 +37,20 @@
-
+
-
+
- = 1")>
+ = 1")>
-
+
@@ -58,135 +58,126 @@
-
-
-
-
-
-
+
+
+
- 0)
- ORDER BY oli.OrderLineItemOrderID, oli.OrderLineItemID
- ", [ { value = StationID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
+ INNER JOIN Items i ON i.ID = oli.ItemID
+ LEFT JOIN Items parent ON parent.ItemID = i.ParentItemID
+ WHERE oli.OrderID = ?
+ AND oli.IsDeleted = b'0'
+ AND (i.StationID = ? OR i.StationID = 0 OR i.StationID IS NULL OR oli.ParentOrderLineItemID > 0)
+ ORDER BY oli.ID
+ ", [
+ { value = qOrders.ID, cfsqltype = "cf_sql_integer" },
+ { value = StationID, cfsqltype = "cf_sql_integer" }
+ ], { datasource = "payfrit" })>
-
+ INNER JOIN Items i ON i.ID = oli.ItemID
+ LEFT JOIN Items parent ON parent.ItemID = i.ParentItemID
+ WHERE oli.OrderID = ?
+ AND oli.IsDeleted = b'0'
+ ORDER BY oli.ID
+ ", [ { value = qOrders.ID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
-
-
-
-
-
-
-
+
+
-
-
-
-
-
@@ -198,25 +189,24 @@
-
direct child: ItemID=#qKids.ItemID#")>
-
+
template child: ItemID=#qTemplateKids.ItemID#")>
-
+
@@ -96,16 +96,16 @@
-
+
@@ -318,16 +318,16 @@
-
+
@@ -364,21 +364,21 @@
-
+
-
+
@@ -180,9 +180,9 @@
-
+
@@ -201,12 +201,12 @@
-
+
@@ -218,9 +218,9 @@
"
UPDATE Orders
SET OrderTypeID = ?,
- OrderAddressID = ?,
- OrderDeliveryFee = ?,
- OrderLastEditedOn = ?
+ AddressID = ?,
+ DeliveryFee = ?,
+ LastEditedOn = ?
WHERE OrderID = ?
",
[
@@ -238,9 +238,9 @@
"
UPDATE Orders
SET OrderTypeID = ?,
- OrderAddressID = NULL,
- OrderDeliveryFee = 0,
- OrderLastEditedOn = ?
+ AddressID = NULL,
+ DeliveryFee = 0,
+ LastEditedOn = ?
WHERE OrderID = ?
",
[
diff --git a/api/orders/submit.cfm b/api/orders/submit.cfm
index 1d52472..f9878c0 100644
--- a/api/orders/submit.cfm
+++ b/api/orders/submit.cfm
@@ -37,12 +37,12 @@
-
-
+
+
-
-
+
+
@@ -79,11 +79,11 @@
@@ -140,11 +140,11 @@
-
+
@@ -167,11 +167,11 @@
-
+
@@ -181,9 +181,9 @@
"
SELECT COUNT(*) AS Cnt
FROM OrderLineItems
- WHERE OrderLineItemOrderID = ?
- AND OrderLineItemParentOrderLineItemID = 0
- AND OrderLineItemIsDeleted = b'0'
+ WHERE OrderID = ?
+ AND ParentOrderLineItemID = 0
+ AND IsDeleted = b'0'
",
[ { value = OrderID, cfsqltype = "cf_sql_integer" } ],
{ datasource = "payfrit" }
@@ -250,9 +250,9 @@
"
UPDATE Orders
SET
- OrderStatusID = 1,
- OrderSubmittedOn = ?,
- OrderLastEditedOn = ?
+ StatusID = 1,
+ SubmittedOn = ?,
+ LastEditedOn = ?
WHERE OrderID = ?
",
[
diff --git a/api/orders/updateStatus.cfm b/api/orders/updateStatus.cfm
index 46a80f8..bfde882 100644
--- a/api/orders/updateStatus.cfm
+++ b/api/orders/updateStatus.cfm
@@ -37,11 +37,11 @@
@@ -49,13 +49,13 @@
-
+
@@ -99,7 +99,7 @@
@@ -107,7 +107,7 @@
-
+
@@ -125,13 +125,13 @@
0) {
// Update to active
queryExecute("
- UPDATE lt_Users_Businesses_Employees
- SET EmployeeIsActive = 1, EmployeeStatusID = 2
+ UPDATE Employees
+ SET IsActive = 1, StatusID = 2
WHERE BusinessID = ? AND UserID = ?
", [
{ value: businessId, cfsqltype: "cf_sql_integer" },
{ value: userId, cfsqltype: "cf_sql_integer" }
], { datasource: "payfrit" });
- apiAbort({ "OK": true, "MESSAGE": "Employee reactivated", "EmployeeID": qCheck.EmployeeID });
+ apiAbort({ "OK": true, "MESSAGE": "Employee reactivated", "EmployeeID": qCheck.ID });
}
// Insert new
- // NOTE: BusinessID in lt_Users_Businesses_Employees is technically redundant since
+ // NOTE: BusinessID in Employees is technically redundant since
// the business relationship is established via ServicePoint -> Beacon chain.
// Kept for legacy/convenience but could be derived from context.
queryExecute("
- INSERT INTO lt_Users_Businesses_Employees (BusinessID, UserID, EmployeeStatusID, EmployeeIsActive)
+ INSERT INTO Employees (BusinessID, UserID, StatusID, IsActive)
VALUES (?, ?, 2, 1)
", [
{ value: businessId, cfsqltype: "cf_sql_integer" },
@@ -67,7 +67,7 @@ try {
qNew = queryExecute("SELECT LAST_INSERT_ID() AS EmployeeID", {}, { datasource: "payfrit" });
- apiAbort({ "OK": true, "MESSAGE": "Team member added", "EmployeeID": qNew.EmployeeID });
+ apiAbort({ "OK": true, "MESSAGE": "Team member added", "EmployeeID": qNew.ID });
} catch (any e) {
apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message });
diff --git a/api/portal/getSettings.cfm b/api/portal/getSettings.cfm
index e6c5211..b128375 100644
--- a/api/portal/getSettings.cfm
+++ b/api/portal/getSettings.cfm
@@ -24,17 +24,12 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) ||
try {
q = queryExecute("
SELECT
- BusinessID,
- BusinessName,
- BusinessTaxRate,
- BusinessAddress,
- BusinessCity,
- BusinessState,
- BusinessZip,
- BusinessContactNumber,
- BusinessEmailAddress
- FROM Businesses
- WHERE BusinessID = :businessId
+ b.ID,
+ b.Name,
+ b.TaxRate,
+ b.Phone
+ FROM Businesses b
+ WHERE b.ID = :businessId
LIMIT 1
", { businessId: request.BusinessID }, { datasource: "payfrit" });
@@ -42,23 +37,52 @@ try {
apiAbort({ OK: false, ERROR: "business_not_found" });
}
+ // Get address from Addresses table
+ qAddr = queryExecute("
+ SELECT a.Line1, a.Line2, a.City, a.ZIPCode, s.Abbreviation AS State
+ FROM Addresses a
+ LEFT JOIN tt_States s ON s.ID = a.StateID
+ WHERE (a.BusinessID = :businessId OR a.ID = (SELECT AddressID FROM Businesses WHERE ID = :businessId))
+ AND a.IsDeleted = 0
+ LIMIT 1
+ ", { businessId: request.BusinessID }, { datasource: "payfrit" });
+
+ addressStr = "";
+ addrCity = "";
+ addrState = "";
+ addrZip = "";
+ if (qAddr.recordCount > 0) {
+ addressStr = qAddr.Line1 ?: "";
+ addrCity = qAddr.City ?: "";
+ addrState = qAddr.State ?: "";
+ addrZip = qAddr.ZIPCode ?: "";
+ }
+
+ // Get owner email from Users table
+ qUser = queryExecute("
+ SELECT ContactNumber, EmailAddress
+ FROM Users
+ WHERE ID = (SELECT UserID FROM Businesses WHERE ID = :businessId)
+ LIMIT 1
+ ", { businessId: request.BusinessID }, { datasource: "payfrit" });
+
// Format tax rate as percentage for display (0.0825 -> 8.25)
- taxRateRaw = isNumeric(q.BusinessTaxRate) ? q.BusinessTaxRate : 0;
+ taxRateRaw = isNumeric(q.TaxRate) ? q.TaxRate : 0;
taxRatePercent = taxRateRaw * 100;
writeOutput(serializeJSON({
"OK": true,
"SETTINGS": {
- "BusinessID": q.BusinessID,
- "BusinessName": q.BusinessName,
+ "BusinessID": q.ID,
+ "Name": q.Name,
"TaxRate": taxRateRaw,
"TaxRatePercent": taxRatePercent,
- "Address": q.BusinessAddress ?: "",
- "City": q.BusinessCity ?: "",
- "State": q.BusinessState ?: "",
- "Zip": q.BusinessZip ?: "",
- "Phone": q.BusinessContactNumber ?: "",
- "Email": q.BusinessEmailAddress ?: ""
+ "Address": addressStr,
+ "City": addrCity,
+ "State": addrState,
+ "Zip": addrZip,
+ "Phone": q.Phone ?: "",
+ "Email": qUser.recordCount > 0 ? (qUser.EmailAddress ?: "") : ""
}
}));
diff --git a/api/portal/myBusinesses.cfm b/api/portal/myBusinesses.cfm
index 45d97d9..aa17c67 100644
--- a/api/portal/myBusinesses.cfm
+++ b/api/portal/myBusinesses.cfm
@@ -43,22 +43,22 @@ try {
}
// Get businesses for this user
- // Users are linked to businesses via BusinessUserID field (owner)
+ // Users are linked to businesses via UserID field (owner)
- q = queryTimed("
+ q = queryExecute("
SELECT
- b.BusinessID,
- b.BusinessName
+ b.ID,
+ b.Name
FROM Businesses b
- WHERE b.BusinessUserID = :userID
- ORDER BY b.BusinessName
+ WHERE b.UserID = :userID
+ ORDER BY b.Name
", { userID: userID }, { datasource: "payfrit" });
businesses = [];
for (row in q) {
arrayAppend(businesses, {
- "BusinessID": row.BusinessID,
- "BusinessName": row.BusinessName
+ "BusinessID": row.ID,
+ "Name": row.Name
});
}
@@ -71,6 +71,5 @@ try {
response["MESSAGE"] = e.message;
}
-logPerf();
writeOutput(serializeJSON(response));
diff --git a/api/portal/reassign_employees.cfm b/api/portal/reassign_employees.cfm
index 4eacb4d..dc6920c 100644
--- a/api/portal/reassign_employees.cfm
+++ b/api/portal/reassign_employees.cfm
@@ -5,12 +5,12 @@
- UPDATE lt_Users_Businesses_Employees
+ UPDATE Employees
SET BusinessID =
- SELECT COUNT(*) AS cnt FROM lt_Users_Businesses_Employees WHERE BusinessID =
+ SELECT COUNT(*) AS cnt FROM Employees WHERE BusinessID =
#serializeJSON({
diff --git a/api/portal/searchUser.cfm b/api/portal/searchUser.cfm
index 8ae6c45..a4634c2 100644
--- a/api/portal/searchUser.cfm
+++ b/api/portal/searchUser.cfm
@@ -41,9 +41,9 @@ try {
// Search by phone - normalize both sides
phoneDigits = normalizePhone(query);
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName, UserContactNumber, UserEmailAddress
+ SELECT ID, FirstName, LastName, ContactNumber, EmailAddress
FROM Users
- WHERE REPLACE(REPLACE(REPLACE(REPLACE(UserContactNumber, '-', ''), ' ', ''), '(', ''), ')', '') LIKE :phone
+ WHERE REPLACE(REPLACE(REPLACE(REPLACE(ContactNumber, '-', ''), ' ', ''), '(', ''), ')', '') LIKE :phone
LIMIT 1
", {
phone: { value: "%" & phoneDigits & "%", cfsqltype: "cf_sql_varchar" }
@@ -51,9 +51,9 @@ try {
} else if (isEmail) {
// Search by email (partial match)
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName, UserContactNumber, UserEmailAddress
+ SELECT ID, FirstName, LastName, ContactNumber, EmailAddress
FROM Users
- WHERE UserEmailAddress LIKE :email
+ WHERE EmailAddress LIKE :email
LIMIT 1
", {
email: { value: "%" & query & "%", cfsqltype: "cf_sql_varchar" }
@@ -61,10 +61,10 @@ try {
} else {
// Search by name
qUser = queryExecute("
- SELECT UserID, UserFirstName, UserLastName, UserContactNumber, UserEmailAddress
+ SELECT ID, FirstName, LastName, ContactNumber, EmailAddress
FROM Users
- WHERE UserFirstName LIKE :name OR UserLastName LIKE :name
- OR CONCAT(UserFirstName, ' ', UserLastName) LIKE :name
+ WHERE FirstName LIKE :name OR LastName LIKE :name
+ OR CONCAT(FirstName, ' ', LastName) LIKE :name
LIMIT 1
", {
name: { value: "%" & query & "%", cfsqltype: "cf_sql_varchar" }
@@ -74,20 +74,20 @@ try {
if (qUser.recordCount > 0) {
// Check if already on team
qTeam = queryExecute("
- SELECT EmployeeID FROM lt_Users_Businesses_Employees
+ SELECT ID FROM Employees
WHERE BusinessID = :bizId AND UserID = :userId
", {
bizId: { value: businessId, cfsqltype: "cf_sql_integer" },
- userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" }
+ userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
apiAbort({
"OK": true,
"USER": {
- "UserID": qUser.UserID,
- "Name": trim(qUser.UserFirstName & " " & qUser.UserLastName),
- "Phone": qUser.UserContactNumber,
- "Email": qUser.UserEmailAddress,
+ "UserID": qUser.ID,
+ "Name": trim(qUser.FirstName & " " & qUser.LastName),
+ "Phone": qUser.ContactNumber,
+ "Email": qUser.EmailAddress,
"AlreadyOnTeam": qTeam.recordCount > 0
}
});
diff --git a/api/portal/stats.cfm b/api/portal/stats.cfm
index 0181805..43c7f30 100644
--- a/api/portal/stats.cfm
+++ b/api/portal/stats.cfm
@@ -36,51 +36,63 @@ try {
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
+ // Orders today count
+ qOrdersToday = queryExecute("
+ SELECT COUNT(*) as cnt
+ FROM Orders
+ WHERE BusinessID = :businessID
+ AND SubmittedOn >= :todayStart
+ AND SubmittedOn <= :todayEnd
", {
businessID: businessID,
todayStart: { value: todayStart, cfsqltype: "cf_sql_varchar" },
todayEnd: { value: todayEnd, cfsqltype: "cf_sql_varchar" }
});
+ // Revenue today (sum of line items)
+ qRevenueToday = queryExecute("
+ SELECT COALESCE(SUM(li.Quantity * li.Price), 0) as total
+ FROM Orders o
+ JOIN OrderLineItems li ON li.OrderID = o.ID
+ WHERE o.BusinessID = :businessID
+ AND o.SubmittedOn >= :todayStart
+ AND o.SubmittedOn <= :todayEnd
+ AND o.StatusID >= 1
+ ", {
+ businessID: businessID,
+ todayStart: { value: todayStart, cfsqltype: "cf_sql_varchar" },
+ todayEnd: { value: todayEnd, cfsqltype: "cf_sql_varchar" }
+ });
+
+ // Pending orders (status 1 = submitted, 2 = preparing)
+ qPendingOrders = queryExecute("
+ SELECT COUNT(*) as cnt
+ FROM Orders
+ WHERE BusinessID = :businessID
+ AND StatusID IN (1, 2)
+ ", { businessID: businessID });
+
+ // Menu items count (active items that have a parent category, excluding categories themselves)
+ // Categories are items with ParentItemID = 0 and IsCollapsible = 0
+ qMenuItems = queryExecute("
+ SELECT COUNT(*) as cnt
+ FROM Items
+ WHERE BusinessID = :businessID
+ AND IsActive = 1
+ AND ParentItemID > 0
+ ", { businessID: businessID });
+
response["OK"] = true;
response["STATS"] = {
- "ordersToday": qStats.ordersToday,
- "revenueToday": qStats.revenueToday,
- "pendingOrders": qStats.pendingOrders,
- "menuItems": qStats.menuItems
+ "ordersToday": qOrdersToday.cnt,
+ "revenueToday": qRevenueToday.total,
+ "pendingOrders": qPendingOrders.cnt,
+ "menuItems": qMenuItems.cnt
};
} catch (any e) {
response["ERROR"] = e.message;
}
-logPerf();
writeOutput(serializeJSON(response));
diff --git a/api/portal/team.cfm b/api/portal/team.cfm
index 147b27f..5b057f2 100644
--- a/api/portal/team.cfm
+++ b/api/portal/team.cfm
@@ -42,25 +42,25 @@ try {
// Cast BIT to INT to avoid binary comparison issues
qTeam = queryExecute("
SELECT
- e.EmployeeID,
+ e.ID,
e.UserID,
- e.EmployeeStatusID,
- CAST(e.EmployeeIsActive AS UNSIGNED) AS EmployeeIsActive,
- u.UserFirstName,
- u.UserLastName,
- u.UserEmailAddress,
- u.UserContactNumber,
- CASE e.EmployeeStatusID
+ e.StatusID,
+ CAST(e.IsActive AS UNSIGNED) AS IsActive,
+ u.FirstName,
+ u.LastName,
+ u.EmailAddress,
+ u.ContactNumber,
+ CASE e.StatusID
WHEN 0 THEN 'Pending'
WHEN 1 THEN 'Invited'
WHEN 2 THEN 'Active'
WHEN 3 THEN 'Suspended'
ELSE 'Unknown'
END AS StatusName
- FROM lt_Users_Businesses_Employees e
- JOIN Users u ON e.UserID = u.UserID
+ FROM Employees e
+ JOIN Users u ON e.UserID = u.ID
WHERE e.BusinessID = ?
- ORDER BY e.EmployeeIsActive DESC, u.UserFirstName ASC
+ ORDER BY e.IsActive DESC, u.FirstName ASC
", [
{ value: businessId, cfsqltype: "cf_sql_integer" }
], { datasource: "payfrit" });
@@ -68,16 +68,16 @@ try {
team = [];
for (row in qTeam) {
arrayAppend(team, {
- "EmployeeID": row.EmployeeID,
+ "EmployeeID": row.ID,
"UserID": row.UserID,
- "Name": trim(row.UserFirstName & " " & row.UserLastName),
- "FirstName": row.UserFirstName,
- "LastName": row.UserLastName,
- "Email": row.UserEmailAddress,
- "Phone": row.UserContactNumber,
- "StatusID": row.EmployeeStatusID,
+ "Name": trim(row.FirstName & " " & row.LastName),
+ "FirstName": row.FirstName,
+ "LastName": row.LastName,
+ "Email": row.EmailAddress,
+ "Phone": row.ContactNumber,
+ "StatusID": row.StatusID,
"StatusName": row.StatusName,
- "IsActive": val(row.EmployeeIsActive) == 1
+ "IsActive": val(row.IsActive) == 1
});
}
diff --git a/api/portal/updateSettings.cfm b/api/portal/updateSettings.cfm
index 33f29a3..ff01f74 100644
--- a/api/portal/updateSettings.cfm
+++ b/api/portal/updateSettings.cfm
@@ -54,95 +54,119 @@ try {
if (taxRate < 0 || taxRate > 0.5) {
apiAbort({ OK: false, ERROR: "invalid_tax_rate", MESSAGE: "Tax rate must be between 0% and 50%" });
}
- arrayAppend(updates, "BusinessTaxRate = :taxRate");
+ arrayAppend(updates, "TaxRate = :taxRate");
params.taxRate = { value: taxRate, cfsqltype: "cf_sql_decimal" };
} else if (structKeyExists(data, "TaxRate") && isNumeric(data.TaxRate)) {
taxRate = data.TaxRate;
if (taxRate < 0 || taxRate > 0.5) {
apiAbort({ OK: false, ERROR: "invalid_tax_rate", MESSAGE: "Tax rate must be between 0 and 0.5" });
}
- arrayAppend(updates, "BusinessTaxRate = :taxRate");
+ arrayAppend(updates, "TaxRate = :taxRate");
params.taxRate = { value: taxRate, cfsqltype: "cf_sql_decimal" };
}
// Add more updatable fields as needed
- if (structKeyExists(data, "BusinessName") && len(trim(data.BusinessName))) {
- arrayAppend(updates, "BusinessName = :businessName");
- params.businessName = { value: left(trim(data.BusinessName), 100), cfsqltype: "cf_sql_varchar" };
- }
-
- if (structKeyExists(data, "Address") && len(trim(data.Address))) {
- arrayAppend(updates, "BusinessAddress = :address");
- params.address = { value: left(trim(data.Address), 255), cfsqltype: "cf_sql_varchar" };
- }
-
- if (structKeyExists(data, "City")) {
- arrayAppend(updates, "BusinessCity = :city");
- params.city = { value: left(trim(data.City), 100), cfsqltype: "cf_sql_varchar" };
- }
-
- if (structKeyExists(data, "State")) {
- arrayAppend(updates, "BusinessState = :state");
- params.state = { value: left(trim(data.State), 2), cfsqltype: "cf_sql_varchar" };
- }
-
- if (structKeyExists(data, "Zip")) {
- arrayAppend(updates, "BusinessZip = :zip");
- params.zip = { value: left(trim(data.Zip), 10), cfsqltype: "cf_sql_varchar" };
+ if (structKeyExists(data, "Name") && len(trim(data.Name))) {
+ arrayAppend(updates, "Name = :businessName");
+ params.businessName = { value: left(trim(data.Name), 100), cfsqltype: "cf_sql_varchar" };
}
if (structKeyExists(data, "Phone")) {
- arrayAppend(updates, "BusinessContactNumber = :phone");
+ arrayAppend(updates, "Phone = :phone");
params.phone = { value: left(trim(data.Phone), 20), cfsqltype: "cf_sql_varchar" };
}
- if (structKeyExists(data, "Email")) {
- arrayAppend(updates, "BusinessEmailAddress = :email");
- params.email = { value: left(trim(data.Email), 100), cfsqltype: "cf_sql_varchar" };
+ // Track whether we need to update address separately
+ hasAddressUpdate = false;
+ addrFields = {};
+ if (structKeyExists(data, "Address") && len(trim(data.Address))) {
+ hasAddressUpdate = true;
+ addrFields.Line1 = left(trim(data.Address), 100);
+ }
+ if (structKeyExists(data, "City")) {
+ hasAddressUpdate = true;
+ addrFields.City = left(trim(data.City), 50);
+ }
+ if (structKeyExists(data, "Zip")) {
+ hasAddressUpdate = true;
+ addrFields.ZIPCode = left(trim(data.Zip), 10);
}
- if (arrayLen(updates) == 0) {
+ if (arrayLen(updates) == 0 && !hasAddressUpdate) {
apiAbort({ OK: false, ERROR: "no_fields", MESSAGE: "No valid fields to update" });
}
- // Build and execute update
- sql = "UPDATE Businesses SET " & arrayToList(updates, ", ") & " WHERE BusinessID = :businessId";
- queryExecute(sql, params, { datasource: "payfrit" });
+ // Build and execute Businesses update
+ if (arrayLen(updates) > 0) {
+ sql = "UPDATE Businesses SET " & arrayToList(updates, ", ") & " WHERE ID = :businessId";
+ queryExecute(sql, params, { datasource: "payfrit" });
+ }
+
+ // Update address in Addresses table if needed
+ if (hasAddressUpdate) {
+ qExistingAddr = queryExecute("
+ SELECT ID FROM Addresses
+ WHERE (BusinessID = :businessId OR ID = (SELECT AddressID FROM Businesses WHERE ID = :businessId))
+ AND IsDeleted = 0
+ LIMIT 1
+ ", { businessId: request.BusinessID }, { datasource: "payfrit" });
+
+ if (qExistingAddr.recordCount > 0) {
+ addrUpdates = [];
+ addrParams = { addrId: qExistingAddr.ID };
+ if (structKeyExists(addrFields, "Line1")) {
+ arrayAppend(addrUpdates, "Line1 = :line1");
+ addrParams.line1 = { value: addrFields.Line1, cfsqltype: "cf_sql_varchar" };
+ }
+ if (structKeyExists(addrFields, "City")) {
+ arrayAppend(addrUpdates, "City = :city");
+ addrParams.city = { value: addrFields.City, cfsqltype: "cf_sql_varchar" };
+ }
+ if (structKeyExists(addrFields, "ZIPCode")) {
+ arrayAppend(addrUpdates, "ZIPCode = :zip");
+ addrParams.zip = { value: addrFields.ZIPCode, cfsqltype: "cf_sql_varchar" };
+ }
+ if (arrayLen(addrUpdates) > 0) {
+ queryExecute("UPDATE Addresses SET " & arrayToList(addrUpdates, ", ") & " WHERE ID = :addrId",
+ addrParams, { datasource: "payfrit" });
+ }
+ }
+ }
// Return updated settings
q = queryExecute("
- SELECT
- BusinessID,
- BusinessName,
- BusinessTaxRate,
- BusinessAddress,
- BusinessCity,
- BusinessState,
- BusinessZip,
- BusinessContactNumber,
- BusinessEmailAddress
- FROM Businesses
- WHERE BusinessID = :businessId
+ SELECT b.ID, b.Name, b.TaxRate, b.Phone
+ FROM Businesses b
+ WHERE b.ID = :businessId
LIMIT 1
", { businessId: request.BusinessID }, { datasource: "payfrit" });
- taxRateRaw = isNumeric(q.BusinessTaxRate) ? q.BusinessTaxRate : 0;
+ qAddr = queryExecute("
+ SELECT a.Line1, a.City, a.ZIPCode, s.Abbreviation AS State
+ FROM Addresses a
+ LEFT JOIN tt_States s ON s.ID = a.StateID
+ WHERE (a.BusinessID = :businessId OR a.ID = (SELECT AddressID FROM Businesses WHERE ID = :businessId))
+ AND a.IsDeleted = 0
+ LIMIT 1
+ ", { businessId: request.BusinessID }, { datasource: "payfrit" });
+
+ taxRateRaw = isNumeric(q.TaxRate) ? q.TaxRate : 0;
taxRatePercent = taxRateRaw * 100;
writeOutput(serializeJSON({
"OK": true,
"MESSAGE": "Settings updated",
"SETTINGS": {
- "BusinessID": q.BusinessID,
- "BusinessName": q.BusinessName,
+ "BusinessID": q.ID,
+ "Name": q.Name,
"TaxRate": taxRateRaw,
"TaxRatePercent": taxRatePercent,
- "Address": q.BusinessAddress ?: "",
- "City": q.BusinessCity ?: "",
- "State": q.BusinessState ?: "",
- "Zip": q.BusinessZip ?: "",
- "Phone": q.BusinessContactNumber ?: "",
- "Email": q.BusinessEmailAddress ?: ""
+ "Address": qAddr.recordCount > 0 ? (qAddr.Line1 ?: "") : "",
+ "City": qAddr.recordCount > 0 ? (qAddr.City ?: "") : "",
+ "State": qAddr.recordCount > 0 ? (qAddr.State ?: "") : "",
+ "Zip": qAddr.recordCount > 0 ? (qAddr.ZIPCode ?: "") : "",
+ "Phone": q.Phone ?: "",
+ "Email": ""
}
}));
diff --git a/api/ratings/createAdminRating.cfm b/api/ratings/createAdminRating.cfm
index d52face..6511424 100644
--- a/api/ratings/createAdminRating.cfm
+++ b/api/ratings/createAdminRating.cfm
@@ -46,9 +46,9 @@ try {
// Verify task exists and is completed
qTask = queryExecute("
- SELECT t.TaskID, t.TaskClaimedByUserID, t.TaskCompletedOn, t.TaskBusinessID
+ SELECT t.ID, t.ClaimedByUserID, t.CompletedOn, t.BusinessID
FROM Tasks t
- WHERE t.TaskID = :taskID
+ WHERE t.ID = :taskID
", { taskID: taskID });
if (qTask.recordCount == 0) {
@@ -56,12 +56,12 @@ try {
abort;
}
- if (len(trim(qTask.TaskCompletedOn)) == 0) {
+ if (len(trim(qTask.CompletedOn)) == 0) {
writeOutput(serializeJSON({ "OK": false, "ERROR": "not_completed", "MESSAGE": "Task has not been completed yet." }));
abort;
}
- workerUserID = qTask.TaskClaimedByUserID;
+ workerUserID = qTask.ClaimedByUserID;
if (workerUserID == 0) {
writeOutput(serializeJSON({ "OK": false, "ERROR": "no_worker", "MESSAGE": "No worker assigned to this task." }));
abort;
@@ -70,8 +70,8 @@ try {
// Check if admin rating already exists for this task
qExisting = queryExecute("
SELECT TaskRatingID FROM TaskRatings
- WHERE TaskRatingTaskID = :taskID
- AND TaskRatingDirection = 'admin_rates_worker'
+ WHERE TaskID = :taskID
+ AND Direction = 'admin_rates_worker'
LIMIT 1
", { taskID: taskID });
@@ -84,9 +84,9 @@ try {
token = generateToken();
queryExecute("
INSERT INTO TaskRatings (
- TaskRatingTaskID, TaskRatingByUserID, TaskRatingForUserID, TaskRatingDirection,
- TaskRatingOnTime, TaskRatingCompletedScope, TaskRatingRequiredFollowup, TaskRatingContinueAllow,
- TaskRatingAccessToken, TaskRatingExpiresOn, TaskRatingCompletedOn
+ TaskID, ByUserID, ForUserID, Direction,
+ OnTime, CompletedScope, RequiredFollowup, ContinueAllow,
+ AccessToken, ExpiresOn, CompletedOn
) VALUES (
:taskID, :adminUserID, :workerUserID, 'admin_rates_worker',
:onTime, :completedScope, :requiredFollowup, :continueAllow,
diff --git a/api/ratings/listForAdmin.cfm b/api/ratings/listForAdmin.cfm
index 0270c53..7c8cf46 100644
--- a/api/ratings/listForAdmin.cfm
+++ b/api/ratings/listForAdmin.cfm
@@ -31,32 +31,32 @@ try {
// Get completed tasks from last 7 days where a worker was assigned
// and no admin rating exists yet
qTasks = queryExecute("
- SELECT t.TaskID, t.TaskTitle, t.TaskCompletedOn, t.TaskClaimedByUserID, t.TaskOrderID,
- u.UserFirstName AS WorkerFirstName, u.UserLastName AS WorkerLastName,
- o.OrderID, o.OrderUserID,
- cu.UserFirstName AS CustomerFirstName, cu.UserLastName AS CustomerLastName,
- sp.ServicePointName,
+ SELECT t.ID, t.Title, t.CompletedOn, t.ClaimedByUserID, t.OrderID,
+ u.FirstName AS WorkerFirstName, u.LastName AS WorkerLastName,
+ o.ID, o.UserID,
+ cu.FirstName AS CustomerFirstName, cu.LastName AS CustomerLastName,
+ sp.Name,
(SELECT COUNT(*) FROM TaskRatings r
- WHERE r.TaskRatingTaskID = t.TaskID
- AND r.TaskRatingDirection = 'admin_rates_worker') AS HasAdminRating
+ WHERE r.TaskID = t.ID
+ AND r.Direction = 'admin_rates_worker') AS HasAdminRating
FROM Tasks t
- INNER JOIN Users u ON u.UserID = t.TaskClaimedByUserID
- LEFT JOIN Orders o ON o.OrderID = t.TaskOrderID
- LEFT JOIN Users cu ON cu.UserID = o.OrderUserID
- LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
- WHERE t.TaskBusinessID = :businessID
- AND t.TaskCompletedOn IS NOT NULL
- AND t.TaskCompletedOn > DATE_SUB(NOW(), INTERVAL 7 DAY)
- AND t.TaskClaimedByUserID > 0
+ INNER JOIN Users u ON u.ID = t.ClaimedByUserID
+ LEFT JOIN Orders o ON o.ID = t.OrderID
+ LEFT JOIN Users cu ON cu.ID = o.UserID
+ LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
+ WHERE t.BusinessID = :businessID
+ AND t.CompletedOn IS NOT NULL
+ AND t.CompletedOn > DATE_SUB(NOW(), INTERVAL 7 DAY)
+ AND t.ClaimedByUserID > 0
HAVING HasAdminRating = 0
- ORDER BY t.TaskCompletedOn DESC
+ ORDER BY t.CompletedOn DESC
LIMIT 50
", { businessID: businessID });
tasks = [];
for (row in qTasks) {
// Build task title
- taskTitle = row.TaskTitle;
+ taskTitle = row.Title;
if (len(taskTitle) == 0 && row.OrderID > 0) {
taskTitle = "Order ##" & row.OrderID;
}
@@ -66,12 +66,12 @@ try {
arrayAppend(tasks, {
"TaskID": row.TaskID,
- "TaskTitle": taskTitle,
- "CompletedOn": dateTimeFormat(row.TaskCompletedOn, "yyyy-mm-dd HH:nn:ss"),
- "WorkerUserID": row.TaskClaimedByUserID,
+ "Title": taskTitle,
+ "CompletedOn": dateTimeFormat(row.CompletedOn, "yyyy-mm-dd HH:nn:ss"),
+ "WorkerUserID": row.ClaimedByUserID,
"WorkerName": trim(row.WorkerFirstName & " " & row.WorkerLastName),
"CustomerName": len(row.CustomerFirstName) ? trim(row.CustomerFirstName & " " & row.CustomerLastName) : "",
- "ServicePointName": row.ServicePointName ?: "",
+ "Name": row.Name ?: "",
"OrderID": row.OrderID ?: 0
});
}
diff --git a/api/ratings/setup.cfm b/api/ratings/setup.cfm
index 8edfe6a..018b46c 100644
--- a/api/ratings/setup.cfm
+++ b/api/ratings/setup.cfm
@@ -5,36 +5,36 @@ try {
// Create TaskRatings table
queryExecute("
CREATE TABLE IF NOT EXISTS TaskRatings (
- TaskRatingID INT AUTO_INCREMENT PRIMARY KEY,
- TaskRatingTaskID INT NOT NULL,
+ ID INT AUTO_INCREMENT PRIMARY KEY,
+ TaskID INT NOT NULL,
- TaskRatingByUserID INT NOT NULL,
- TaskRatingForUserID INT NOT NULL,
- TaskRatingDirection VARCHAR(25) NOT NULL,
+ ByUserID INT NOT NULL,
+ ForUserID INT NOT NULL,
+ Direction VARCHAR(25) NOT NULL,
-- Customer/Admin rates Worker
- TaskRatingOnTime TINYINT(1) NULL,
- TaskRatingCompletedScope TINYINT(1) NULL,
- TaskRatingRequiredFollowup TINYINT(1) NULL,
- TaskRatingContinueAllow TINYINT(1) NULL,
+ OnTime TINYINT(1) NULL,
+ CompletedScope TINYINT(1) NULL,
+ RequiredFollowup TINYINT(1) NULL,
+ ContinueAllow TINYINT(1) NULL,
-- Worker rates Customer
- TaskRatingPrepared TINYINT(1) NULL,
- TaskRatingRespectful TINYINT(1) NULL,
- TaskRatingWouldAutoAssign TINYINT(1) NULL,
+ Prepared TINYINT(1) NULL,
+ Respectful TINYINT(1) NULL,
+ WouldAutoAssign TINYINT(1) NULL,
-- For rating links in receipts
- TaskRatingAccessToken VARCHAR(64) NOT NULL UNIQUE,
- TaskRatingExpiresOn DATETIME NOT NULL,
+ AccessToken VARCHAR(64) NOT NULL UNIQUE,
+ ExpiresOn DATETIME NOT NULL,
-- Timestamps
- TaskRatingCreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP,
- TaskRatingCompletedOn DATETIME NULL,
+ CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP,
+ CompletedOn DATETIME NULL,
- INDEX idx_task (TaskRatingTaskID),
- INDEX idx_for_user (TaskRatingForUserID),
- INDEX idx_by_user (TaskRatingByUserID),
- INDEX idx_token (TaskRatingAccessToken)
+ INDEX idx_task (TaskID),
+ INDEX idx_for_user (ForUserID),
+ INDEX idx_by_user (ByUserID),
+ INDEX idx_token (AccessToken)
)
", {}, { datasource: "payfrit" });
diff --git a/api/ratings/submit.cfm b/api/ratings/submit.cfm
index 22ace82..54b6a81 100644
--- a/api/ratings/submit.cfm
+++ b/api/ratings/submit.cfm
@@ -27,14 +27,14 @@ try {
// Look up the rating by token
qRating = queryExecute("
- SELECT r.*, t.TaskTitle,
- u_for.UserFirstName AS ForUserFirstName, u_for.UserLastName AS ForUserLastName,
- u_by.UserFirstName AS ByUserFirstName, u_by.UserLastName AS ByUserLastName
+ SELECT r.*, t.Title,
+ u_for.FirstName AS ForFirstName, u_for.LastName AS ForLastName,
+ u_by.FirstName AS ByFirstName, u_by.LastName AS ByLastName
FROM TaskRatings r
- JOIN Tasks t ON t.TaskID = r.TaskRatingTaskID
- LEFT JOIN Users u_for ON u_for.UserID = r.TaskRatingForUserID
- LEFT JOIN Users u_by ON u_by.UserID = r.TaskRatingByUserID
- WHERE r.TaskRatingAccessToken = ?
+ JOIN Tasks t ON t.ID = r.TaskID
+ LEFT JOIN Users u_for ON u_for.ID = r.ForUserID
+ LEFT JOIN Users u_by ON u_by.ID = r.ByUserID
+ WHERE r.AccessToken = ?
LIMIT 1
", [{ value = token, cfsqltype = "cf_sql_varchar" }]);
@@ -44,13 +44,13 @@ try {
}
// Check if expired
- if (qRating.TaskRatingExpiresOn < now()) {
+ if (qRating.ExpiresOn < now()) {
writeOutput(serializeJSON({ "OK": false, "ERROR": "expired", "MESSAGE": "This rating link has expired." }));
abort;
}
// Check if already completed
- if (len(trim(qRating.TaskRatingCompletedOn)) > 0) {
+ if (len(trim(qRating.CompletedOn)) > 0) {
writeOutput(serializeJSON({ "OK": false, "ERROR": "already_submitted", "MESSAGE": "This rating has already been submitted." }));
abort;
}
@@ -65,22 +65,22 @@ try {
// Return rating details for UI to display
result = {
"OK": true,
- "RatingID": qRating.TaskRatingID,
- "Direction": qRating.TaskRatingDirection,
- "TaskTitle": qRating.TaskTitle,
- "ForUserName": trim(qRating.ForUserFirstName & " " & qRating.ForUserLastName),
- "ExpiresOn": dateTimeFormat(qRating.TaskRatingExpiresOn, "yyyy-mm-dd HH:nn:ss")
+ "RatingID": qRating.ID,
+ "Direction": qRating.Direction,
+ "Title": qRating.Title,
+ "ForUserName": trim(qRating.ForFirstName & " " & qRating.ForLastName),
+ "ExpiresOn": dateTimeFormat(qRating.ExpiresOn, "yyyy-mm-dd HH:nn:ss")
};
// Include appropriate questions based on direction
- if (qRating.TaskRatingDirection == "customer_rates_worker" || qRating.TaskRatingDirection == "admin_rates_worker") {
+ if (qRating.Direction == "customer_rates_worker" || qRating.Direction == "admin_rates_worker") {
result["Questions"] = {
"onTime": "Was the worker on time?",
"completedScope": "Was the scope completed?",
"requiredFollowup": "Was follow-up required?",
"continueAllow": "Continue to allow these tasks?"
};
- } else if (qRating.TaskRatingDirection == "worker_rates_customer") {
+ } else if (qRating.Direction == "worker_rates_customer") {
result["Questions"] = {
"prepared": "Was the customer prepared?",
"completedScope": "Was the scope clear?",
@@ -94,37 +94,37 @@ try {
}
// Process submission based on direction
- if (qRating.TaskRatingDirection == "customer_rates_worker" || qRating.TaskRatingDirection == "admin_rates_worker") {
+ if (qRating.Direction == "customer_rates_worker" || qRating.Direction == "admin_rates_worker") {
queryExecute("
UPDATE TaskRatings SET
- TaskRatingOnTime = ?,
- TaskRatingCompletedScope = ?,
- TaskRatingRequiredFollowup = ?,
- TaskRatingContinueAllow = ?,
- TaskRatingCompletedOn = NOW()
- WHERE TaskRatingID = ?
+ OnTime = ?,
+ CompletedScope = ?,
+ RequiredFollowup = ?,
+ ContinueAllow = ?,
+ CompletedOn = NOW()
+ WHERE ID = ?
", [
{ value = structKeyExists(data,"onTime") ? (data.onTime ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"onTime") },
{ value = structKeyExists(data,"completedScope") ? (data.completedScope ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"completedScope") },
{ value = structKeyExists(data,"requiredFollowup") ? (data.requiredFollowup ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"requiredFollowup") },
{ value = structKeyExists(data,"continueAllow") ? (data.continueAllow ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"continueAllow") },
- { value = qRating.TaskRatingID, cfsqltype = "cf_sql_integer" }
+ { value = qRating.ID, cfsqltype = "cf_sql_integer" }
]);
- } else if (qRating.TaskRatingDirection == "worker_rates_customer") {
+ } else if (qRating.Direction == "worker_rates_customer") {
queryExecute("
UPDATE TaskRatings SET
- TaskRatingPrepared = ?,
- TaskRatingCompletedScope = ?,
- TaskRatingRespectful = ?,
- TaskRatingWouldAutoAssign = ?,
- TaskRatingCompletedOn = NOW()
- WHERE TaskRatingID = ?
+ Prepared = ?,
+ CompletedScope = ?,
+ Respectful = ?,
+ WouldAutoAssign = ?,
+ CompletedOn = NOW()
+ WHERE ID = ?
", [
{ value = structKeyExists(data,"prepared") ? (data.prepared ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"prepared") },
{ value = structKeyExists(data,"completedScope") ? (data.completedScope ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"completedScope") },
{ value = structKeyExists(data,"respectful") ? (data.respectful ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"respectful") },
{ value = structKeyExists(data,"wouldAutoAssign") ? (data.wouldAutoAssign ? 1 : 0) : javaCast("null",""), cfsqltype = "cf_sql_tinyint", null = !structKeyExists(data,"wouldAutoAssign") },
- { value = qRating.TaskRatingID, cfsqltype = "cf_sql_integer" }
+ { value = qRating.ID, cfsqltype = "cf_sql_integer" }
]);
}
diff --git a/api/servicepoints/delete.cfm b/api/servicepoints/delete.cfm
index 3638d9c..2b2c8e2 100644
--- a/api/servicepoints/delete.cfm
+++ b/api/servicepoints/delete.cfm
@@ -49,17 +49,17 @@ servicePointId = int(data.ServicePointID);
UPDATE ServicePoints
- SET ServicePointIsActive = 0
+ SET IsActive = 0
WHERE ServicePointID =
- AND ServicePointBusinessID =
+ AND BusinessID =
- SELECT ServicePointID, ServicePointIsActive
+ SELECT ID, IsActive
FROM ServicePoints
- WHERE ServicePointID =
- AND ServicePointBusinessID =
+ WHERE ID =
+ AND BusinessID =
LIMIT 1
diff --git a/api/servicepoints/get.cfm b/api/servicepoints/get.cfm
index fd54b7c..6808a37 100644
--- a/api/servicepoints/get.cfm
+++ b/api/servicepoints/get.cfm
@@ -37,16 +37,16 @@ servicePointId = int(data.ServicePointID);
SELECT
- ServicePointID,
- ServicePointBusinessID,
- ServicePointName,
- ServicePointCode,
- ServicePointTypeID,
- ServicePointIsActive,
+ ID,
+ BusinessID,
+ Name,
+ Code,
+ TypeID,
+ IsActive,
SortOrder
FROM ServicePoints
- WHERE ServicePointID =
- AND ServicePointBusinessID =
+ WHERE ID =
+ AND BusinessID =
LIMIT 1
@@ -56,12 +56,12 @@ servicePointId = int(data.ServicePointID);
diff --git a/api/servicepoints/list.cfm b/api/servicepoints/list.cfm
index f8e6f5f..eb13235 100644
--- a/api/servicepoints/list.cfm
+++ b/api/servicepoints/list.cfm
@@ -57,31 +57,31 @@ if (structKeyExists(data, "onlyActive")) {
SELECT
- ServicePointID,
- ServicePointName,
- ServicePointTypeID,
- ServicePointCode,
- ServicePointDescription,
- ServicePointSortOrder,
- ServicePointIsActive
+ ID,
+ Name,
+ TypeID,
+ Code,
+ Description,
+ SortOrder,
+ IsActive
FROM ServicePoints
- WHERE ServicePointBusinessID =
+ WHERE BusinessID =
- AND ServicePointIsActive = 1
+ AND IsActive = 1
- ORDER BY ServicePointSortOrder, ServicePointName
+ ORDER BY SortOrder, Name
diff --git a/api/servicepoints/reassign_all.cfm b/api/servicepoints/reassign_all.cfm
index 34cde69..ff50a49 100644
--- a/api/servicepoints/reassign_all.cfm
+++ b/api/servicepoints/reassign_all.cfm
@@ -7,11 +7,11 @@
UPDATE ServicePoints
- SET ServicePointBusinessID =
+ SET BusinessID =
- SELECT COUNT(*) AS cnt FROM ServicePoints WHERE ServicePointBusinessID =
+ SELECT COUNT(*) AS cnt FROM ServicePoints WHERE BusinessID =
#serializeJSON({ "OK": true, "MESSAGE": "All service points reassigned to BusinessID #targetBusinessID#", "COUNT": qCount.cnt })#
diff --git a/api/servicepoints/save.cfm b/api/servicepoints/save.cfm
index 29a818b..ebf8069 100644
--- a/api/servicepoints/save.cfm
+++ b/api/servicepoints/save.cfm
@@ -34,8 +34,8 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) ||
apiAbort({ OK=false, ERROR="no_business_selected" });
}
-if (!structKeyExists(data, "ServicePointName") || len(normStr(data.ServicePointName)) EQ 0) {
- apiAbort({ OK=false, ERROR="missing_name", MESSAGE="ServicePointName is required" });
+if (!structKeyExists(data, "Name") || len(normStr(data.Name)) EQ 0) {
+ apiAbort({ OK=false, ERROR="missing_name", MESSAGE="Name is required" });
}
servicePointId = 0;
@@ -43,10 +43,10 @@ if (structKeyExists(data, "ServicePointID") && isNumeric(data.ServicePointID) &&
servicePointId = int(data.ServicePointID);
}
-spName = normStr(data.ServicePointName);
-spCode = structKeyExists(data, "ServicePointCode") ? normStr(data.ServicePointCode) : "";
-spTypeID = structKeyExists(data, "ServicePointTypeID") && isNumeric(data.ServicePointTypeID) ? int(data.ServicePointTypeID) : 1;
-sortOrder = structKeyExists(data, "ServicePointSortOrder") && isNumeric(data.ServicePointSortOrder) ? int(data.ServicePointSortOrder) : 0;
+spName = normStr(data.Name);
+spCode = structKeyExists(data, "Code") ? normStr(data.Code) : "";
+spTypeID = structKeyExists(data, "TypeID") && isNumeric(data.TypeID) ? int(data.TypeID) : 1;
+sortOrder = structKeyExists(data, "SortOrder") && isNumeric(data.SortOrder) ? int(data.SortOrder) : 0;
isActive = 1;
if (structKeyExists(data, "IsActive")) {
@@ -61,21 +61,21 @@ if (structKeyExists(data, "IsActive")) {
UPDATE ServicePoints
SET
- ServicePointName = ,
- ServicePointCode = ,
- ServicePointTypeID = ,
- ServicePointIsActive = ,
- ServicePointSortOrder =
+ Name = ,
+ Code = ,
+ TypeID = ,
+ IsActive = ,
+ SortOrder =
WHERE ServicePointID =
- AND ServicePointBusinessID =
+ AND BusinessID =
- SELECT ServicePointID
+ SELECT ID
FROM ServicePoints
- WHERE ServicePointID =
- AND ServicePointBusinessID =
+ WHERE ID =
+ AND BusinessID =
LIMIT 1
@@ -88,12 +88,12 @@ if (structKeyExists(data, "IsActive")) {
INSERT INTO ServicePoints (
- ServicePointBusinessID,
- ServicePointName,
- ServicePointCode,
- ServicePointTypeID,
- ServicePointIsActive,
- ServicePointSortOrder
+ BusinessID,
+ Name,
+ Code,
+ TypeID,
+ IsActive,
+ SortOrder
) VALUES (
,
,
@@ -113,27 +113,27 @@ if (structKeyExists(data, "IsActive")) {
SELECT
- ServicePointID,
- ServicePointBusinessID,
- ServicePointName,
- ServicePointCode,
- ServicePointTypeID,
- ServicePointIsActive,
- ServicePointSortOrder
+ ID,
+ BusinessID,
+ Name,
+ Code,
+ TypeID,
+ IsActive,
+ SortOrder
FROM ServicePoints
- WHERE ServicePointID =
- AND ServicePointBusinessID =
+ WHERE ID =
+ AND BusinessID =
LIMIT 1
#serializeJSON({ OK=true, ERROR="", SERVICEPOINT=servicePoint })#
diff --git a/api/setup/checkDuplicate.cfm b/api/setup/checkDuplicate.cfm
index 1a69d06..fdb1a09 100644
--- a/api/setup/checkDuplicate.cfm
+++ b/api/setup/checkDuplicate.cfm
@@ -18,7 +18,7 @@
* Returns:
* {
* "OK": true,
- * "duplicates": [ { BusinessID, BusinessName, Address } ]
+ * "duplicates": [ { BusinessID, Name, Address } ]
* }
*/
@@ -45,24 +45,24 @@ try {
// Match by name (case-insensitive) OR by address components
qDuplicates = queryExecute("
SELECT DISTINCT
- b.BusinessID,
- b.BusinessName,
- a.AddressLine1,
- a.AddressCity,
- s.tt_StateAbbreviation as AddressState,
- a.AddressZIPCode
+ b.ID,
+ b.Name,
+ a.Line1,
+ a.City,
+ s.Abbreviation as AddressState,
+ a.ZIPCode
FROM Businesses b
- LEFT JOIN Addresses a ON a.AddressBusinessID = b.BusinessID
- LEFT JOIN tt_States s ON s.tt_StateID = a.AddressStateID
+ LEFT JOIN Addresses a ON a.BusinessID = b.ID
+ LEFT JOIN tt_States s ON s.ID = a.StateID
WHERE
- LOWER(b.BusinessName) = LOWER(:bizName)
+ LOWER(b.Name) = LOWER(:bizName)
OR (
- LOWER(a.AddressLine1) = LOWER(:addressLine1)
- AND LOWER(a.AddressCity) = LOWER(:city)
- AND a.AddressLine1 != ''
- AND a.AddressCity != ''
+ LOWER(a.Line1) = LOWER(:addressLine1)
+ AND LOWER(a.City) = LOWER(:city)
+ AND a.Line1 != ''
+ AND a.City != ''
)
- ORDER BY b.BusinessName
+ ORDER BY b.Name
", {
bizName: bizName,
addressLine1: addressLine1,
@@ -71,14 +71,14 @@ try {
for (i = 1; i <= qDuplicates.recordCount; i++) {
addressParts = [];
- if (len(qDuplicates.AddressLine1[i])) arrayAppend(addressParts, qDuplicates.AddressLine1[i]);
- if (len(qDuplicates.AddressCity[i])) arrayAppend(addressParts, qDuplicates.AddressCity[i]);
+ if (len(qDuplicates.Line1[i])) arrayAppend(addressParts, qDuplicates.Line1[i]);
+ if (len(qDuplicates.City[i])) arrayAppend(addressParts, qDuplicates.City[i]);
if (len(qDuplicates.AddressState[i])) arrayAppend(addressParts, qDuplicates.AddressState[i]);
- if (len(qDuplicates.AddressZIPCode[i])) arrayAppend(addressParts, qDuplicates.AddressZIPCode[i]);
+ if (len(qDuplicates.ZIPCode[i])) arrayAppend(addressParts, qDuplicates.ZIPCode[i]);
arrayAppend(response.duplicates, {
"BusinessID": qDuplicates.BusinessID[i],
- "BusinessName": qDuplicates.BusinessName[i],
+ "Name": qDuplicates.Name[i],
"Address": arrayToList(addressParts, ", ")
});
}
diff --git a/api/setup/importBusiness.cfm b/api/setup/importBusiness.cfm
index 0f05ba0..460933d 100644
--- a/api/setup/importBusiness.cfm
+++ b/api/setup/importBusiness.cfm
@@ -11,7 +11,7 @@
* - Business record with contact info
* - Categories as Items (ParentID=0)
* - Menu items as children of categories
- * - Modifier templates linked via ItemTemplateLinks
+ * - Modifier templates linked via lt_ItemID_TemplateItemID
* - Modifier options as children of templates
*
* POST JSON structure:
@@ -93,7 +93,7 @@ try {
response.steps.append("Step 1: Creating business record...");
qCheck = queryExecute("
- SELECT BusinessID FROM Businesses WHERE BusinessName = :name
+ SELECT ID FROM Businesses WHERE Name = :name
", { name: biz.name }, { datasource: "payfrit" });
if (qCheck.recordCount > 0) {
@@ -102,7 +102,7 @@ try {
response.warnings.append("Existing business found - will add to existing menu");
} else if (!dryRun) {
queryExecute("
- INSERT INTO Businesses (BusinessName, BusinessUserID, BusinessAddressID, BusinessDeliveryZipCodes, BusinessAddedOn) VALUES (:name, :ownerID, 0, '', NOW())
+ INSERT INTO Businesses (Name, UserID, AddressID, BusinessDeliveryZipCodes, AddedOn) VALUES (:name, :ownerID, 0, '', NOW())
", {
name: biz.name, ownerID: ownerUserID
}, { datasource: "payfrit" });
@@ -130,23 +130,23 @@ try {
if (!dryRun) {
// Check if template already exists for this business
qTmpl = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizID
- AND ItemName = :name
- AND ItemParentItemID = 0
- AND ItemID IN (SELECT TemplateItemID FROM ItemTemplateLinks)
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizID
+ AND Name = :name
+ AND ParentItemID = 0
+ AND ItemID IN (SELECT TemplateItemID FROM lt_ItemID_TemplateItemID)
", { bizID: BusinessID, name: templateName }, { datasource: "payfrit" });
if (qTmpl.recordCount > 0) {
templateItemID = qTmpl.ItemID;
response.steps.append("Template exists: " & templateName & " (ID: " & templateItemID & ")");
} else {
- // Create template as Item at ParentID=0, with ItemIsCollapsible=1 to mark it as a template
+ // Create template as Item at ParentID=0, with IsCollapsible=1 to mark it as a template
// This ensures the API filter excludes it from categories
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemRequiresChildSelection, ItemMaxNumSelectionReq, ItemSortOrder, ItemIsCollapsible
+ BusinessID, Name, ParentItemID, Price,
+ IsActive, RequiresChildSelection, MaxNumSelectionReq, SortOrder, IsCollapsible
) VALUES (
:bizID, :name, 0, 0, 1, :required, :maxSelect, 0, 1
)
@@ -173,15 +173,15 @@ try {
optDefault = structKeyExists(opt, "isDefault") && opt.isDefault == true;
qOpt = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizID AND ItemName = :name AND ItemParentItemID = :parentID
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizID AND Name = :name AND ParentItemID = :parentID
", { bizID: BusinessID, name: optName, parentID: templateItemID }, { datasource: "payfrit" });
if (qOpt.recordCount == 0) {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemIsCheckedByDefault, ItemSortOrder
+ BusinessID, Name, ParentItemID, Price,
+ IsActive, IsCheckedByDefault, SortOrder
) VALUES (
:bizID, :name, :parentID, :price, 1, :isDefault, :sortOrder
)
@@ -215,11 +215,11 @@ try {
if (!dryRun) {
// Check if category exists (Item at ParentID=0, not a template)
qCat = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizID
- AND ItemName = :name
- AND ItemParentItemID = 0
- AND ItemID NOT IN (SELECT TemplateItemID FROM ItemTemplateLinks)
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizID
+ AND Name = :name
+ AND ParentItemID = 0
+ AND ItemID NOT IN (SELECT TemplateItemID FROM lt_ItemID_TemplateItemID)
", { bizID: BusinessID, name: catName }, { datasource: "payfrit" });
if (qCat.recordCount > 0) {
@@ -228,8 +228,8 @@ try {
} else {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemSortOrder
+ BusinessID, Name, ParentItemID, Price,
+ IsActive, SortOrder
) VALUES (
:bizID, :name, 0, 0, 1, :sortOrder
)
@@ -272,17 +272,17 @@ try {
if (!dryRun) {
// Check if item exists
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizID AND ItemName = :name AND ItemParentItemID = :parentID
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizID AND Name = :name AND ParentItemID = :parentID
", { bizID: BusinessID, name: itemName, parentID: categoryItemID }, { datasource: "payfrit" });
if (qItem.recordCount > 0) {
- menuItemID = qItem.ItemID;
+ menuItemID = qItem.ID;
} else {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemDescription, ItemParentItemID,
- ItemPrice, ItemIsActive, ItemSortOrder
+ BusinessID, Name, Description, ParentItemID,
+ Price, IsActive, SortOrder
) VALUES (
:bizID, :name, :desc, :parentID, :price, 1, :sortOrder
)
@@ -308,13 +308,13 @@ try {
// Check if link exists
qLink = queryExecute("
- SELECT 1 FROM ItemTemplateLinks
+ SELECT 1 FROM lt_ItemID_TemplateItemID
WHERE ItemID = :itemID AND TemplateItemID = :templateID
", { itemID: menuItemID, templateID: templateItemID }, { datasource: "payfrit" });
if (qLink.recordCount == 0) {
queryExecute("
- INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
+ INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
VALUES (:itemID, :templateID, :sortOrder)
", {
itemID: menuItemID,
diff --git a/api/setup/reimportBigDeans.cfm b/api/setup/reimportBigDeans.cfm
index 24ea666..6dfe0e8 100644
--- a/api/setup/reimportBigDeans.cfm
+++ b/api/setup/reimportBigDeans.cfm
@@ -16,9 +16,9 @@ actions = [];
// ============================================================
if (!dryRun) {
// Delete template links first
- queryExecute("DELETE FROM ItemTemplateLinks WHERE ItemID IN (SELECT ItemID FROM Items WHERE ItemBusinessID = :bizId)", { bizId: bizId });
+ queryExecute("DELETE FROM lt_ItemID_TemplateItemID WHERE ItemID IN (SELECT ID FROM Items WHERE BusinessID = :bizId)", { bizId: bizId });
// Delete all items
- queryExecute("DELETE FROM Items WHERE ItemBusinessID = :bizId", { bizId: bizId });
+ queryExecute("DELETE FROM Items WHERE BusinessID = :bizId", { bizId: bizId });
}
arrayAppend(actions, { step: "CLEAR", message: dryRun ? "Would clear existing data" : "Cleared existing data" });
@@ -29,11 +29,11 @@ arrayAppend(actions, { step: "CLEAR", message: dryRun ? "Would clear existing da
// Helper function to insert item and return ID
function insertItem(name, description, parentId, price, isActive, isCheckedByDefault, requiresChild, maxSelections, isCollapsible, sortOrder) {
if (dryRun) return 0;
- // Note: ItemIsActive is BIT(1) type, use b'1' or b'0' syntax
+ // Note: IsActive is BIT(1) type, use b'1' or b'0' syntax
queryExecute("
- INSERT INTO Items (ItemBusinessID, ItemName, ItemDescription, ItemParentItemID, ItemPrice,
- ItemIsActive, ItemIsCheckedByDefault, ItemRequiresChildSelection,
- ItemMaxNumSelectionReq, ItemIsCollapsible, ItemSortOrder, ItemAddedOn)
+ INSERT INTO Items (BusinessID, Name, Description, ParentItemID, Price,
+ IsActive, IsCheckedByDefault, RequiresChildSelection,
+ MaxNumSelectionReq, IsCollapsible, SortOrder, AddedOn)
VALUES (:bizId, :name, :desc, :parentId, :price, b'#isActive#', :isDefault, :reqChild, :maxSel, :isCollapse, :sort, NOW())
", {
bizId: bizId, name: name, desc: description, parentId: parentId, price: price,
@@ -49,7 +49,7 @@ function insertItem(name, description, parentId, price, isActive, isCheckedByDef
function linkTemplate(menuItemId, templateId, sortOrder) {
if (dryRun) return;
queryExecute("
- INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
+ INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
VALUES (:itemId, :templateId, :sort)
", { itemId: menuItemId, templateId: templateId, sort: sortOrder });
}
@@ -316,16 +316,16 @@ arrayAppend(actions, { step: "ITEMS", category: "Hot Dogs & Such", count: 3 });
// Count totals
if (!dryRun) {
- qCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE ItemBusinessID = :bizId", { bizId: bizId });
+ qCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId", { bizId: bizId });
totalItems = qCount.cnt;
- qTemplateCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE ItemBusinessID = :bizId AND ItemParentItemID = 0 AND ItemIsCollapsible = 1", { bizId: bizId });
+ qTemplateCount = queryExecute("SELECT COUNT(*) as cnt FROM Items WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsCollapsible = 1", { bizId: bizId });
templateCount = qTemplateCount.cnt;
qLinkCount = queryExecute("
- SELECT COUNT(*) as cnt FROM ItemTemplateLinks tl
- JOIN Items i ON i.ItemID = tl.ItemID
- WHERE i.ItemBusinessID = :bizId
+ SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID tl
+ JOIN Items i ON i.ID = tl.ItemID
+ WHERE i.BusinessID = :bizId
", { bizId: bizId });
linkCount = qLinkCount.cnt;
} else {
diff --git a/api/setup/saveWizard.cfm b/api/setup/saveWizard.cfm
index d80833c..06a4040 100644
--- a/api/setup/saveWizard.cfm
+++ b/api/setup/saveWizard.cfm
@@ -71,7 +71,7 @@ try {
response.steps.append("State value received: '" & state & "' (len: " & len(state) & ")");
if (len(state)) {
qState = queryExecute("
- SELECT tt_StateID FROM tt_States WHERE tt_StateAbbreviation = :abbr
+ SELECT tt_StateID FROM tt_States WHERE Abbreviation = :abbr
", { abbr: uCase(state) }, { datasource: "payfrit" });
response.steps.append("State lookup for '" & uCase(state) & "' found " & qState.recordCount & " records");
@@ -82,7 +82,7 @@ try {
}
queryExecute("
- INSERT INTO Addresses (AddressLine1, AddressCity, AddressStateID, AddressZIPCode, AddressUserID, AddressTypeID, AddressAddedOn)
+ INSERT INTO Addresses (Line1, City, StateID, ZIPCode, UserID, AddressTypeID, AddedOn)
VALUES (:line1, :city, :stateID, :zip, :userID, :typeID, NOW())
", {
line1: len(addressLine1) ? addressLine1 : "Address pending",
@@ -103,7 +103,7 @@ try {
// Create new business with address link and phone
queryExecute("
- INSERT INTO Businesses (BusinessName, BusinessPhone, BusinessUserID, BusinessAddressID, BusinessDeliveryZipCodes, BusinessCommunityMealType, BusinessTaxRate, BusinessAddedOn)
+ INSERT INTO Businesses (Name, Phone, UserID, AddressID, BusinessDeliveryZipCodes, CommunityMealType, TaxRate, AddedOn)
VALUES (:name, :phone, :userId, :addressId, :deliveryZips, :communityMealType, :taxRate, NOW())
", {
name: bizName,
@@ -121,7 +121,7 @@ try {
// Update address with business ID link
queryExecute("
- UPDATE Addresses SET AddressBusinessID = :businessID WHERE AddressID = :addressID
+ UPDATE Addresses SET BusinessID = :businessID WHERE ID = :addressID
", {
businessID: businessId,
addressID: addressId
@@ -141,7 +141,7 @@ try {
for (tt = 1; tt <= arrayLen(defaultTaskTypes); tt++) {
taskType = defaultTaskTypes[tt];
queryExecute("
- INSERT INTO tt_TaskTypes (tt_TaskTypeName, tt_TaskTypeDescription, tt_TaskTypeIcon, tt_TaskTypeColor, tt_TaskTypeBusinessID, tt_TaskTypeSortOrder)
+ INSERT INTO tt_TaskTypes (Name, Description, Icon, Color, BusinessID, SortOrder)
VALUES (:name, :description, :icon, :color, :businessID, :sortOrder)
", {
name: { value: taskType.name, cfsqltype: "cf_sql_varchar" },
@@ -173,7 +173,7 @@ try {
// Insert hours record for this day
queryExecute("
- INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime)
+ INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime)
VALUES (:bizID, :dayID, :openTime, :closeTime)
", {
bizID: businessId,
@@ -188,14 +188,14 @@ try {
} else {
// Verify existing business exists
qBiz = queryExecute("
- SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID = :id
+ SELECT ID, Name FROM Businesses WHERE ID = :id
", { id: businessId }, { datasource: "payfrit" });
if (qBiz.recordCount == 0) {
throw(message="Business not found: " & businessId);
}
- response.steps.append("Found existing business: " & qBiz.BusinessName);
+ response.steps.append("Found existing business: " & qBiz.Name);
}
// Build modifier template map
@@ -220,23 +220,23 @@ try {
// Check if template already exists for this business
qTmpl = queryExecute("
- SELECT i.ItemID FROM Items i
- WHERE i.ItemBusinessID = :bizID
- AND i.ItemName = :name
- AND i.ItemParentItemID = 0
- AND i.ItemCategoryID = 0
+ SELECT i.ID FROM Items i
+ WHERE i.BusinessID = :bizID
+ AND i.Name = :name
+ AND i.ParentItemID = 0
+ AND i.CategoryID = 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 ItemCategoryID=0 to mark as template
+ // Create template as Item with CategoryID=0 to mark as template
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemParentItemID, ItemCategoryID, ItemPrice,
- ItemIsActive, ItemRequiresChildSelection, ItemMaxNumSelectionReq,
- ItemSortOrder
+ BusinessID, Name, ParentItemID, CategoryID, Price,
+ IsActive, RequiresChildSelection, MaxNumSelectionReq,
+ SortOrder
) VALUES (
:bizID, :name, 0, 0, 0, 1, :required, 1, 0
)
@@ -267,15 +267,15 @@ try {
optPrice = structKeyExists(opt, "price") && isSimpleValue(opt.price) ? val(opt.price) : 0;
qOpt = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizID AND ItemName = :name AND ItemParentItemID = :parentID
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizID AND Name = :name AND ParentItemID = :parentID
", { bizID: businessId, name: optName, parentID: templateItemID }, { datasource: "payfrit" });
if (qOpt.recordCount == 0) {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemParentItemID, ItemCategoryID,
- ItemPrice, ItemIsActive, ItemSortOrder
+ BusinessID, Name, ParentItemID, CategoryID,
+ Price, IsActive, SortOrder
) VALUES (
:bizID, :name, :parentID, 0, :price, 1, :sortOrder
)
@@ -295,8 +295,8 @@ try {
if (providedMenuId > 0) {
menuID = providedMenuId;
// Look up the menu name for logging
- qMenuName = queryExecute("SELECT MenuName FROM Menus WHERE MenuID = :id", { id: menuID }, { datasource: "payfrit" });
- menuName = qMenuName.recordCount > 0 ? qMenuName.MenuName : "Menu " & menuID;
+ qName = queryExecute("SELECT Name FROM Menus WHERE ID = :id", { id: menuID }, { datasource: "payfrit" });
+ menuName = qName.recordCount > 0 ? qName.Name : "Menu " & menuID;
response.steps.append("Using provided menu: " & menuName & " (ID: " & menuID & ")");
} else {
// Create a Menu record for this business (or get existing menu with same name)
@@ -319,9 +319,9 @@ try {
// Validate menu hours fall within business operating hours
if (len(menuStartTime) && len(menuEndTime)) {
qHours = queryExecute("
- SELECT MIN(HoursOpenTime) as earliestOpen, MAX(HoursClosingTime) as latestClose
+ SELECT MIN(OpenTime) as earliestOpen, MAX(ClosingTime) as latestClose
FROM Hours
- WHERE HoursBusinessID = :bizID
+ WHERE BusinessID = :bizID
", { bizID: businessId }, { datasource: "payfrit" });
if (qHours.recordCount > 0 && !isNull(qHours.earliestOpen) && !isNull(qHours.latestClose)) {
@@ -336,17 +336,17 @@ try {
}
qMenu = queryExecute("
- SELECT MenuID FROM Menus
- WHERE MenuBusinessID = :bizID AND MenuName = :name AND MenuIsActive = 1
+ SELECT ID FROM Menus
+ WHERE BusinessID = :bizID AND Name = :name AND IsActive = 1
", { bizID: businessId, name: menuName }, { datasource: "payfrit" });
if (qMenu.recordCount > 0) {
- menuID = qMenu.MenuID;
+ menuID = qMenu.ID;
// Update existing menu with new time range if provided
if (len(menuStartTime) && len(menuEndTime)) {
queryExecute("
- UPDATE Menus SET MenuStartTime = :startTime, MenuEndTime = :endTime
- WHERE MenuID = :menuID
+ UPDATE Menus SET StartTime = :startTime, EndTime = :endTime
+ WHERE ID = :menuID
", {
menuID: menuID,
startTime: menuStartTime,
@@ -359,7 +359,7 @@ try {
} else {
queryExecute("
INSERT INTO Menus (
- MenuBusinessID, MenuName, MenuDaysActive, MenuStartTime, MenuEndTime, MenuSortOrder, MenuIsActive, MenuAddedOn
+ BusinessID, Name, DaysActive, StartTime, EndTime, SortOrder, IsActive, AddedOn
) VALUES (
:bizID, :name, 127, :startTime, :endTime, 0, 1, NOW()
)
@@ -394,8 +394,8 @@ try {
// Check if category exists in Categories table for this menu
qCat = queryExecute("
- SELECT CategoryID FROM Categories
- WHERE CategoryBusinessID = :bizID AND CategoryName = :name AND CategoryMenuID = :menuID
+ SELECT ID FROM Categories
+ WHERE BusinessID = :bizID AND Name = :name AND MenuID = :menuID
", { bizID: businessId, name: catName, menuID: menuID }, { datasource: "payfrit" });
if (qCat.recordCount > 0) {
@@ -405,7 +405,7 @@ try {
// Create category in Categories table with MenuID
queryExecute("
INSERT INTO Categories (
- CategoryBusinessID, CategoryMenuID, CategoryName, CategorySortOrder
+ BusinessID, MenuID, Name, SortOrder
) VALUES (
:bizID, :menuID, :name, :sortOrder
)
@@ -483,20 +483,20 @@ try {
// Check if item exists
qItem = queryExecute("
- SELECT ItemID FROM Items
- WHERE ItemBusinessID = :bizID
- AND ItemName = :name
- AND ItemCategoryID = :catID
+ SELECT ID FROM Items
+ WHERE BusinessID = :bizID
+ AND Name = :name
+ AND CategoryID = :catID
", { bizID: businessId, name: itemName, catID: categoryID }, { datasource: "payfrit" });
if (qItem.recordCount > 0) {
- menuItemID = qItem.ItemID;
+ menuItemID = qItem.ID;
// Update existing item
queryExecute("
UPDATE Items SET
- ItemDescription = :desc,
- ItemPrice = :price,
- ItemSortOrder = :sortOrder
+ Description = :desc,
+ Price = :price,
+ SortOrder = :sortOrder
WHERE ItemID = :id
", {
desc: itemDesc,
@@ -507,8 +507,8 @@ try {
} else {
queryExecute("
INSERT INTO Items (
- ItemBusinessID, ItemName, ItemDescription, ItemParentItemID,
- ItemCategoryID, ItemPrice, ItemIsActive, ItemSortOrder
+ BusinessID, Name, Description, ParentItemID,
+ CategoryID, Price, IsActive, SortOrder
) VALUES (
:bizID, :name, :desc, 0, :catID, :price, 1, :sortOrder
)
@@ -544,13 +544,13 @@ try {
// Check if link exists
qLink = queryExecute("
- SELECT 1 FROM ItemTemplateLinks
+ SELECT 1 FROM lt_ItemID_TemplateItemID
WHERE ItemID = :itemID AND TemplateItemID = :templateID
", { itemID: menuItemID, templateID: templateItemID }, { datasource: "payfrit" });
if (qLink.recordCount == 0) {
queryExecute("
- INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
+ INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
VALUES (:itemID, :templateID, :sortOrder)
", {
itemID: menuItemID,
diff --git a/api/stations/list.cfm b/api/stations/list.cfm
index 62d8520..b47750a 100644
--- a/api/stations/list.cfm
+++ b/api/stations/list.cfm
@@ -35,20 +35,20 @@
diff --git a/api/stripe/createPaymentIntent.cfm b/api/stripe/createPaymentIntent.cfm
index 536384a..52ae950 100644
--- a/api/stripe/createPaymentIntent.cfm
+++ b/api/stripe/createPaymentIntent.cfm
@@ -62,9 +62,9 @@ try {
// Get business Stripe account
qBusiness = queryExecute("
- SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete, BusinessName
+ SELECT StripeAccountID, StripeOnboardingComplete, Name
FROM Businesses
- WHERE BusinessID = :businessID
+ WHERE ID = :businessID
", { businessID: businessID }, { datasource: "payfrit" });
if (qBusiness.recordCount == 0) {
@@ -75,18 +75,18 @@ try {
// Get order's delivery fee (if delivery order)
qOrder = queryExecute("
- SELECT OrderDeliveryFee, OrderTypeID
+ SELECT DeliveryFee, OrderTypeID
FROM Orders
- WHERE OrderID = :orderID
+ WHERE ID = :orderID
", { orderID: orderID }, { datasource: "payfrit" });
deliveryFee = 0;
if (qOrder.recordCount > 0 && qOrder.OrderTypeID == 3) {
- deliveryFee = val(qOrder.OrderDeliveryFee);
+ deliveryFee = val(qOrder.DeliveryFee);
}
// 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
@@ -119,12 +119,12 @@ try {
if (hasStripeConnect) {
httpService.addParam(type="formfield", name="application_fee_amount", value=totalPlatformFeeCents);
- 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);
httpService.addParam(type="formfield", name="metadata[business_id]", value=businessID);
- 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);
@@ -141,6 +141,23 @@ try {
// Fees are calculated dynamically, not stored in DB
+ // Link PaymentIntent to worker payout ledger (if a ledger row exists for this order's task)
+ try {
+ queryExecute("
+ UPDATE WorkPayoutLedgers wpl
+ INNER JOIN Tasks t ON t.TaskID = wpl.TaskID AND t.OrderID = :orderID
+ SET wpl.StripePaymentIntentID = :piID
+ WHERE wpl.Status = 'pending_charge'
+ AND wpl.StripePaymentIntentID IS NULL
+ ", {
+ orderID: orderID,
+ piID: piData.id
+ }, { datasource: "payfrit" });
+ } catch (any e) {
+ // Non-fatal: ledger row may not exist yet (task not completed before payment)
+ writeLog(file="stripe_webhooks", text="Ledger link skipped for order #orderID#: #e.message#");
+ }
+
response["OK"] = true;
response["CLIENT_SECRET"] = piData.client_secret;
response["PAYMENT_INTENT_ID"] = piData.id;
diff --git a/api/stripe/onboard.cfm b/api/stripe/onboard.cfm
index 6d13b3c..c59e3b9 100644
--- a/api/stripe/onboard.cfm
+++ b/api/stripe/onboard.cfm
@@ -32,9 +32,9 @@ try {
// Check if business already has a Stripe account
qBusiness = queryExecute("
- SELECT BusinessStripeAccountID, BusinessName, BusinessEmail
+ SELECT StripeAccountID, Name, BusinessEmail
FROM Businesses
- WHERE BusinessID = :businessID
+ WHERE ID = :businessID
", { businessID: businessID });
if (qBusiness.recordCount == 0) {
@@ -43,7 +43,7 @@ try {
abort;
}
- stripeAccountID = qBusiness.BusinessStripeAccountID;
+ stripeAccountID = qBusiness.StripeAccountID;
// Create new connected account if none exists
if (stripeAccountID == "" || isNull(stripeAccountID)) {
@@ -58,7 +58,7 @@ try {
httpService.addParam(type="formfield", name="email", value=qBusiness.BusinessEmail);
httpService.addParam(type="formfield", name="capabilities[card_payments][requested]", value="true");
httpService.addParam(type="formfield", name="capabilities[transfers][requested]", value="true");
- httpService.addParam(type="formfield", name="business_profile[name]", value=qBusiness.BusinessName);
+ httpService.addParam(type="formfield", name="business_profile[name]", value=qBusiness.Name);
result = httpService.send().getPrefix();
accountData = deserializeJSON(result.fileContent);
@@ -74,8 +74,8 @@ try {
// Save to database
queryExecute("
UPDATE Businesses
- SET BusinessStripeAccountID = :stripeAccountID,
- BusinessStripeOnboardingStarted = NOW()
+ SET StripeAccountID = :stripeAccountID,
+ StripeOnboardingStarted = NOW()
WHERE BusinessID = :businessID
", {
stripeAccountID: stripeAccountID,
diff --git a/api/stripe/status.cfm b/api/stripe/status.cfm
index 532d09c..3e9bb4e 100644
--- a/api/stripe/status.cfm
+++ b/api/stripe/status.cfm
@@ -23,9 +23,9 @@ try {
// Get business Stripe info
qBusiness = queryExecute("
- SELECT BusinessStripeAccountID, BusinessStripeOnboardingComplete
+ SELECT StripeAccountID, StripeOnboardingComplete
FROM Businesses
- WHERE BusinessID = :businessID
+ WHERE ID = :businessID
", { businessID: businessID });
if (qBusiness.recordCount == 0) {
@@ -34,7 +34,7 @@ try {
abort;
}
- stripeAccountID = qBusiness.BusinessStripeAccountID;
+ stripeAccountID = qBusiness.StripeAccountID;
if (stripeAccountID == "" || isNull(stripeAccountID)) {
response["OK"] = true;
@@ -73,10 +73,10 @@ try {
accountStatus = "active";
// Mark as complete in database if not already
- if (!qBusiness.BusinessStripeOnboardingComplete) {
+ if (!qBusiness.StripeOnboardingComplete) {
queryExecute("
UPDATE Businesses
- SET BusinessStripeOnboardingComplete = 1
+ SET StripeOnboardingComplete = 1
WHERE BusinessID = :businessID
", { businessID: businessID });
}
@@ -96,8 +96,8 @@ try {
} else {
// No Stripe key, just return what we have in DB
response["OK"] = true;
- response["CONNECTED"] = qBusiness.BusinessStripeOnboardingComplete == 1;
- response["ACCOUNT_STATUS"] = qBusiness.BusinessStripeOnboardingComplete == 1 ? "active" : "unknown";
+ response["CONNECTED"] = qBusiness.StripeOnboardingComplete == 1;
+ response["ACCOUNT_STATUS"] = qBusiness.StripeOnboardingComplete == 1 ? "active" : "unknown";
response["STRIPE_ACCOUNT_ID"] = stripeAccountID;
}
diff --git a/api/stripe/webhook.cfm b/api/stripe/webhook.cfm
index e12097d..639e32d 100644
--- a/api/stripe/webhook.cfm
+++ b/api/stripe/webhook.cfm
@@ -52,14 +52,83 @@ try {
// Note: Task is created later when order status changes to Ready (3) in updateStatus.cfm
queryExecute("
UPDATE Orders
- SET OrderPaymentStatus = 'paid',
+ SET PaymentStatus = 'paid',
OrderPaymentCompletedOn = NOW(),
- OrderStatusID = CASE WHEN OrderStatusID = 0 THEN 1 ELSE OrderStatusID END
+ StatusID = CASE WHEN StatusID = 0 THEN 1 ELSE StatusID END
WHERE OrderID = :orderID
", { orderID: orderID });
writeLog(file="stripe_webhooks", text="Order #orderID# marked as paid");
}
+
+ // === WORKER PAYOUT TRANSFER ===
+ // Find ledger row for this PaymentIntent
+ try {
+ qLedger = queryExecute("
+ SELECT wpl.ID, wpl.UserID, wpl.TaskID, wpl.NetTransferCents,
+ wpl.StripeTransferID, wpl.Status
+ FROM WorkPayoutLedgers wpl
+ WHERE wpl.StripePaymentIntentID = :piID
+ LIMIT 1
+ ", { piID: paymentIntentID });
+
+ if (qLedger.recordCount > 0 && isNull(qLedger.StripeTransferID) && qLedger.Status == "pending_charge") {
+ // Mark as charged
+ queryExecute("
+ UPDATE WorkPayoutLedgers SET Status = 'charged', UpdatedAt = NOW()
+ WHERE ID = :ledgerID
+ ", { ledgerID: qLedger.ID });
+
+ // Look up worker's Stripe Connected Account
+ qWorker = queryExecute("
+ SELECT StripeConnectedAccountID FROM Users WHERE ID = :userID
+ ", { userID: qLedger.UserID });
+
+ workerAccountID = qWorker.recordCount > 0 ? (qWorker.StripeConnectedAccountID ?: "") : "";
+
+ if (len(trim(workerAccountID)) > 0 && qLedger.NetTransferCents > 0) {
+ // Create Stripe Transfer — regardless of payoutsEnabled (Stripe holds funds)
+ stripeSecretKey = application.stripeSecretKey ?: "";
+ httpTransfer = new http();
+ httpTransfer.setMethod("POST");
+ httpTransfer.setUrl("https://api.stripe.com/v1/transfers");
+ httpTransfer.setUsername(stripeSecretKey);
+ httpTransfer.setPassword("");
+ httpTransfer.addParam(type="formfield", name="amount", value=qLedger.NetTransferCents);
+ httpTransfer.addParam(type="formfield", name="currency", value="usd");
+ httpTransfer.addParam(type="formfield", name="destination", value=workerAccountID);
+ httpTransfer.addParam(type="formfield", name="metadata[user_id]", value=qLedger.UserID);
+ httpTransfer.addParam(type="formfield", name="metadata[task_id]", value=qLedger.TaskID);
+ httpTransfer.addParam(type="formfield", name="metadata[ledger_id]", value=qLedger.ID);
+ httpTransfer.addParam(type="formfield", name="metadata[activation_withheld_cents]", value=0);
+
+ transferResult = httpTransfer.send().getPrefix();
+ transferData = deserializeJSON(transferResult.fileContent);
+
+ if (structKeyExists(transferData, "id")) {
+ queryExecute("
+ UPDATE WorkPayoutLedgers
+ SET StripeTransferID = :transferID, Status = 'transferred', UpdatedAt = NOW()
+ WHERE ID = :ledgerID
+ ", { transferID: transferData.id, ledgerID: qLedger.ID });
+
+ writeLog(file="stripe_webhooks", text="Transfer #transferData.id# created for ledger #qLedger.ID#");
+ } else {
+ writeLog(file="stripe_webhooks", text="Transfer failed for ledger #qLedger.ID#: #transferData.error.message ?: 'unknown'#");
+ }
+ } else if (qLedger.NetTransferCents == 0) {
+ // Nothing to transfer (entire amount withheld for activation)
+ queryExecute("
+ UPDATE WorkPayoutLedgers SET Status = 'transferred', UpdatedAt = NOW()
+ WHERE ID = :ledgerID
+ ", { ledgerID: qLedger.ID });
+ }
+ // else: no connected account yet — stays 'charged', transfer deferred
+ }
+ } catch (any transferErr) {
+ writeLog(file="stripe_webhooks", text="Worker transfer error: #transferErr.message#");
+ }
+
break;
case "payment_intent.payment_failed":
@@ -71,7 +140,7 @@ try {
if (orderID > 0) {
queryExecute("
UPDATE Orders
- SET OrderPaymentStatus = 'failed',
+ SET PaymentStatus = 'failed',
OrderPaymentError = :failureMessage
WHERE OrderID = :orderID
", {
@@ -91,14 +160,14 @@ try {
if (paymentIntentID != "") {
qOrder = queryExecute("
- SELECT OrderID FROM Orders
+ SELECT ID FROM Orders
WHERE OrderStripePaymentIntentID = :paymentIntentID
", { paymentIntentID: paymentIntentID });
if (qOrder.recordCount > 0) {
queryExecute("
UPDATE Orders
- SET OrderPaymentStatus = 'refunded',
+ SET PaymentStatus = 'refunded',
OrderRefundAmount = :refundAmount,
OrderRefundedOn = NOW()
WHERE OrderStripePaymentIntentID = :paymentIntentID
@@ -119,27 +188,27 @@ try {
if (paymentIntentID != "") {
qOrder = queryExecute("
- SELECT OrderID, OrderBusinessID FROM Orders
+ SELECT ID, BusinessID FROM Orders
WHERE OrderStripePaymentIntentID = :paymentIntentID
", { paymentIntentID: paymentIntentID });
if (qOrder.recordCount > 0) {
queryExecute("
UPDATE Orders
- SET OrderPaymentStatus = 'disputed'
+ SET PaymentStatus = 'disputed'
WHERE OrderStripePaymentIntentID = :paymentIntentID
", { paymentIntentID: paymentIntentID });
// Create a task for the dispute
queryExecute("
- INSERT INTO Tasks (TaskBusinessID, TaskCategoryID, TaskTitle, TaskDetails, TaskCreatedOn, TaskStatusID, TaskSourceType, TaskSourceID)
- VALUES (:businessID, 4, 'Payment Dispute', 'Order ###qOrder.OrderID# has been disputed. Review immediately.', NOW(), 0, 'dispute', :orderID)
+ INSERT INTO Tasks (BusinessID, CategoryID, Title, Details, CreatedOn, StatusID, SourceType, SourceID)
+ VALUES (:businessID, 4, 'Payment Dispute', 'Order ###qOrder.ID# has been disputed. Review immediately.', NOW(), 0, 'dispute', :orderID)
", {
- businessID: qOrder.OrderBusinessID,
- orderID: qOrder.OrderID
+ businessID: qOrder.BusinessID,
+ orderID: qOrder.ID
});
- writeLog(file="stripe_webhooks", text="Dispute created for order #qOrder.OrderID#");
+ writeLog(file="stripe_webhooks", text="Dispute created for order #qOrder.ID#");
}
}
break;
@@ -150,14 +219,61 @@ try {
chargesEnabled = eventData.charges_enabled ?: false;
payoutsEnabled = eventData.payouts_enabled ?: false;
+ // Business accounts
if (chargesEnabled && payoutsEnabled) {
queryExecute("
UPDATE Businesses
- SET BusinessStripeOnboardingComplete = 1
- WHERE BusinessStripeAccountID = :accountID
+ SET StripeOnboardingComplete = 1
+ WHERE StripeAccountID = :accountID
", { accountID: accountID });
- writeLog(file="stripe_webhooks", text="Account #accountID# is now fully active");
+ writeLog(file="stripe_webhooks", text="Business account #accountID# is now fully active");
+ }
+
+ // Worker accounts — update StripePayoutsEnabled for tier derivation
+ try {
+ qWorkerAcct = queryExecute("
+ SELECT ID FROM Users
+ WHERE StripeConnectedAccountID = :accountID
+ LIMIT 1
+ ", { accountID: accountID });
+
+ if (qWorkerAcct.recordCount > 0) {
+ queryExecute("
+ UPDATE Users
+ SET StripePayoutsEnabled = :payoutsEnabled
+ WHERE StripeConnectedAccountID = :accountID
+ ", {
+ payoutsEnabled: payoutsEnabled ? 1 : 0,
+ accountID: accountID
+ });
+
+ writeLog(file="stripe_webhooks", text="Worker user #qWorkerAcct.ID# payoutsEnabled=#payoutsEnabled#");
+ }
+ } catch (any workerErr) {
+ writeLog(file="stripe_webhooks", text="Worker account update error: #workerErr.message#");
+ }
+
+ break;
+
+ case "checkout.session.completed":
+ // Activation early unlock payment completed
+ try {
+ sessionMetadata = eventData.metadata ?: {};
+ metaType = sessionMetadata.type ?: "";
+ metaUserID = val(sessionMetadata.user_id ?: 0);
+
+ if (metaType == "activation_unlock" && metaUserID > 0) {
+ queryExecute("
+ UPDATE Users
+ SET ActivationBalanceCents = ActivationCapCents
+ WHERE ID = :userID
+ ", { userID: metaUserID });
+
+ writeLog(file="stripe_webhooks", text="Activation completed via payment for user #metaUserID#");
+ }
+ } catch (any checkoutErr) {
+ writeLog(file="stripe_webhooks", text="Checkout session error: #checkoutErr.message#");
}
break;
diff --git a/api/tasks/accept.cfm b/api/tasks/accept.cfm
index 2cef886..b17d0e9 100644
--- a/api/tasks/accept.cfm
+++ b/api/tasks/accept.cfm
@@ -37,26 +37,26 @@
-
+
0) {
userQuery = queryExecute("
- SELECT UserFirstName FROM Users WHERE UserID = :userID
+ SELECT FirstName FROM Users WHERE ID = :userID
", { userID: { value: userID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
- if (userQuery.recordCount && len(trim(userQuery.UserFirstName))) {
- userName = userQuery.UserFirstName;
+ if (userQuery.recordCount && len(trim(userQuery.FirstName))) {
+ userName = userQuery.FirstName;
}
}
@@ -63,14 +63,14 @@ try {
taskTypeCategoryID = 0;
if (taskTypeID > 0) {
typeQuery = queryExecute("
- SELECT tt_TaskTypeName, tt_TaskTypeCategoryID FROM tt_TaskTypes WHERE tt_TaskTypeID = :typeID
+ SELECT Name, TaskCategoryID FROM tt_TaskTypes WHERE tt_TaskTypeID = :typeID
", { typeID: { value: taskTypeID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
if (typeQuery.recordCount) {
- if (len(trim(typeQuery.tt_TaskTypeName))) {
- taskTypeName = typeQuery.tt_TaskTypeName;
+ if (len(trim(typeQuery.Name))) {
+ taskTypeName = typeQuery.Name;
}
- if (!isNull(typeQuery.tt_TaskTypeCategoryID) && isNumeric(typeQuery.tt_TaskTypeCategoryID) && typeQuery.tt_TaskTypeCategoryID > 0) {
- taskTypeCategoryID = typeQuery.tt_TaskTypeCategoryID;
+ if (!isNull(typeQuery.TaskCategoryID) && isNumeric(typeQuery.TaskCategoryID) && typeQuery.TaskCategoryID > 0) {
+ taskTypeCategoryID = typeQuery.TaskCategoryID;
}
}
}
@@ -105,36 +105,36 @@ try {
} else {
// Fallback: look up or create a "Service" category for this business
catQuery = queryExecute("
- SELECT TaskCategoryID FROM TaskCategories
- WHERE TaskCategoryBusinessID = :businessID AND TaskCategoryName = 'Service'
+ SELECT ID FROM TaskCategories
+ WHERE BusinessID = :businessID AND Name = 'Service'
LIMIT 1
", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
if (catQuery.recordCount == 0) {
// Create the category
queryExecute("
- INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
+ INSERT INTO TaskCategories (BusinessID, Name, Color)
VALUES (:businessID, 'Service', '##FF9800')
", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
catResult = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
categoryID = catResult.newID;
} else {
- categoryID = catQuery.TaskCategoryID;
+ categoryID = catQuery.ID;
}
}
// Insert task
queryExecute("
INSERT INTO Tasks (
- TaskBusinessID,
- TaskCategoryID,
- TaskOrderID,
+ BusinessID,
+ CategoryID,
+ OrderID,
TaskTypeID,
- TaskTitle,
- TaskDetails,
- TaskClaimedByUserID,
- TaskAddedOn
+ Title,
+ Details,
+ ClaimedByUserID,
+ CreatedOn
) VALUES (
:businessID,
:categoryID,
diff --git a/api/tasks/complete.cfm b/api/tasks/complete.cfm
index c30eac2..455d773 100644
--- a/api/tasks/complete.cfm
+++ b/api/tasks/complete.cfm
@@ -45,11 +45,11 @@
@@ -59,23 +59,23 @@
-
+
-
+
-
+
-
-
-
+
+
+
@@ -104,30 +104,88 @@
-
+
+ ", [ { value = qTask.OrderID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/api/tasks/completeChat.cfm b/api/tasks/completeChat.cfm
index 795cfd8..7cd9d2a 100644
--- a/api/tasks/completeChat.cfm
+++ b/api/tasks/completeChat.cfm
@@ -36,9 +36,9 @@
@@ -51,14 +51,14 @@
-
+
diff --git a/api/tasks/create.cfm b/api/tasks/create.cfm
index 05d251f..edeb522 100644
--- a/api/tasks/create.cfm
+++ b/api/tasks/create.cfm
@@ -31,14 +31,14 @@ try {
// Get task type info for display
taskTypeQuery = queryExecute("
- SELECT tt_TaskTypeName, tt_TaskTypeColor, tt_TaskTypeIcon
+ SELECT Name, Color, Icon
FROM tt_TaskTypes
WHERE tt_TaskTypeID = :taskTypeID
", { taskTypeID: taskTypeID }, { datasource: "payfrit" });
taskTitle = message;
- if (taskTypeQuery.recordCount && len(taskTypeQuery.tt_TaskTypeName)) {
- taskTitle = taskTypeQuery.tt_TaskTypeName;
+ if (taskTypeQuery.recordCount && len(taskTypeQuery.Name)) {
+ taskTitle = taskTypeQuery.Name;
}
// Use message as details
@@ -47,14 +47,14 @@ try {
// Insert service bell task
queryExecute("
INSERT INTO Tasks (
- TaskBusinessID,
+ BusinessID,
TaskTypeID,
- TaskCategoryID,
- TaskOrderID,
- TaskTitle,
- TaskDetails,
- TaskAddedOn,
- TaskClaimedByUserID
+ CategoryID,
+ OrderID,
+ Title,
+ Details,
+ CreatedOn,
+ ClaimedByUserID
) VALUES (
:businessID,
:taskTypeID,
@@ -84,10 +84,10 @@ try {
itemName = "";
if (itemID > 0) {
itemQuery = queryExecute("
- SELECT ItemName FROM Items WHERE ItemID = :itemID
+ SELECT Name FROM Items WHERE ID = :itemID
", { itemID: itemID });
if (itemQuery.recordCount) {
- itemName = itemQuery.ItemName;
+ itemName = itemQuery.Name;
}
}
@@ -107,14 +107,14 @@ try {
// Insert legacy task
queryExecute("
INSERT INTO Tasks (
- TaskBusinessID,
+ BusinessID,
TaskItemID,
TaskType,
TaskDescription,
TaskInstructions,
TaskPYTReward,
TaskStatus,
- TaskCreatedOn
+ CreatedOn
) VALUES (
:businessID,
:itemID,
diff --git a/api/tasks/createChat.cfm b/api/tasks/createChat.cfm
index ebf142c..af02596 100644
--- a/api/tasks/createChat.cfm
+++ b/api/tasks/createChat.cfm
@@ -39,27 +39,27 @@ try {
// In that case, we use userID to match existing chats
// Check for existing open chat at this service point
- // An open chat is one where TaskTypeID=2 (Chat) and TaskCompletedOn IS NULL
+ // An open chat is one where TaskTypeID=2 (Chat) and CompletedOn IS NULL
forceNew = structKeyExists(data, "ForceNew") && data.ForceNew == true;
if (!forceNew) {
// Look for any active chat for this business
// Check by: order match, service point match, OR user match (for remote chats)
existingChat = queryExecute("
- SELECT t.TaskID, t.TaskAddedOn,
- (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.TaskID) as LastMessageTime
+ SELECT t.ID, t.CreatedOn,
+ (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.ID) as LastMessageTime
FROM Tasks t
- LEFT JOIN ChatMessages cm2 ON cm2.TaskID = t.TaskID AND cm2.SenderUserID = :userID
- WHERE t.TaskBusinessID = :businessID
+ LEFT JOIN ChatMessages cm2 ON cm2.TaskID = t.ID AND cm2.SenderUserID = :userID
+ WHERE t.BusinessID = :businessID
AND t.TaskTypeID = 2
- AND t.TaskCompletedOn IS NULL
+ AND t.CompletedOn IS NULL
AND (
- (t.TaskOrderID = :orderID AND :orderID > 0)
- OR (t.TaskSourceType = 'servicepoint' AND t.TaskSourceID = :servicePointID AND :servicePointID > 0)
- OR (t.TaskSourceType = 'user' AND t.TaskSourceID = :userID AND :userID > 0)
+ (t.OrderID = :orderID AND :orderID > 0)
+ OR (t.SourceType = 'servicepoint' AND t.SourceID = :servicePointID AND :servicePointID > 0)
+ OR (t.SourceType = 'user' AND t.SourceID = :userID AND :userID > 0)
OR (cm2.SenderUserID = :userID AND :userID > 0)
)
- ORDER BY t.TaskAddedOn DESC
+ ORDER BY t.CreatedOn DESC
LIMIT 1
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" },
@@ -72,21 +72,21 @@ try {
// Check if chat is stale (more than 30 minutes since last message, or 30 min since creation if no messages)
lastActivity = existingChat.LastMessageTime;
if (isNull(lastActivity) || !isDate(lastActivity)) {
- lastActivity = existingChat.TaskAddedOn;
+ lastActivity = existingChat.CreatedOn;
}
chatAge = dateDiff("n", lastActivity, now());
if (chatAge > 30) {
// Auto-close stale chat
queryExecute("
- UPDATE Tasks SET TaskCompletedOn = NOW()
+ UPDATE Tasks SET CompletedOn = NOW()
WHERE TaskID = :taskID
- ", { taskID: { value: existingChat.TaskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
+ ", { taskID: { value: existingChat.ID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
} else {
// Return existing chat
apiAbort({
"OK": true,
- "TaskID": existingChat.TaskID,
+ "TaskID": existingChat.ID,
"MESSAGE": "Rejoined existing chat",
"EXISTING": true
});
@@ -98,19 +98,19 @@ try {
tableName = "";
if (servicePointID > 0) {
spQuery = queryExecute("
- SELECT ServicePointName FROM ServicePoints WHERE ServicePointID = :spID
+ SELECT Name FROM ServicePoints WHERE ID = :spID
", { spID: { value: servicePointID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
- tableName = spQuery.recordCount ? spQuery.ServicePointName : "Table ##" & servicePointID;
+ tableName = spQuery.recordCount ? spQuery.Name : "Table ##" & servicePointID;
}
// Get user name if available
userName = "";
if (userID > 0) {
userQuery = queryExecute("
- SELECT UserFirstName FROM Users WHERE UserID = :userID
+ SELECT FirstName FROM Users WHERE ID = :userID
", { userID: { value: userID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
- if (userQuery.recordCount && len(trim(userQuery.UserFirstName))) {
- userName = userQuery.UserFirstName;
+ if (userQuery.recordCount && len(trim(userQuery.FirstName))) {
+ userName = userQuery.FirstName;
}
}
@@ -137,22 +137,22 @@ try {
// Look up or create a "Chat" category for this business
catQuery = queryExecute("
- SELECT TaskCategoryID FROM TaskCategories
- WHERE TaskCategoryBusinessID = :businessID AND TaskCategoryName = 'Chat'
+ SELECT ID FROM TaskCategories
+ WHERE BusinessID = :businessID AND Name = 'Chat'
LIMIT 1
", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
if (catQuery.recordCount == 0) {
// Create the category (blue color for chat)
queryExecute("
- INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
+ INSERT INTO TaskCategories (BusinessID, Name, Color)
VALUES (:businessID, 'Chat', '##2196F3')
", { businessID: { value: businessID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
catResult = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
categoryID = catResult.newID;
} else {
- categoryID = catQuery.TaskCategoryID;
+ categoryID = catQuery.ID;
}
// Determine source type and ID based on dine-in vs remote
@@ -167,16 +167,16 @@ try {
// Insert task with TaskTypeID = 2 (Chat)
queryExecute("
INSERT INTO Tasks (
- TaskBusinessID,
- TaskCategoryID,
- TaskOrderID,
+ BusinessID,
+ CategoryID,
+ OrderID,
TaskTypeID,
- TaskTitle,
- TaskDetails,
- TaskClaimedByUserID,
- TaskSourceType,
- TaskSourceID,
- TaskAddedOn
+ Title,
+ Details,
+ ClaimedByUserID,
+ SourceType,
+ SourceID,
+ CreatedOn
) VALUES (
:businessID,
:categoryID,
@@ -206,7 +206,7 @@ try {
// If there's an initial message, save it
if (len(initialMessage) && userID > 0) {
queryExecute("
- INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageText)
+ INSERT INTO ChatMessages (TaskID, SenderUserID, SenderType, MessageBody)
VALUES (:taskID, :userID, 'customer', :message)
", {
taskID: { value: taskID, cfsqltype: "cf_sql_integer" },
diff --git a/api/tasks/deleteCategory.cfm b/api/tasks/deleteCategory.cfm
index e36dea9..5e8c311 100644
--- a/api/tasks/deleteCategory.cfm
+++ b/api/tasks/deleteCategory.cfm
@@ -51,8 +51,8 @@ try {
// Verify ownership
qCheck = queryExecute("
- SELECT TaskCategoryID FROM TaskCategories
- WHERE TaskCategoryID = :id AND TaskCategoryBusinessID = :businessID
+ SELECT ID FROM TaskCategories
+ WHERE ID = :id AND BusinessID = :businessID
", {
id: { value: categoryID, cfsqltype: "cf_sql_integer" },
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
@@ -65,7 +65,7 @@ try {
// Check if any tasks use this category
qTasks = queryExecute("
SELECT COUNT(*) as cnt FROM Tasks
- WHERE TaskCategoryID = :id
+ WHERE CategoryID = :id
", {
id: { value: categoryID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
@@ -73,8 +73,8 @@ try {
if (qTasks.cnt > 0) {
// Soft delete - just deactivate
queryExecute("
- UPDATE TaskCategories SET TaskCategoryIsActive = 0
- WHERE TaskCategoryID = :id
+ UPDATE TaskCategories SET IsActive = 0
+ WHERE ID = :id
", {
id: { value: categoryID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
@@ -86,7 +86,7 @@ try {
} else {
// Hard delete - no tasks use it
queryExecute("
- DELETE FROM TaskCategories WHERE TaskCategoryID = :id
+ DELETE FROM TaskCategories WHERE ID = :id
", {
id: { value: categoryID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
diff --git a/api/tasks/deleteType.cfm b/api/tasks/deleteType.cfm
index 69218a7..2ba1bbe 100644
--- a/api/tasks/deleteType.cfm
+++ b/api/tasks/deleteType.cfm
@@ -46,7 +46,7 @@ try {
// Verify task type exists and belongs to this business
qCheck = queryExecute("
- SELECT tt_TaskTypeID, tt_TaskTypeBusinessID
+ SELECT tt_TaskTypeID, BusinessID
FROM tt_TaskTypes
WHERE tt_TaskTypeID = :taskTypeID
", {
@@ -57,7 +57,7 @@ try {
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Task type not found" });
}
- if (isNull(qCheck.tt_TaskTypeBusinessID) || qCheck.tt_TaskTypeBusinessID != businessID) {
+ if (isNull(qCheck.BusinessID) || qCheck.BusinessID != businessID) {
apiAbort({ "OK": false, "ERROR": "not_authorized", "MESSAGE": "Task type does not belong to this business" });
}
@@ -65,7 +65,7 @@ try {
queryExecute("
DELETE FROM tt_TaskTypes
WHERE tt_TaskTypeID = :taskTypeID
- AND tt_TaskTypeBusinessID = :businessID
+ AND BusinessID = :businessID
", {
taskTypeID: { value: taskTypeID, cfsqltype: "cf_sql_integer" },
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
diff --git a/api/tasks/expireStaleChats.cfm b/api/tasks/expireStaleChats.cfm
index fe9c637..b2d8737 100644
--- a/api/tasks/expireStaleChats.cfm
+++ b/api/tasks/expireStaleChats.cfm
@@ -16,16 +16,16 @@ try {
// Find open chat tasks that are stale
// A chat is stale if:
// 1. TaskTypeID = 2 (Chat)
- // 2. TaskCompletedOn IS NULL (not closed)
+ // 2. CompletedOn IS NULL (not closed)
// 3. No messages in the last 20 minutes AND task is older than 20 minutes
staleChats = queryExecute("
- SELECT t.TaskID, t.TaskAddedOn,
- (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.TaskID) as LastMessageOn
+ SELECT t.ID, t.CreatedOn,
+ (SELECT MAX(cm.CreatedOn) FROM ChatMessages cm WHERE cm.TaskID = t.ID) as LastMessageOn
FROM Tasks t
WHERE t.TaskTypeID = 2
- AND t.TaskCompletedOn IS NULL
- AND t.TaskAddedOn < DATE_SUB(NOW(), INTERVAL 20 MINUTE)
+ AND t.CompletedOn IS NULL
+ AND t.CreatedOn < DATE_SUB(NOW(), INTERVAL 20 MINUTE)
", {}, { datasource: "payfrit" });
expiredCount = 0;
@@ -48,12 +48,12 @@ try {
if (shouldExpire) {
queryExecute("
- UPDATE Tasks SET TaskCompletedOn = NOW()
+ UPDATE Tasks SET CompletedOn = NOW()
WHERE TaskID = :taskID
- ", { taskID: { value: chat.TaskID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
+ ", { taskID: { value: chat.ID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
expiredCount++;
- arrayAppend(expiredIds, chat.TaskID);
+ arrayAppend(expiredIds, chat.ID);
}
}
diff --git a/api/tasks/getDetails.cfm b/api/tasks/getDetails.cfm
index a35c34c..567d619 100644
--- a/api/tasks/getDetails.cfm
+++ b/api/tasks/getDetails.cfm
@@ -37,35 +37,35 @@
@@ -73,9 +73,9 @@
-
-
-
+
+
+
@@ -95,44 +95,44 @@
-
+
+ ", [ { value = qTask.ServicePointID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
-
+
@@ -140,34 +140,34 @@
diff --git a/api/tasks/listAllTypes.cfm b/api/tasks/listAllTypes.cfm
index a1c7138..602a385 100644
--- a/api/tasks/listAllTypes.cfm
+++ b/api/tasks/listAllTypes.cfm
@@ -46,15 +46,15 @@ try {
q = queryExecute("
SELECT
tt_TaskTypeID as TaskTypeID,
- tt_TaskTypeName as TaskTypeName,
- tt_TaskTypeDescription as TaskTypeDescription,
- tt_TaskTypeIcon as TaskTypeIcon,
- tt_TaskTypeColor as TaskTypeColor,
- tt_TaskTypeSortOrder as SortOrder,
- tt_TaskTypeCategoryID as CategoryID
+ Name as TaskTypeName,
+ Description as TaskTypeDescription,
+ Icon as TaskTypeIcon,
+ Color as TaskTypeColor,
+ SortOrder as SortOrder,
+ TaskCategoryID as CategoryID
FROM tt_TaskTypes
- WHERE tt_TaskTypeBusinessID = :businessID
- ORDER BY tt_TaskTypeSortOrder, tt_TaskTypeID
+ WHERE BusinessID = :businessID
+ ORDER BY SortOrder, tt_TaskTypeID
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
diff --git a/api/tasks/listCategories.cfm b/api/tasks/listCategories.cfm
index 04f58d9..1bd0c27 100644
--- a/api/tasks/listCategories.cfm
+++ b/api/tasks/listCategories.cfm
@@ -48,13 +48,13 @@ try {
// Get Task Categories (separate from Services/Task Types)
qCategories = queryExecute("
SELECT
- TaskCategoryID,
- TaskCategoryName,
- TaskCategoryColor
+ ID,
+ Name,
+ Color
FROM TaskCategories
- WHERE TaskCategoryBusinessID = :businessID
- AND TaskCategoryIsActive = 1
- ORDER BY TaskCategoryName
+ WHERE BusinessID = :businessID
+ AND IsActive = 1
+ ORDER BY Name
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
@@ -62,9 +62,9 @@ try {
categories = [];
for (row in qCategories) {
arrayAppend(categories, {
- "TaskCategoryID": row.TaskCategoryID,
- "TaskCategoryName": row.TaskCategoryName,
- "TaskCategoryColor": row.TaskCategoryColor
+ "TaskCategoryID": row.ID,
+ "Name": row.Name,
+ "Color": row.Color
});
}
diff --git a/api/tasks/listMine.cfm b/api/tasks/listMine.cfm
index 03d0176..e71a5d8 100644
--- a/api/tasks/listMine.cfm
+++ b/api/tasks/listMine.cfm
@@ -37,28 +37,28 @@
-
+
-
+
-
+
-
+
-
+
- = DATE_SUB(CURDATE(), INTERVAL 7 DAY)")>
+ = DATE_SUB(CURDATE(), INTERVAL 7 DAY)")>
@@ -66,29 +66,29 @@
@@ -96,35 +96,35 @@
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
+
-
+
-
+
@@ -56,25 +56,25 @@
@@ -82,29 +82,29 @@
-
-
-
-
+
+
+
+
-
+
-
+
0) {
// UPDATE existing category
qCheck = queryExecute("
- SELECT TaskCategoryID FROM TaskCategories
- WHERE TaskCategoryID = :id AND TaskCategoryBusinessID = :businessID
+ SELECT ID FROM TaskCategories
+ WHERE ID = :id AND BusinessID = :businessID
", {
id: { value: categoryID, cfsqltype: "cf_sql_integer" },
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
@@ -79,9 +79,9 @@ try {
queryExecute("
UPDATE TaskCategories SET
- TaskCategoryName = :name,
- TaskCategoryColor = :color
- WHERE TaskCategoryID = :id
+ Name = :name,
+ Color = :color
+ WHERE ID = :id
", {
name: { value: categoryName, cfsqltype: "cf_sql_varchar" },
color: { value: categoryColor, cfsqltype: "cf_sql_varchar" },
@@ -97,7 +97,7 @@ try {
} else {
// INSERT new category
queryExecute("
- INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
+ INSERT INTO TaskCategories (BusinessID, Name, Color)
VALUES (:businessID, :name, :color)
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" },
diff --git a/api/tasks/saveType.cfm b/api/tasks/saveType.cfm
index 56c4853..75e9aa2 100644
--- a/api/tasks/saveType.cfm
+++ b/api/tasks/saveType.cfm
@@ -97,7 +97,7 @@ try {
qCheck = queryExecute("
SELECT tt_TaskTypeID FROM tt_TaskTypes
WHERE tt_TaskTypeID = :taskTypeID
- AND tt_TaskTypeBusinessID = :businessID
+ AND BusinessID = :businessID
", {
taskTypeID: { value: taskTypeID, cfsqltype: "cf_sql_integer" },
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
@@ -109,11 +109,11 @@ try {
queryExecute("
UPDATE tt_TaskTypes
- SET tt_TaskTypeName = :taskTypeName,
- tt_TaskTypeDescription = :taskTypeDescription,
- tt_TaskTypeIcon = :taskTypeIcon,
- tt_TaskTypeColor = :taskTypeColor,
- tt_TaskTypeCategoryID = :categoryID
+ SET Name = :taskTypeName,
+ Description = :taskTypeDescription,
+ Icon = :taskTypeIcon,
+ Color = :taskTypeColor,
+ TaskCategoryID = :categoryID
WHERE tt_TaskTypeID = :taskTypeID
", {
taskTypeName: { value: taskTypeName, cfsqltype: "cf_sql_varchar" },
@@ -132,7 +132,7 @@ try {
} else {
// INSERT new task type
queryExecute("
- INSERT INTO tt_TaskTypes (tt_TaskTypeName, tt_TaskTypeDescription, tt_TaskTypeIcon, tt_TaskTypeColor, tt_TaskTypeBusinessID, tt_TaskTypeCategoryID)
+ INSERT INTO tt_TaskTypes (Name, Description, Icon, Color, BusinessID, TaskCategoryID)
VALUES (:taskTypeName, :taskTypeDescription, :taskTypeIcon, :taskTypeColor, :businessID, :categoryID)
", {
taskTypeName: { value: taskTypeName, cfsqltype: "cf_sql_varchar" },
diff --git a/api/tasks/seedCategories.cfm b/api/tasks/seedCategories.cfm
index 09d9b30..b48f60b 100644
--- a/api/tasks/seedCategories.cfm
+++ b/api/tasks/seedCategories.cfm
@@ -47,7 +47,7 @@ try {
// Check if categories already exist
qCheck = queryExecute("
SELECT COUNT(*) AS cnt FROM TaskCategories
- WHERE TaskCategoryBusinessID = :businessID
+ WHERE BusinessID = :businessID
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
@@ -55,10 +55,10 @@ try {
if (qCheck.cnt > 0) {
// Categories already exist, just return them
qCategories = queryExecute("
- SELECT TaskCategoryID, TaskCategoryName, TaskCategoryColor
+ SELECT ID, Name, Color
FROM TaskCategories
- WHERE TaskCategoryBusinessID = :businessID AND TaskCategoryIsActive = 1
- ORDER BY TaskCategoryName
+ WHERE BusinessID = :businessID AND IsActive = 1
+ ORDER BY Name
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
@@ -66,9 +66,9 @@ try {
categories = [];
for (row in qCategories) {
arrayAppend(categories, {
- "TaskCategoryID": row.TaskCategoryID,
- "TaskCategoryName": row.TaskCategoryName,
- "TaskCategoryColor": row.TaskCategoryColor
+ "TaskCategoryID": row.ID,
+ "Name": row.Name,
+ "Color": row.Color
});
}
@@ -93,7 +93,7 @@ try {
// Insert defaults
for (cat in defaults) {
queryExecute("
- INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
+ INSERT INTO TaskCategories (BusinessID, Name, Color)
VALUES (:businessID, :name, :color)
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" },
@@ -104,10 +104,10 @@ try {
// Return the created categories
qCategories = queryExecute("
- SELECT TaskCategoryID, TaskCategoryName, TaskCategoryColor
+ SELECT ID, Name, Color
FROM TaskCategories
- WHERE TaskCategoryBusinessID = :businessID AND TaskCategoryIsActive = 1
- ORDER BY TaskCategoryName
+ WHERE BusinessID = :businessID AND IsActive = 1
+ ORDER BY Name
", {
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
}, { datasource: "payfrit" });
@@ -115,9 +115,9 @@ try {
categories = [];
for (row in qCategories) {
arrayAppend(categories, {
- "TaskCategoryID": row.TaskCategoryID,
- "TaskCategoryName": row.TaskCategoryName,
- "TaskCategoryColor": row.TaskCategoryColor
+ "TaskCategoryID": row.ID,
+ "Name": row.Name,
+ "Color": row.Color
});
}
diff --git a/api/tasks/setup.cfm b/api/tasks/setup.cfm
index 7142665..e623fb6 100644
--- a/api/tasks/setup.cfm
+++ b/api/tasks/setup.cfm
@@ -4,22 +4,22 @@
-
+
-
+
= 4) {
- maskedPhone = "***-***-" & right(user.UserPhone, 4);
+ if (len(trim(user.ContactNumber)) >= 4) {
+ maskedPhone = "***-***-" & right(user.ContactNumber, 4);
}
arrayAppend(users, {
"UserID": user.UserID,
- "Name": trim(user.UserFirstName & " " & user.UserLastName),
- "Email": user.UserEmail,
+ "Name": trim(user.FirstName & " " & user.LastName),
+ "Email": user.EmailAddress,
"Phone": maskedPhone,
"AvatarUrl": len(trim(user.UserAvatarPath)) ? "https://biz.payfrit.com/uploads/" & user.UserAvatarPath : ""
});
diff --git a/api/workers/createAccount.cfm b/api/workers/createAccount.cfm
new file mode 100644
index 0000000..2d9d7ba
--- /dev/null
+++ b/api/workers/createAccount.cfm
@@ -0,0 +1,94 @@
+
+
+
+
+
+/**
+ * Create or reuse Stripe Connect Express account for worker.
+ */
+
+response = { "OK": false };
+
+try {
+ requestData = deserializeJSON(toString(getHttpRequestData().content));
+ userID = val(requestData.UserID ?: 0);
+
+ if (userID == 0 && structKeyExists(request, "UserID")) {
+ userID = val(request.UserID);
+ }
+
+ if (userID == 0) {
+ response["ERROR"] = "missing_params";
+ response["MESSAGE"] = "UserID is required.";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ qUser = queryExecute("
+ SELECT StripeConnectedAccountID, EmailAddress, FirstName, LastName
+ FROM Users WHERE ID = :userID
+ ", { userID: userID }, { datasource: "payfrit" });
+
+ if (qUser.recordCount == 0) {
+ response["ERROR"] = "user_not_found";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ existingAccountID = qUser.StripeConnectedAccountID ?: "";
+
+ if (len(trim(existingAccountID)) > 0) {
+ // Already has an account
+ response["OK"] = true;
+ response["ACCOUNT_ID"] = existingAccountID;
+ response["CREATED"] = false;
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ // Create new Stripe Connect Express account
+ stripeSecretKey = application.stripeSecretKey ?: "";
+
+ httpService = new http();
+ httpService.setMethod("POST");
+ httpService.setUrl("https://api.stripe.com/v1/accounts");
+ httpService.setUsername(stripeSecretKey);
+ httpService.setPassword("");
+
+ httpService.addParam(type="formfield", name="type", value="express");
+ httpService.addParam(type="formfield", name="country", value="US");
+
+ userEmail = qUser.EmailAddress ?: "";
+ if (len(trim(userEmail)) > 0) {
+ httpService.addParam(type="formfield", name="email", value=userEmail);
+ }
+
+ httpService.addParam(type="formfield", name="capabilities[transfers][requested]", value="true");
+ httpService.addParam(type="formfield", name="metadata[user_id]", value=userID);
+
+ result = httpService.send().getPrefix();
+ acctData = deserializeJSON(result.fileContent);
+
+ if (structKeyExists(acctData, "error")) {
+ response["ERROR"] = acctData.error.message;
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ newAccountID = acctData.id;
+
+ // Save to Users table
+ queryExecute("
+ UPDATE Users SET StripeConnectedAccountID = :acctID WHERE ID = :userID
+ ", { acctID: newAccountID, userID: userID }, { datasource: "payfrit" });
+
+ response["OK"] = true;
+ response["ACCOUNT_ID"] = newAccountID;
+ response["CREATED"] = true;
+
+} catch (any e) {
+ response["ERROR"] = e.message;
+}
+
+writeOutput(serializeJSON(response));
+
diff --git a/api/workers/earlyUnlock.cfm b/api/workers/earlyUnlock.cfm
new file mode 100644
index 0000000..41cd975
--- /dev/null
+++ b/api/workers/earlyUnlock.cfm
@@ -0,0 +1,85 @@
+
+
+
+
+
+/**
+ * Create Stripe Checkout Session for activation early unlock.
+ * Worker pays remaining activation balance via card.
+ */
+
+response = { "OK": false };
+
+try {
+ requestData = deserializeJSON(toString(getHttpRequestData().content));
+ userID = val(requestData.UserID ?: 0);
+
+ if (userID == 0 && structKeyExists(request, "UserID")) {
+ userID = val(request.UserID);
+ }
+
+ if (userID == 0) {
+ response["ERROR"] = "missing_params";
+ response["MESSAGE"] = "UserID is required.";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ qUser = queryExecute("
+ SELECT ActivationBalanceCents, ActivationCapCents
+ FROM Users WHERE ID = :userID
+ ", { userID: userID }, { datasource: "payfrit" });
+
+ if (qUser.recordCount == 0) {
+ response["ERROR"] = "user_not_found";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ remainingCents = val(qUser.ActivationCapCents) - val(qUser.ActivationBalanceCents);
+
+ if (remainingCents <= 0) {
+ response["OK"] = true;
+ response["ALREADY_COMPLETE"] = true;
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ // Create Stripe Checkout Session
+ stripeSecretKey = application.stripeSecretKey ?: "";
+
+ httpService = new http();
+ httpService.setMethod("POST");
+ httpService.setUrl("https://api.stripe.com/v1/checkout/sessions");
+ httpService.setUsername(stripeSecretKey);
+ httpService.setPassword("");
+
+ httpService.addParam(type="formfield", name="mode", value="payment");
+ httpService.addParam(type="formfield", name="line_items[0][price_data][unit_amount]", value=remainingCents);
+ httpService.addParam(type="formfield", name="line_items[0][price_data][currency]", value="usd");
+ httpService.addParam(type="formfield", name="line_items[0][price_data][product_data][name]", value="Payfrit Activation");
+ httpService.addParam(type="formfield", name="line_items[0][quantity]", value="1");
+ httpService.addParam(type="formfield", name="success_url", value="https://biz.payfrit.com/works/activation?success=1");
+ httpService.addParam(type="formfield", name="cancel_url", value="https://biz.payfrit.com/works/activation?cancel=1");
+ httpService.addParam(type="formfield", name="metadata[user_id]", value=userID);
+ httpService.addParam(type="formfield", name="metadata[type]", value="activation_unlock");
+
+ result = httpService.send().getPrefix();
+ sessionData = deserializeJSON(result.fileContent);
+
+ if (structKeyExists(sessionData, "error")) {
+ response["ERROR"] = sessionData.error.message;
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ response["OK"] = true;
+ response["CHECKOUT_URL"] = sessionData.url;
+ response["AMOUNT_DUE_CENTS"] = remainingCents;
+
+} catch (any e) {
+ response["ERROR"] = e.message;
+}
+
+writeOutput(serializeJSON(response));
+
diff --git a/api/workers/ledger.cfm b/api/workers/ledger.cfm
new file mode 100644
index 0000000..6dbc153
--- /dev/null
+++ b/api/workers/ledger.cfm
@@ -0,0 +1,72 @@
+
+
+
+
+
+/**
+ * Read-only worker earnings/payout ledger.
+ */
+
+response = { "OK": false };
+
+try {
+ requestData = deserializeJSON(toString(getHttpRequestData().content));
+ userID = val(requestData.UserID ?: 0);
+
+ if (userID == 0 && structKeyExists(request, "UserID")) {
+ userID = val(request.UserID);
+ }
+
+ if (userID == 0) {
+ response["ERROR"] = "missing_params";
+ response["MESSAGE"] = "UserID is required.";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ // Get ledger entries (most recent first)
+ qLedger = queryExecute("
+ SELECT TaskID, GrossEarningsCents, ActivationWithheldCents,
+ NetTransferCents, Status, CreatedAt
+ FROM WorkPayoutLedgers
+ WHERE UserID = :userID
+ ORDER BY CreatedAt DESC
+ LIMIT 100
+ ", { userID: userID }, { datasource: "payfrit" });
+
+ // Get totals
+ qTotals = queryExecute("
+ SELECT
+ COALESCE(SUM(GrossEarningsCents), 0) AS TotalGrossCents,
+ COALESCE(SUM(ActivationWithheldCents), 0) AS TotalWithheldCents,
+ COALESCE(SUM(CASE WHEN Status = 'transferred' THEN NetTransferCents ELSE 0 END), 0) AS TotalTransferredCents
+ FROM WorkPayoutLedgers
+ WHERE UserID = :userID
+ ", { userID: userID }, { datasource: "payfrit" });
+
+ ledgerEntries = [];
+ for (row in qLedger) {
+ arrayAppend(ledgerEntries, {
+ "TaskID": row.TaskID,
+ "GrossEarningsCents": row.GrossEarningsCents,
+ "ActivationWithheldCents": row.ActivationWithheldCents,
+ "NetTransferCents": row.NetTransferCents,
+ "Status": row.Status,
+ "CreatedAt": dateTimeFormat(row.CreatedAt, "yyyy-MM-dd'T'HH:nn:ss")
+ });
+ }
+
+ response["OK"] = true;
+ response["LEDGER"] = ledgerEntries;
+ response["TOTALS"] = {
+ "TotalGrossCents": val(qTotals.TotalGrossCents),
+ "TotalWithheldCents": val(qTotals.TotalWithheldCents),
+ "TotalTransferredCents": val(qTotals.TotalTransferredCents)
+ };
+
+} catch (any e) {
+ response["ERROR"] = e.message;
+}
+
+writeOutput(serializeJSON(response));
+
diff --git a/api/workers/myBusinesses.cfm b/api/workers/myBusinesses.cfm
index 1915381..0bda0a5 100644
--- a/api/workers/myBusinesses.cfm
+++ b/api/workers/myBusinesses.cfm
@@ -36,17 +36,17 @@
@@ -54,11 +54,11 @@
diff --git a/api/workers/onboardingLink.cfm b/api/workers/onboardingLink.cfm
new file mode 100644
index 0000000..7ca0b91
--- /dev/null
+++ b/api/workers/onboardingLink.cfm
@@ -0,0 +1,77 @@
+
+
+
+
+
+/**
+ * Generate Stripe-hosted onboarding link for worker's connected account.
+ */
+
+response = { "OK": false };
+
+try {
+ requestData = deserializeJSON(toString(getHttpRequestData().content));
+ userID = val(requestData.UserID ?: 0);
+
+ if (userID == 0 && structKeyExists(request, "UserID")) {
+ userID = val(request.UserID);
+ }
+
+ if (userID == 0) {
+ response["ERROR"] = "missing_params";
+ response["MESSAGE"] = "UserID is required.";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ qUser = queryExecute("
+ SELECT StripeConnectedAccountID FROM Users WHERE ID = :userID
+ ", { userID: userID }, { datasource: "payfrit" });
+
+ if (qUser.recordCount == 0) {
+ response["ERROR"] = "user_not_found";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ accountID = qUser.StripeConnectedAccountID ?: "";
+
+ if (len(trim(accountID)) == 0) {
+ response["ERROR"] = "no_stripe_account";
+ response["MESSAGE"] = "Create a Stripe account first.";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ // Create Account Link for onboarding
+ stripeSecretKey = application.stripeSecretKey ?: "";
+
+ httpService = new http();
+ httpService.setMethod("POST");
+ httpService.setUrl("https://api.stripe.com/v1/account_links");
+ httpService.setUsername(stripeSecretKey);
+ httpService.setPassword("");
+
+ httpService.addParam(type="formfield", name="account", value=accountID);
+ httpService.addParam(type="formfield", name="refresh_url", value="https://biz.payfrit.com/works/tier?refresh=1");
+ httpService.addParam(type="formfield", name="return_url", value="https://biz.payfrit.com/works/tier?return=1");
+ httpService.addParam(type="formfield", name="type", value="account_onboarding");
+
+ result = httpService.send().getPrefix();
+ linkData = deserializeJSON(result.fileContent);
+
+ if (structKeyExists(linkData, "error")) {
+ response["ERROR"] = linkData.error.message;
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ response["OK"] = true;
+ response["ONBOARDING_URL"] = linkData.url;
+
+} catch (any e) {
+ response["ERROR"] = e.message;
+}
+
+writeOutput(serializeJSON(response));
+
diff --git a/api/workers/tierStatus.cfm b/api/workers/tierStatus.cfm
new file mode 100644
index 0000000..6756097
--- /dev/null
+++ b/api/workers/tierStatus.cfm
@@ -0,0 +1,72 @@
+
+
+
+
+
+/**
+ * Worker Tier + Activation Status
+ * Returns cached DB state. No Stripe polling.
+ * Tier is derived: payoutsEnabled ? 1 : 0
+ */
+
+response = { "OK": false };
+
+try {
+ requestData = deserializeJSON(toString(getHttpRequestData().content));
+ userID = val(requestData.UserID ?: 0);
+
+ // Fallback to auth header
+ if (userID == 0 && structKeyExists(request, "UserID")) {
+ userID = val(request.UserID);
+ }
+
+ if (userID == 0) {
+ response["ERROR"] = "missing_params";
+ response["MESSAGE"] = "UserID is required.";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ qUser = queryExecute("
+ SELECT StripeConnectedAccountID, StripePayoutsEnabled,
+ ActivationBalanceCents, ActivationCapCents
+ FROM Users WHERE ID = :userID
+ ", { userID: userID }, { datasource: "payfrit" });
+
+ if (qUser.recordCount == 0) {
+ response["ERROR"] = "user_not_found";
+ writeOutput(serializeJSON(response));
+ abort;
+ }
+
+ payoutsEnabled = qUser.StripePayoutsEnabled == 1;
+ hasAccount = len(trim(qUser.StripeConnectedAccountID ?: "")) > 0;
+ balanceCents = val(qUser.ActivationBalanceCents);
+ capCents = val(qUser.ActivationCapCents);
+ remainingCents = capCents - balanceCents;
+ if (remainingCents < 0) remainingCents = 0;
+ isComplete = (remainingCents == 0);
+ progressPercent = capCents > 0 ? round((balanceCents / capCents) * 100) : 100;
+ if (progressPercent > 100) progressPercent = 100;
+
+ response["OK"] = true;
+ response["TIER"] = payoutsEnabled ? 1 : 0;
+ response["STRIPE"] = {
+ "HasAccount": hasAccount,
+ "PayoutsEnabled": payoutsEnabled,
+ "SetupIncomplete": hasAccount && !payoutsEnabled
+ };
+ response["ACTIVATION"] = {
+ "BalanceCents": balanceCents,
+ "CapCents": capCents,
+ "RemainingCents": remainingCents,
+ "IsComplete": isComplete,
+ "ProgressPercent": progressPercent
+ };
+
+} catch (any e) {
+ response["ERROR"] = e.message;
+}
+
+writeOutput(serializeJSON(response));
+
diff --git a/confirm.cfm b/confirm.cfm
index fe32e31..7fc8b23 100644
--- a/confirm.cfm
+++ b/confirm.cfm
@@ -6,11 +6,11 @@
- SELECT UserID
+ SELECT ID
FROM Users
- WHERE UserUUID = '#url.UUID#'
+ WHERE UUID = '#url.UUID#'
AND
- UserIsEmailVerified = 0
+ IsEmailVerified = 0
@@ -18,14 +18,14 @@
UPDATE Users
SET IsEmailVerified = 1
- WHERE UserID = '#get_user.UserID#'
+ WHERE UserID = '#get_user.ID#'
-
+
@@ -47,9 +47,9 @@
- SELECT UserID
+ SELECT ID
FROM Users
- WHERE UserUUID = '#url.UUID#'
+ WHERE UUID = '#url.UUID#'
AND
IsEmailVerified = 1
diff --git a/confirm_email.cfm b/confirm_email.cfm
index e5f281a..896421e 100644
--- a/confirm_email.cfm
+++ b/confirm_email.cfm
@@ -6,28 +6,27 @@
- SELECT UserID, UserEmailAddress
- FROM Users
- WHERE UserUUID = '#url.UUID#'
+ ID AS UserID
+ WHERE UUID = '#url.UUID#'
AND
- UserIsEmailVerified = 0
+ IsEmailVerified = 0
AND
- UserIsContactVerified > 0
+ IsContactVerified > 0
UPDATE Users
- SET UserIsEmailVerified = 1
- WHERE UserID = '#get_user.UserID#'
+ SET IsEmailVerified = 1
+ WHERE UserID = '#get_user.ID#'
-
+
@@ -35,7 +34,7 @@
@@ -49,20 +48,19 @@
- SELECT UserID, UserContactNumber
- FROM Users
- WHERE UserUUID = '#url.UUID#'
+ ID AS UserID
+ WHERE UUID = '#url.UUID#'
AND
- UserIsEmailVerified = 0
+ IsEmailVerified = 0
AND
- UserIsContactVerified = 0
+ IsContactVerified = 0
UPDATE Users
- SET UserIsEmailVerified = 1
+ SET IsEmailVerified = 1
WHERE UserID = '#get_confirmed_customer.UserID#'
@@ -72,11 +70,11 @@
UPDATE Users
- SET UserMobileVerifyCode = '#customer_OPT_confirm#'
+ SET MobileVerifyCode = '#customer_OPT_confirm#'
WHERE UserID = #get_confirmed_customer.UserID#
- we sent a six-digit code to #get_confirmed_customer.UserContactNumber#, please input that code here:
+ we sent a six-digit code to #get_confirmed_customer.ContactNumber#, please input that code here:
-
- SELECT I.ItemName, OL.OrderLineItemQuantity, OL.OrderLineItemRemark, O.OrderAddedOn, OL.OrderLineItemID, O.OrderID, O.OrderRemarks, C.CategoryName
+ SELECT I.Name, OL.Quantity, OL.Remark, O.AddedOn, OL.ID, O.ID, O.Remarks, C.Name
FROM Orders O, OrderLineItems OL, Items I, Categories C
- WHERE O.OrderStatusID = 1
+ WHERE O.StatusID = 1
AND
- OL.OrderLineItemItemID = I.ItemID
+ OL.ItemID = I.ID
AND
- OL.OrderLineItemIsDeleted = 0
+ OL.IsDeleted = 0
AND
- OL.OrderLineItemParentOrderLineItemID = 0
+ OL.ParentOrderLineItemID = 0
AND
- I.ItemCategoryID = C.CategoryID
+ I.CategoryID = C.ID
AND
- O.OrderID = #get_orders.OrderID#
+ O.ID = #get_orders.ID#
AND
- O.OrderID = OL.OrderLineItemOrderID
+ O.ID = OL.OrderID
-
+
- ORDER ON: #dateformat(get_line_items.OrderAddedOn,"YYYY-MM-DD")# @ #timeformat(get_line_items.OrderAddedOn,"HH:NN:SS")#
- (#get_line_items.OrderLineItemQuantity#) #CategoryName# : #get_line_items.ItemName#
- ORDER NOTES: #get_line_items.OrderRemarks#
+ ORDER ON: #dateformat(get_line_items.AddedOn,"YYYY-MM-DD")# @ #timeformat(get_line_items.AddedOn,"HH:NN:SS")#
+ (#get_line_items.Quantity#) #Name# : #get_line_items.Name#
+ ORDER NOTES: #get_line_items.Remarks#
- SELECT I.ItemName, I.ItemID, I.ItemPrice, I.ItemParentItemID, O.OrderLineItemParentOrderLineItemID, O.OrderLineItemRemark
+ SELECT I.Name, I.ID, I.Price, I.ParentItemID, O.ParentOrderLineItemID, O.Remark
FROM OrderLineItems O, Items I
- WHERE OrderLineItemOrderID = #get_line_items.OrderID#
+ WHERE OrderID = #get_line_items.OrderID#
AND
- O.OrderLineItemItemID = I.ItemID
+ O.ItemID = I.ID
AND
- OrderLineItemParentOrderLineItemID = #get_line_items.OrderLineItemID#
- ORDER BY OrderLineItemAddedOn DESC
+ ParentOrderLineItemID = #get_line_items.OrderLineItemID#
+ ORDER BY AddedOn DESC
- SELECT ItemName
+ SELECT Name
FROM Items
- WHERE ItemID = #get_child_line_items.ItemParentItemID#
+ WHERE ID = #get_child_line_items.ParentItemID#
- #get_parent_item_Name.ItemName# : #get_child_line_items.ItemName#
- ITEM NOTES: #get_line_items.OrderLineItemRemark#
+ #get_parent_item_Name.Name# : #get_child_line_items.Name#
+ ITEM NOTES: #get_line_items.Remark#
@@ -213,57 +213,57 @@
Kitchen items being prepared:
- SELECT O.OrderID
+ SELECT O.ID
FROM Orders O, Businesses B
- WHERE O.OrderStatusID = 2
+ WHERE O.StatusID = 2
AND
- O.OrderBusinessID = B.BusinessID
+ O.BusinessID = B.ID
AND
- B.BusinessID = #request.BusinessID#
- ORDER BY O.OrderAddedOn ASC
+ B.ID = #request.BusinessID#
+ ORDER BY O.AddedOn ASC
-
+
-
- SELECT I.ItemName, OL.OrderLineItemQuantity, O.OrderAddedOn, OL.OrderLineItemID
+ SELECT I.Name, OL.Quantity, O.AddedOn, OL.ID
FROM Orders O, OrderLineItems OL, Items I
- WHERE O.OrderStatusID = 2
+ WHERE O.StatusID = 2
AND
- OL.OrderLineItemStatusID = 2
+ OL.StatusID = 2
AND
- OL.OrderLineItemItemID = I.ItemID
+ OL.ItemID = I.ID
AND
- OL.OrderLineItemIsDeleted = 0
+ OL.IsDeleted = 0
AND
- O.OrderID = #get_orders.OrderID#
+ O.ID = #get_orders.ID#
AND
- O.OrderID = OL.OrderLineItemOrderID
+ O.ID = OL.OrderID
-
+
-
(#get_line_items.OrderLineItemQuantity#) #get_line_items.ItemName# #dateformat(get_line_items.OrderAddedOn,"YYYY-MM-DD")# @ #timeformat(get_line_items.OrderAddedOn,"HH:NN:SS")#
+ (#get_line_items.Quantity#) #get_line_items.Name# #dateformat(get_line_items.AddedOn,"YYYY-MM-DD")# @ #timeformat(get_line_items.AddedOn,"HH:NN:SS")#
-
@@ -479,12 +479,12 @@
- SELECT B.BusinessName
+ SELECT B.Name
FROM Businesses B
- WHERE B.BusinessID = #request.BusinessID#
+ WHERE B.ID = #request.BusinessID#
- You are logged in as #get_biz_name.BusinessName#
+ You are logged in as #get_biz_name.Name#
@@ -494,28 +494,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+