Replace queryExecute with queryTimed across all endpoints for perf tracking
Converts 200+ endpoint files to use queryTimed() wrapper which tracks DB query count and execution time. Restores perf dashboard files that were accidentally moved to _scripts/. Includes portal UI updates.
This commit is contained in:
parent
f52d14bb7e
commit
16a3b7c9a3
206 changed files with 6275 additions and 5754 deletions
|
|
@ -103,6 +103,8 @@ if (len(request._api_path)) {
|
|||
if (findNoCase("/api/auth/verifyOTP.cfm", request._api_path)) request._api_isPublic = true;
|
||||
if (findNoCase("/api/auth/loginOTP.cfm", request._api_path)) request._api_isPublic = true;
|
||||
if (findNoCase("/api/auth/verifyLoginOTP.cfm", request._api_path)) request._api_isPublic = true;
|
||||
if (findNoCase("/api/auth/sendLoginOTP.cfm", request._api_path)) request._api_isPublic = true;
|
||||
if (findNoCase("/api/auth/verifyEmailOTP.cfm", request._api_path)) request._api_isPublic = true;
|
||||
if (findNoCase("/api/auth/completeProfile.cfm", request._api_path)) request._api_isPublic = true;
|
||||
|
||||
if (findNoCase("/api/businesses/list.cfm", request._api_path)) request._api_isPublic = true;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ try {
|
|||
|
||||
// If setting as default, clear other defaults first (for same type)
|
||||
if (setAsDefault) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Addresses
|
||||
SET IsDefaultDelivery = 0
|
||||
WHERE UserID = :userId
|
||||
|
|
@ -68,11 +68,11 @@ try {
|
|||
}
|
||||
|
||||
// Get next AddressID
|
||||
qNext = queryExecute("SELECT IFNULL(MAX(ID), 0) + 1 AS NextID FROM Addresses", {}, { datasource: "payfrit" });
|
||||
qNext = queryTimed("SELECT IFNULL(MAX(ID), 0) + 1 AS NextID FROM Addresses", {}, { datasource: "payfrit" });
|
||||
newAddressId = qNext.NextID;
|
||||
|
||||
// Insert new address
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Addresses (
|
||||
ID,
|
||||
UserID,
|
||||
|
|
@ -117,7 +117,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Get state info for response
|
||||
qState = queryExecute("SELECT Abbreviation as StateAbbreviation, Name as StateName FROM tt_States WHERE ID = :stateId", {
|
||||
qState = queryTimed("SELECT Abbreviation as StateAbbreviation, Name as StateName FROM tt_States WHERE ID = :stateId", {
|
||||
stateId: { value: stateId, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U
|
|||
userToken = getHeader("X-User-Token");
|
||||
if (len(userToken)) {
|
||||
try {
|
||||
qTok = queryExecute(
|
||||
qTok = queryTimed(
|
||||
"SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1",
|
||||
[{ value = userToken, cfsqltype = "cf_sql_varchar" }],
|
||||
{ datasource = "payfrit" }
|
||||
|
|
@ -75,7 +75,7 @@ if (addressId <= 0) {
|
|||
|
||||
try {
|
||||
// First, get the address details so we can find all matching duplicates
|
||||
qAddr = queryExecute("
|
||||
qAddr = queryTimed("
|
||||
SELECT Line1, Line2, City, StateID, ZIPCode
|
||||
FROM Addresses
|
||||
WHERE ID = :addressId
|
||||
|
|
@ -91,7 +91,7 @@ try {
|
|||
}
|
||||
|
||||
// Soft-delete ALL addresses that match the same Line1, Line2, City, StateID, ZIPCode
|
||||
qDelete = queryExecute("
|
||||
qDelete = queryTimed("
|
||||
UPDATE Addresses
|
||||
SET IsDeleted = 1
|
||||
WHERE UserID = :userId
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U
|
|||
userToken = getHeader("X-User-Token");
|
||||
if (len(userToken)) {
|
||||
try {
|
||||
qTok = queryExecute(
|
||||
qTok = queryTimed(
|
||||
"SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1",
|
||||
[{ value = userToken, cfsqltype = "cf_sql_varchar" }],
|
||||
{ datasource = "payfrit" }
|
||||
|
|
@ -47,7 +47,7 @@ if (userId <= 0) {
|
|||
|
||||
try {
|
||||
// Get user's delivery addresses
|
||||
qAddresses = queryExecute("
|
||||
qAddresses = queryTimed("
|
||||
SELECT
|
||||
a.ID,
|
||||
a.IsDefaultDelivery,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ try {
|
|||
}
|
||||
|
||||
// Verify address belongs to user
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT ID
|
||||
FROM Addresses
|
||||
WHERE ID = :addressId
|
||||
|
|
@ -61,7 +61,7 @@ try {
|
|||
}
|
||||
|
||||
// Clear all defaults for this user
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Addresses
|
||||
SET IsDefaultDelivery = 0
|
||||
WHERE UserID = :userId
|
||||
|
|
@ -72,7 +72,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Set this one as default
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Addresses
|
||||
SET IsDefaultDelivery = 1
|
||||
WHERE ID = :addressId
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<!--- List US states for address forms --->
|
||||
<cfscript>
|
||||
try {
|
||||
qStates = queryExecute("
|
||||
qStates = queryTimed("
|
||||
SELECT ID as StateID, Abbreviation as StateAbbreviation, Name as StateName
|
||||
FROM tt_States
|
||||
ORDER BY Name
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
try {
|
||||
qTypes = queryExecute("
|
||||
qTypes = queryTimed("
|
||||
SELECT tt_AddressTypeID as ID, tt_AddressType as Label
|
||||
FROM tt_AddressTypes
|
||||
ORDER BY tt_AddressTypeID
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Add IsActive column to TaskCategories table
|
||||
try {
|
||||
// Check if column exists
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
AND TABLE_NAME = 'TaskCategories'
|
||||
|
|
@ -13,7 +13,7 @@ try {
|
|||
", [], { datasource: "payfrit" });
|
||||
|
||||
if (qCheck.recordCount == 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE TaskCategories
|
||||
ADD COLUMN IsActive TINYINT(1) NOT NULL DEFAULT 1
|
||||
", [], { datasource: "payfrit" });
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ response = { "OK": false };
|
|||
|
||||
try {
|
||||
// Check if columns already exist
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
|
|
@ -33,7 +33,7 @@ try {
|
|||
|
||||
// Add ScheduleStart if not exists
|
||||
if (!listFindNoCase(existingCols, "ScheduleStart")) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Categories
|
||||
ADD COLUMN ScheduleStart TIME NULL
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
|
@ -42,7 +42,7 @@ try {
|
|||
|
||||
// Add ScheduleEnd if not exists
|
||||
if (!listFindNoCase(existingCols, "ScheduleEnd")) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Categories
|
||||
ADD COLUMN ScheduleEnd TIME NULL
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
|
@ -51,7 +51,7 @@ try {
|
|||
|
||||
// Add ScheduleDays if not exists
|
||||
if (!listFindNoCase(existingCols, "ScheduleDays")) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Categories
|
||||
ADD COLUMN ScheduleDays VARCHAR(20) NULL
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ try {
|
|||
bigDeansBusinessId = 27;
|
||||
|
||||
// Find the Fountain Soda item we created
|
||||
qFountain = queryExecute("
|
||||
qFountain = queryTimed("
|
||||
SELECT ID, Name FROM Items
|
||||
WHERE BusinessID = :bizId AND Name = 'Fountain Soda'
|
||||
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
||||
|
|
@ -29,14 +29,14 @@ try {
|
|||
response["FountainSodaID"] = fountainId;
|
||||
|
||||
// Update Fountain Soda to require child selection and be collapsible
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET RequiresChildSelection = 1, IsCollapsible = 1
|
||||
WHERE ID = :itemId
|
||||
", { itemId: fountainId }, { datasource: "payfrit" });
|
||||
|
||||
// Check if modifiers already exist
|
||||
qExisting = queryExecute("
|
||||
qExisting = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Items WHERE ParentItemID = :parentId
|
||||
", { parentId: fountainId }, { datasource: "payfrit" });
|
||||
|
||||
|
|
@ -48,10 +48,10 @@ try {
|
|||
}
|
||||
|
||||
// Add Size group
|
||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
sizeGroupId = qMaxItem.nextId;
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
ID, BusinessID, CategoryID, ParentItemID,
|
||||
Name, Description, Price, IsActive,
|
||||
|
|
@ -77,8 +77,8 @@ try {
|
|||
|
||||
sizesAdded = 0;
|
||||
for (size in sizes) {
|
||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
queryExecute("
|
||||
qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||
Name, Description, Price, IsActive,
|
||||
|
|
@ -103,10 +103,10 @@ try {
|
|||
}
|
||||
|
||||
// Add Type/Flavor group
|
||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
typeGroupId = qMaxItem.nextId;
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
ID, BusinessID, CategoryID, ParentItemID,
|
||||
Name, Description, Price, IsActive,
|
||||
|
|
@ -136,8 +136,8 @@ try {
|
|||
|
||||
typesAdded = 0;
|
||||
for (type in types) {
|
||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
queryExecute("
|
||||
qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||
Name, Description, Price, IsActive,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ response = { "OK": false };
|
|||
|
||||
try {
|
||||
// Check if column already exists
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
|
|
@ -25,14 +25,14 @@ try {
|
|||
response["MESSAGE"] = "CategoryID column already exists";
|
||||
} else {
|
||||
// Add the column
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Items
|
||||
ADD COLUMN CategoryID INT NULL DEFAULT 0 AFTER ParentItemID
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
||||
// Add index for performance
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE INDEX idx_items_categoryid ON Items(CategoryID)
|
||||
", {}, { datasource: "payfrit" });
|
||||
} catch (any indexErr) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<cfscript>
|
||||
try {
|
||||
// Check if columns already exist
|
||||
checkCols = queryExecute(
|
||||
checkCols = queryTimed(
|
||||
"SHOW COLUMNS FROM Addresses LIKE 'Latitude'",
|
||||
[],
|
||||
{ datasource = "payfrit" }
|
||||
|
|
@ -13,7 +13,7 @@ try {
|
|||
|
||||
if (checkCols.recordCount EQ 0) {
|
||||
// Add the columns
|
||||
queryExecute(
|
||||
queryTimed(
|
||||
"ALTER TABLE Addresses
|
||||
ADD COLUMN Latitude DECIMAL(10,7) NULL,
|
||||
ADD COLUMN Longitude DECIMAL(10,7) NULL",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Add CategoryID column to tt_TaskTypes (Services) table
|
||||
try {
|
||||
// Check if column exists
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
AND TABLE_NAME = 'tt_TaskTypes'
|
||||
|
|
@ -13,7 +13,7 @@ try {
|
|||
", [], { datasource: "payfrit" });
|
||||
|
||||
if (qCheck.recordCount == 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE tt_TaskTypes
|
||||
ADD COLUMN TaskCategoryID INT NULL
|
||||
", [], { datasource: "payfrit" });
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ result = { "OK": true, "STEPS": [] };
|
|||
|
||||
try {
|
||||
// Check if columns already exist
|
||||
cols = queryExecute("
|
||||
cols = queryTimed("
|
||||
SELECT COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
|
|
@ -23,7 +23,7 @@ try {
|
|||
|
||||
// Add SourceType if missing
|
||||
if (!listFindNoCase(existingCols, "SourceType")) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Tasks ADD COLUMN SourceType VARCHAR(50) NULL
|
||||
", [], { datasource: "payfrit" });
|
||||
arrayAppend(result.STEPS, "Added SourceType column");
|
||||
|
|
@ -33,7 +33,7 @@ try {
|
|||
|
||||
// Add SourceID if missing
|
||||
if (!listFindNoCase(existingCols, "SourceID")) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Tasks ADD COLUMN SourceID INT NULL
|
||||
", [], { datasource: "payfrit" });
|
||||
arrayAppend(result.STEPS, "Added SourceID column");
|
||||
|
|
@ -42,7 +42,7 @@ try {
|
|||
}
|
||||
|
||||
// Verify columns now exist
|
||||
verifyQuery = queryExecute("
|
||||
verifyQuery = queryTimed("
|
||||
SELECT COLUMN_NAME, DATA_TYPE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<cfscript>
|
||||
// Show all beacons with their current business/service point assignments
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT
|
||||
b.ID,
|
||||
b.UUID,
|
||||
|
|
@ -35,7 +35,7 @@ for (row in q) {
|
|||
}
|
||||
|
||||
// Also get service points for reference
|
||||
spQuery = queryExecute("
|
||||
spQuery = queryTimed("
|
||||
SELECT sp.ID, sp.Name AS Name, sp.BusinessID AS BusinessID, b.Name AS Name
|
||||
FROM ServicePoints sp
|
||||
JOIN Businesses b ON b.ID = sp.BusinessID
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
<cfscript>
|
||||
// Check Big Dean's owner
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT b.ID, b.Name, b.UserID
|
||||
FROM Businesses b
|
||||
WHERE b.ID = 27
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
||||
// Get users
|
||||
users = queryExecute("
|
||||
users = queryTimed("
|
||||
SELECT *
|
||||
FROM Users
|
||||
ORDER BY ID
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ if (!len(phone)) {
|
|||
abort;
|
||||
}
|
||||
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT ID, FirstName, LastName, EmailAddress, ContactNumber, IsContactVerified
|
||||
FROM Users
|
||||
WHERE ContactNumber = :phone OR EmailAddress = :phone
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ try {
|
|||
lazyDaisyID = 37;
|
||||
|
||||
// Unassign beacons 7, 8, 9 from any service points
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints
|
||||
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||
WHERE BeaconID IN (7, 8, 9) AND BusinessID = :bizId
|
||||
|
|
@ -23,33 +23,33 @@ try {
|
|||
response.steps.append("Unassigned beacons 7, 8, 9 from service points");
|
||||
|
||||
// Delete duplicate beacons 7, 8, 9
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM Beacons
|
||||
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
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
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("
|
||||
queryTimed("
|
||||
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("
|
||||
queryTimed("
|
||||
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("
|
||||
qFinal = queryTimed("
|
||||
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID,
|
||||
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||
biz.Name AS BusinessName
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ try {
|
|||
confirm = structKeyExists(url, "confirm") && url.confirm == "YES";
|
||||
|
||||
// Verification Step 1: Check for items without BusinessID
|
||||
qNoBusinessID = queryExecute("
|
||||
qNoBusinessID = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Items
|
||||
WHERE BusinessID IS NULL OR BusinessID = 0
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
|
@ -36,14 +36,14 @@ try {
|
|||
response.verification["itemsWithoutBusinessID"] = qNoBusinessID.cnt;
|
||||
|
||||
// Verification Step 2: Check that all categories were converted
|
||||
qCategories = queryExecute("
|
||||
qCategories = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Categories
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
||||
response.verification["categoriesRemaining"] = qCategories.cnt;
|
||||
|
||||
// Verification Step 3: Check category Items exist (ParentID=0 with children)
|
||||
qCategoryItems = queryExecute("
|
||||
qCategoryItems = queryTimed("
|
||||
SELECT COUNT(DISTINCT p.ItemID) as cnt
|
||||
FROM Items p
|
||||
INNER JOIN Items c ON c.ParentItemID = p.ItemID
|
||||
|
|
@ -57,7 +57,7 @@ try {
|
|||
response.verification["categoryItemsCreated"] = qCategoryItems.cnt;
|
||||
|
||||
// Verification Step 4: Check templates exist (in lt_ItemID_TemplateItemID)
|
||||
qTemplates = queryExecute("
|
||||
qTemplates = queryTimed("
|
||||
SELECT COUNT(DISTINCT tl.TemplateItemID) as cnt
|
||||
FROM lt_ItemID_TemplateItemID tl
|
||||
INNER JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||
|
|
@ -67,7 +67,7 @@ try {
|
|||
|
||||
// Verification Step 5: Find orphans at ParentID=0
|
||||
// Orphan = ParentID=0, no children pointing to it, not in lt_ItemID_TemplateItemID
|
||||
qOrphans = queryExecute("
|
||||
qOrphans = queryTimed("
|
||||
SELECT i.ID, i.Name, i.BusinessID
|
||||
FROM Items i
|
||||
WHERE i.ParentItemID = 0
|
||||
|
|
@ -121,7 +121,7 @@ try {
|
|||
|
||||
// Step 1: Drop CategoryID column
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Items DROP COLUMN CategoryID
|
||||
", {}, { datasource: "payfrit" });
|
||||
arrayAppend(response.steps, "Dropped CategoryID column from Items");
|
||||
|
|
@ -135,7 +135,7 @@ try {
|
|||
|
||||
// Step 2: Drop IsModifierTemplate column (now derived from lt_ItemID_TemplateItemID)
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Items DROP COLUMN IsModifierTemplate
|
||||
", {}, { datasource: "payfrit" });
|
||||
arrayAppend(response.steps, "Dropped IsModifierTemplate column from Items");
|
||||
|
|
@ -149,7 +149,7 @@ try {
|
|||
|
||||
// Step 3: Drop Categories table
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DROP TABLE Categories
|
||||
", {}, { datasource: "payfrit" });
|
||||
arrayAppend(response.steps, "Dropped Categories table");
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ if (businessId <= 0) {
|
|||
|
||||
try {
|
||||
// Find duplicate UserIDs for this business (keep the one with highest status or oldest)
|
||||
qDupes = queryExecute("
|
||||
qDupes = queryTimed("
|
||||
SELECT ID, COUNT(*) as cnt, MIN(ID) as keepId
|
||||
FROM Employees
|
||||
WHERE BusinessID = ?
|
||||
|
|
@ -44,7 +44,7 @@ try {
|
|||
deleted = 0;
|
||||
for (row in qDupes) {
|
||||
// Delete all but the one we want to keep (the one with lowest EmployeeID)
|
||||
qDel = queryExecute("
|
||||
qDel = queryTimed("
|
||||
DELETE FROM Employees
|
||||
WHERE BusinessID = ? AND UserID = ? AND ID != ?
|
||||
", [
|
||||
|
|
@ -56,7 +56,7 @@ try {
|
|||
}
|
||||
|
||||
// Get remaining employees
|
||||
qRemaining = queryExecute("
|
||||
qRemaining = queryTimed("
|
||||
SELECT e.ID, e.UserID, u.FirstName, u.LastName
|
||||
FROM Employees e
|
||||
JOIN Users u ON e.UserID = u.ID
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ try {
|
|||
keepBusinessID = 37;
|
||||
|
||||
// Unassign all beacons from service points of other businesses
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints
|
||||
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||
WHERE BusinessID != :keepID AND BeaconID IS NOT NULL
|
||||
|
|
@ -18,7 +18,7 @@ try {
|
|||
response.steps.append("Unassigned beacons from other businesses' service points");
|
||||
|
||||
// Get list of businesses to delete
|
||||
qBiz = queryExecute("
|
||||
qBiz = queryTimed("
|
||||
SELECT ID, Name FROM Businesses WHERE ID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ try {
|
|||
|
||||
// Delete related data first (foreign key constraints)
|
||||
// Delete lt_ItemID_TemplateItemID for items from other businesses
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE itl FROM lt_ItemID_TemplateItemID itl
|
||||
JOIN Items i ON i.ID = itl.ItemID
|
||||
WHERE i.BusinessID != :keepID
|
||||
|
|
@ -38,29 +38,29 @@ try {
|
|||
response.steps.append("Deleted lt_ItemID_TemplateItemID for other businesses");
|
||||
|
||||
// Delete Items for other businesses
|
||||
qItems = queryExecute("
|
||||
qItems = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Items WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
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("
|
||||
queryTimed("
|
||||
DELETE FROM Categories WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted categories from other businesses");
|
||||
|
||||
// Delete Hours for other businesses
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM Hours WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted hours from other businesses");
|
||||
|
||||
// Delete Employees for other businesses
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM Employees WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted employees from other businesses");
|
||||
|
|
@ -70,7 +70,7 @@ try {
|
|||
|
||||
// Delete ServicePoints for other businesses
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM ServicePoints WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted service points from other businesses");
|
||||
|
|
@ -80,7 +80,7 @@ try {
|
|||
|
||||
// Delete Stations for other businesses
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM Stations WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted stations from other businesses");
|
||||
|
|
@ -90,7 +90,7 @@ try {
|
|||
|
||||
// Delete beacon-business mappings for other businesses
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM lt_BeaconsID_BusinessesID WHERE BusinessID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted beacon mappings for other businesses");
|
||||
|
|
@ -99,13 +99,13 @@ try {
|
|||
}
|
||||
|
||||
// Finally delete the businesses themselves
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM Businesses WHERE ID != :keepID
|
||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||
response.steps.append("Deleted " & arrayLen(deletedBusinesses) & " businesses");
|
||||
|
||||
// Get beacon status
|
||||
qBeacons = queryExecute("
|
||||
qBeacons = queryTimed("
|
||||
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID,
|
||||
b.UUID, biz.Name AS BusinessName, sp.Name AS ServicePointName
|
||||
FROM ServicePoints sp
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ param name="url.itemId" default="11543";
|
|||
param name="url.action" default="check"; // "check" or "deactivate"
|
||||
|
||||
// Check the item first
|
||||
qItem = queryExecute("
|
||||
qItem = queryTimed("
|
||||
SELECT ID, Name, ParentItemID, IsActive, IsCollapsible
|
||||
FROM Items
|
||||
WHERE ID = :itemId
|
||||
|
|
@ -18,7 +18,7 @@ if (qItem.recordCount == 0) {
|
|||
}
|
||||
|
||||
// Get all children (direct only for display)
|
||||
qChildren = queryExecute("
|
||||
qChildren = queryTimed("
|
||||
SELECT ID, Name
|
||||
FROM Items
|
||||
WHERE ParentItemID = :itemId
|
||||
|
|
@ -46,14 +46,14 @@ result = {
|
|||
|
||||
if (url.action == "deactivate") {
|
||||
// Deactivate children first
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET IsActive = 0
|
||||
WHERE ParentItemID = :itemId
|
||||
", { itemId: url.itemId });
|
||||
|
||||
// Then deactivate the parent
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET IsActive = 0
|
||||
WHERE ItemID = :itemId
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
<cfscript>
|
||||
// Delete cart orders (status 0) to reset for testing
|
||||
result = queryExecute("
|
||||
result = queryTimed("
|
||||
DELETE FROM OrderLineItems
|
||||
WHERE OrderID IN (
|
||||
SELECT ID FROM Orders WHERE StatusID = 0
|
||||
)
|
||||
", {}, { datasource = "payfrit" });
|
||||
|
||||
result2 = queryExecute("
|
||||
result2 = queryTimed("
|
||||
DELETE FROM Orders WHERE StatusID = 0
|
||||
", {}, { datasource = "payfrit" });
|
||||
|
||||
|
|
|
|||
|
|
@ -11,26 +11,26 @@ try {
|
|||
|
||||
for (bizID in businessIDs) {
|
||||
// Delete lt_ItemID_TemplateItemID for items belonging to this business
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
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 BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM Items WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
|
||||
// Delete Categories
|
||||
queryExecute("DELETE FROM Categories WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM Categories WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
|
||||
// Delete Hours
|
||||
queryExecute("DELETE FROM Hours WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM Hours WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
|
||||
// Delete Addresses linked to this business
|
||||
queryExecute("DELETE FROM Addresses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM Addresses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
|
||||
// Delete the Business itself
|
||||
queryExecute("DELETE FROM Businesses WHERE ID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM Businesses WHERE ID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||
|
||||
response.steps.append("Deleted business " & bizID & " and all related data");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<cfscript>
|
||||
// Close all open chat tasks
|
||||
try {
|
||||
result = queryExecute("
|
||||
result = queryTimed("
|
||||
UPDATE Tasks
|
||||
SET CompletedOn = NOW()
|
||||
WHERE TaskTypeID = 2
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ try {
|
|||
bigDeansBusinessId = 27;
|
||||
|
||||
// First, check if Big Dean's has a Beverages/Drinks category
|
||||
qExistingCat = queryExecute("
|
||||
qExistingCat = queryTimed("
|
||||
SELECT ID, Name FROM Categories
|
||||
WHERE BusinessID = :bizId AND (Name LIKE '%Drink%' OR Name LIKE '%Beverage%')
|
||||
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
||||
|
|
@ -24,14 +24,14 @@ try {
|
|||
response["CategoryNote"] = "Using existing category: " & qExistingCat.Name;
|
||||
} else {
|
||||
// Create a new Beverages category for Big Dean's
|
||||
qMaxCat = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" });
|
||||
qMaxCat = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" });
|
||||
drinksCategoryId = qMaxCat.nextId;
|
||||
|
||||
qMaxSort = queryExecute("
|
||||
qMaxSort = queryTimed("
|
||||
SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort FROM Categories WHERE BusinessID = :bizId
|
||||
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Categories (ID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn)
|
||||
VALUES (:catId, :bizId, 0, 'Beverages', :sortOrder, NOW())
|
||||
", {
|
||||
|
|
@ -60,17 +60,17 @@ try {
|
|||
|
||||
for (drink in drinks) {
|
||||
// Check if item already exists
|
||||
qExists = queryExecute("
|
||||
qExists = queryTimed("
|
||||
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) {
|
||||
// Get next ItemID
|
||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
qMaxItem = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
newItemId = qMaxItem.nextId;
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
ID, BusinessID, CategoryID, ParentItemID,
|
||||
Name, Description, Price, IsActive,
|
||||
|
|
@ -100,8 +100,8 @@ try {
|
|||
flavors = ["Chocolate", "Vanilla", "Strawberry"];
|
||||
flavorSort = 0;
|
||||
for (flavor in flavors) {
|
||||
qMaxOpt = queryExecute("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
queryExecute("
|
||||
qMaxOpt = queryTimed("SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
ID, BusinessID, CategoryID, ParentItemID,
|
||||
Name, Description, Price, IsActive,
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ try {
|
|||
uuid = beaconUUIDs[i];
|
||||
|
||||
// Check if beacon exists
|
||||
qB = queryExecute("SELECT ID FROM Beacons WHERE UUID = :uuid", { uuid: uuid }, { datasource: "payfrit" });
|
||||
qB = queryTimed("SELECT ID FROM Beacons WHERE UUID = :uuid", { uuid: uuid }, { datasource: "payfrit" });
|
||||
|
||||
if (qB.recordCount == 0) {
|
||||
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" });
|
||||
queryTimed("INSERT INTO Beacons (UUID, BusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
qNew = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
beaconID = qNew.id;
|
||||
response.steps.append("Created beacon " & beaconID & " with UUID: " & uuid);
|
||||
} else {
|
||||
|
|
@ -34,17 +34,17 @@ try {
|
|||
}
|
||||
|
||||
// Get service point Table 1
|
||||
qSP = queryExecute("
|
||||
qSP = queryTimed("
|
||||
SELECT ID FROM ServicePoints
|
||||
WHERE BusinessID = :bizID AND Name = 'Table 1'
|
||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
|
||||
if (qSP.recordCount == 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO ServicePoints (BusinessID, Name)
|
||||
VALUES (:bizID, 'Table 1')
|
||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
qSP = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
servicePointID = qSP.id;
|
||||
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
|
||||
} else {
|
||||
|
|
@ -53,20 +53,20 @@ try {
|
|||
}
|
||||
|
||||
// Assign all beacons to the Table 1 service point
|
||||
qBeacons = queryExecute("SELECT ID, UUID FROM Beacons WHERE BusinessID = :bizID", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
qBeacons = queryTimed("SELECT ID, UUID FROM Beacons WHERE BusinessID = :bizID", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
|
||||
for (i = 1; i <= qBeacons.recordCount; i++) {
|
||||
beaconID = qBeacons.ID[i];
|
||||
|
||||
// Unassign this beacon from any existing service point
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL
|
||||
WHERE BeaconID = :beaconID
|
||||
|
||||
", { beaconID: beaconID }, { datasource: "payfrit" });
|
||||
|
||||
// Assign beacon to Table 1 service point
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1
|
||||
WHERE ID = :spID AND BusinessID = :bizID
|
||||
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
||||
|
|
@ -74,7 +74,7 @@ try {
|
|||
}
|
||||
|
||||
// Get final status
|
||||
qFinal = queryExecute("
|
||||
qFinal = queryTimed("
|
||||
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID,
|
||||
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||
biz.Name AS BusinessName
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<cfscript>
|
||||
try {
|
||||
// Create ChatMessages table
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE TABLE IF NOT EXISTS ChatMessages (
|
||||
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||
TaskID INT NOT NULL,
|
||||
|
|
@ -20,20 +20,20 @@ try {
|
|||
", {}, { datasource: "payfrit" });
|
||||
|
||||
// Also add a "Chat" category if it doesn't exist for business 17
|
||||
existing = queryExecute("
|
||||
existing = queryTimed("
|
||||
SELECT ID FROM TaskCategories
|
||||
WHERE BusinessID = 17 AND Name = 'Chat'
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
||||
if (existing.recordCount == 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO TaskCategories (BusinessID, Name, Color)
|
||||
VALUES (17, 'Chat', '##2196F3')
|
||||
", {}, { datasource: "payfrit" });
|
||||
}
|
||||
|
||||
// Verify table was created
|
||||
cols = queryExecute("DESCRIBE ChatMessages", {}, { datasource: "payfrit" });
|
||||
cols = queryTimed("DESCRIBE ChatMessages", {}, { datasource: "payfrit" });
|
||||
colNames = [];
|
||||
for (c in cols) {
|
||||
arrayAppend(colNames, c.Field);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ response = { "OK": false };
|
|||
|
||||
try {
|
||||
// Check if Menus table exists
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT 1 FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
AND TABLE_NAME = 'Menus'
|
||||
|
|
@ -29,7 +29,7 @@ try {
|
|||
response["MESSAGE"] = "Menus table already exists";
|
||||
} else {
|
||||
// Create Menus table
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE TABLE Menus (
|
||||
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||
BusinessID INT NOT NULL,
|
||||
|
|
@ -54,7 +54,7 @@ try {
|
|||
}
|
||||
|
||||
// Check if MenuID column exists in Categories table
|
||||
qCatCol = queryExecute("
|
||||
qCatCol = queryTimed("
|
||||
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
AND TABLE_NAME = 'Categories'
|
||||
|
|
@ -63,7 +63,7 @@ try {
|
|||
|
||||
if (qCatCol.recordCount == 0) {
|
||||
// Add MenuID column to Categories table
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Categories
|
||||
ADD COLUMN MenuID INT NULL DEFAULT NULL AFTER BusinessID,
|
||||
ADD INDEX idx_categories_menu (MenuID)
|
||||
|
|
|
|||
|
|
@ -55,18 +55,18 @@ try {
|
|||
}
|
||||
|
||||
// Create minimal address record (just a placeholder)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Addresses (Line1, UserID, AddressTypeID, AddedOn)
|
||||
VALUES ('Parent Business - No Physical Location', :userID, 2, NOW())
|
||||
", {
|
||||
userID: UserID
|
||||
}, { datasource = "payfrit" });
|
||||
|
||||
qAddr = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" });
|
||||
qAddr = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" });
|
||||
addressId = qAddr.id;
|
||||
|
||||
// Create parent business (no menu, no hours, just a shell)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Businesses (Name, UserID, AddressID, ParentBusinessID, BusinessDeliveryZipCodes, AddedOn)
|
||||
VALUES (:name, :userId, :addressId, NULL, '', NOW())
|
||||
", {
|
||||
|
|
@ -75,11 +75,11 @@ try {
|
|||
addressId: addressId
|
||||
}, { datasource = "payfrit" });
|
||||
|
||||
qBiz = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" });
|
||||
qBiz = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource = "payfrit" });
|
||||
newBusinessID = qBiz.id;
|
||||
|
||||
// Link address back to business
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Addresses SET BusinessID = :bizId WHERE ID = :addrId
|
||||
", {
|
||||
bizId: newBusinessID,
|
||||
|
|
@ -91,7 +91,7 @@ try {
|
|||
for (childID in ChildBusinessIDs) {
|
||||
childID = val(childID);
|
||||
if (childID > 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Businesses SET ParentBusinessID = :parentId WHERE ID = :childId
|
||||
", {
|
||||
parentId: newBusinessID,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ bizId = 27;
|
|||
// These are the items that were deactivated by fixBigDeansCategories.cfm
|
||||
deactivatedIds = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204, 11212, 11220, 11259];
|
||||
|
||||
qDeactivated = queryExecute("
|
||||
qDeactivated = queryTimed("
|
||||
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
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
bizId = 27;
|
||||
|
||||
// Get all template links for Big Dean's with item names
|
||||
qLinks = queryExecute("
|
||||
qLinks = queryTimed("
|
||||
SELECT
|
||||
tl.ItemID as MenuItemID,
|
||||
mi.Name as MenuName,
|
||||
|
|
@ -33,7 +33,7 @@ for (row in qLinks) {
|
|||
}
|
||||
|
||||
// Get burgers specifically (parent = 11271)
|
||||
qBurgers = queryExecute("
|
||||
qBurgers = queryTimed("
|
||||
SELECT ID, Name FROM Items
|
||||
WHERE BusinessID = :bizId AND ParentItemID = 11271 AND IsActive = 1
|
||||
ORDER BY SortOrder
|
||||
|
|
@ -42,7 +42,7 @@ qBurgers = queryExecute("
|
|||
burgers = [];
|
||||
for (row in qBurgers) {
|
||||
// Get templates for this burger
|
||||
qBurgerTemplates = queryExecute("
|
||||
qBurgerTemplates = queryTimed("
|
||||
SELECT tl.TemplateItemID, t.Name as TemplateName
|
||||
FROM lt_ItemID_TemplateItemID tl
|
||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
businessID = 27;
|
||||
|
||||
// Run the EXACT query from getForBuilder.cfm
|
||||
qCategories = queryExecute("
|
||||
qCategories = queryTimed("
|
||||
SELECT DISTINCT
|
||||
p.ItemID as CategoryID,
|
||||
p.Name as Name,
|
||||
|
|
@ -31,12 +31,12 @@ for (c in qCategories) {
|
|||
}
|
||||
|
||||
// Also check raw counts
|
||||
rawCount = queryExecute("
|
||||
rawCount = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Items
|
||||
WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsActive = 1
|
||||
", { bizId: businessID });
|
||||
|
||||
childrenCount = queryExecute("
|
||||
childrenCount = queryTimed("
|
||||
SELECT COUNT(DISTINCT c.ParentItemID) as cnt
|
||||
FROM Items c
|
||||
INNER JOIN Items p ON p.ItemID = c.ParentItemID
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
bizId = 27;
|
||||
|
||||
// Get all template links for Big Dean's
|
||||
qLinks = queryExecute("
|
||||
qLinks = queryTimed("
|
||||
SELECT
|
||||
tl.ItemID as MenuItemID,
|
||||
mi.Name as MenuName,
|
||||
|
|
@ -36,7 +36,7 @@ for (row in qLinks) {
|
|||
}
|
||||
|
||||
// Get all templates that exist for this business
|
||||
qTemplates = queryExecute("
|
||||
qTemplates = queryTimed("
|
||||
SELECT ID, Name, IsActive, ParentItemID
|
||||
FROM Items
|
||||
WHERE BusinessID = :bizId
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ bizId = 27;
|
|||
// Check the template items themselves (IDs from lt_ItemID_TemplateItemID)
|
||||
templateIds = "11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227";
|
||||
|
||||
qTemplates = queryExecute("
|
||||
qTemplates = queryTimed("
|
||||
SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID
|
||||
FROM Items
|
||||
WHERE ID IN (#templateIds#)
|
||||
|
|
@ -29,7 +29,7 @@ for (row in qTemplates) {
|
|||
|
||||
// Also check what other templates might exist for burgers
|
||||
// Look for items that are in lt_ItemID_TemplateItemID but NOT linked to burgers
|
||||
qMissingTemplates = queryExecute("
|
||||
qMissingTemplates = queryTimed("
|
||||
SELECT DISTINCT t.ItemID, t.Name, t.IsCollapsible, t.IsActive
|
||||
FROM Items t
|
||||
WHERE t.BusinessID = :bizId
|
||||
|
|
@ -52,7 +52,7 @@ for (row in qMissingTemplates) {
|
|||
}
|
||||
|
||||
// What templates SHOULD burgers have? Let's see all templates used by ANY item
|
||||
qAllTemplateUsage = queryExecute("
|
||||
qAllTemplateUsage = queryTimed("
|
||||
SELECT t.ItemID, t.Name, COUNT(tl.ItemID) as UsageCount
|
||||
FROM lt_ItemID_TemplateItemID tl
|
||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
bizId = 27;
|
||||
|
||||
// Get the template items themselves
|
||||
qTemplates = queryExecute("
|
||||
qTemplates = queryTimed("
|
||||
SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID
|
||||
FROM Items
|
||||
WHERE ID IN (11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227)
|
||||
|
|
@ -26,7 +26,7 @@ for (row in qTemplates) {
|
|||
}
|
||||
|
||||
// What templates are used by burgers vs all items?
|
||||
qBurgerLinks = queryExecute("
|
||||
qBurgerLinks = queryTimed("
|
||||
SELECT mi.ID, mi.Name, GROUP_CONCAT(t.Name ORDER BY tl.SortOrder) as Templates
|
||||
FROM Items mi
|
||||
JOIN lt_ItemID_TemplateItemID tl ON tl.ItemID = mi.ID
|
||||
|
|
@ -48,7 +48,7 @@ for (row in qBurgerLinks) {
|
|||
|
||||
// Also check: are there templates that SHOULD be linked to burgers?
|
||||
// (e.g., Add Cheese, etc.)
|
||||
qCheeseTemplate = queryExecute("
|
||||
qCheeseTemplate = queryTimed("
|
||||
SELECT ID, Name, ParentItemID, IsActive
|
||||
FROM Items
|
||||
WHERE BusinessID = :bizId
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<cftry>
|
||||
<!--- Get raw employee records --- >
|
||||
<cfset qEmployees = queryExecute("
|
||||
<cfset qEmployees = queryTimed("
|
||||
SELECT e.*, b.Name
|
||||
FROM Employees e
|
||||
INNER JOIN Businesses b ON b.ID = e.BusinessID
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
</cfloop>
|
||||
|
||||
<!--- Check for duplicate businesses --- >
|
||||
<cfset qDuplicates = queryExecute("
|
||||
<cfset qDuplicates = queryTimed("
|
||||
SELECT Name, COUNT(*) AS cnt
|
||||
FROM Businesses
|
||||
GROUP BY Name
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<cfscript>
|
||||
// Debug: check ChatMessages table contents
|
||||
try {
|
||||
qAll = queryExecute("SELECT * FROM ChatMessages ORDER BY CreatedOn DESC LIMIT 50", [], { datasource: "payfrit" });
|
||||
qAll = queryTimed("SELECT * FROM ChatMessages ORDER BY CreatedOn DESC LIMIT 50", [], { datasource: "payfrit" });
|
||||
|
||||
messages = [];
|
||||
for (row in qAll) {
|
||||
|
|
@ -20,7 +20,7 @@ try {
|
|||
}
|
||||
|
||||
// Also check schema
|
||||
schema = queryExecute("DESCRIBE ChatMessages", [], { datasource: "payfrit" });
|
||||
schema = queryTimed("DESCRIBE ChatMessages", [], { datasource: "payfrit" });
|
||||
cols = [];
|
||||
for (col in schema) {
|
||||
arrayAppend(cols, { "Field": col.Field, "Type": col.Type });
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ response = { "OK": true };
|
|||
|
||||
try {
|
||||
// Get Fountain Drinks item
|
||||
qFountain = queryExecute("
|
||||
qFountain = queryTimed("
|
||||
SELECT ID, Name, ParentItemID, Price, IsCollapsible, RequiresChildSelection
|
||||
FROM Items
|
||||
WHERE BusinessID = 17 AND Name LIKE '%Fountain%'
|
||||
|
|
@ -27,7 +27,7 @@ try {
|
|||
};
|
||||
|
||||
// Get children of this item
|
||||
qChildren = queryExecute("
|
||||
qChildren = queryTimed("
|
||||
SELECT ID, Name, ParentItemID, Price, IsCollapsible, RequiresChildSelection, IsCheckedByDefault
|
||||
FROM Items
|
||||
WHERE ParentItemID = :parentId
|
||||
|
|
@ -45,7 +45,7 @@ try {
|
|||
};
|
||||
|
||||
// Get grandchildren
|
||||
qGrandchildren = queryExecute("
|
||||
qGrandchildren = queryTimed("
|
||||
SELECT ID, Name, Price, IsCheckedByDefault
|
||||
FROM Items
|
||||
WHERE ParentItemID = :parentId
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ try {
|
|||
if (structKeyExists(data, "Phone") && len(data.Phone)) {
|
||||
phone = reReplace(data.Phone, "[^0-9]", "", "all");
|
||||
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
SELECT ID, FirstName, LastName, EmailAddress, ContactNumber
|
||||
FROM Users
|
||||
WHERE REPLACE(REPLACE(REPLACE(ContactNumber, '-', ''), '(', ''), ')', '') LIKE ?
|
||||
|
|
@ -30,7 +30,7 @@ if (structKeyExists(data, "Phone") && len(data.Phone)) {
|
|||
|
||||
userId = qUser.ID;
|
||||
|
||||
qEmployees = queryExecute("
|
||||
qEmployees = queryTimed("
|
||||
SELECT e.ID, e.BusinessID, e.StatusID,
|
||||
CAST(e.IsActive AS UNSIGNED) AS IsActive,
|
||||
b.Name
|
||||
|
|
@ -66,7 +66,7 @@ if (structKeyExists(data, "Phone") && len(data.Phone)) {
|
|||
// Original behavior - list employees by BusinessID
|
||||
businessId = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 17;
|
||||
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT ID, UserID, StatusID, IsActive,
|
||||
CAST(IsActive AS UNSIGNED) AS IsActiveInt
|
||||
FROM Employees
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ try {
|
|||
|
||||
// Close all open chats action
|
||||
if (structKeyExists(data, "action") && data.action == "closeAllChats") {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Tasks SET CompletedOn = NOW()
|
||||
WHERE TaskTypeID = 2 AND CompletedOn IS NULL
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
|
@ -22,7 +22,7 @@ if (structKeyExists(data, "action") && data.action == "closeAllChats") {
|
|||
</cfscript>
|
||||
|
||||
<cftry>
|
||||
<cfset qTasks = queryExecute("
|
||||
<cfset qTasks = queryTimed("
|
||||
SELECT
|
||||
t.ID,
|
||||
t.BusinessID,
|
||||
|
|
@ -50,7 +50,7 @@ if (structKeyExists(data, "action") && data.action == "closeAllChats") {
|
|||
})>
|
||||
</cfloop>
|
||||
|
||||
<cfset qStats = queryExecute("
|
||||
<cfset qStats = queryTimed("
|
||||
SELECT
|
||||
COUNT(*) as Total,
|
||||
SUM(CASE WHEN ClaimedByUserID > 0 AND CompletedOn IS NULL THEN 1 ELSE 0 END) as ClaimedNotCompleted,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<cfcontent type="application/json; charset=utf-8">
|
||||
|
||||
<cftry>
|
||||
<cfset qAll = queryExecute("
|
||||
<cfset qAll = queryTimed("
|
||||
SELECT ID, ClaimedByUserID, CompletedOn, OrderID,
|
||||
CASE WHEN CompletedOn IS NULL THEN 'YES_NULL' ELSE 'NOT_NULL' END AS IsNull
|
||||
FROM Tasks
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
bizId = 27;
|
||||
|
||||
// Count total links
|
||||
qCount = queryExecute("SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" });
|
||||
qCount = queryTimed("SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" });
|
||||
|
||||
// Get template item IDs for this business
|
||||
qTemplates = queryExecute("
|
||||
qTemplates = queryTimed("
|
||||
SELECT DISTINCT tl.TemplateItemID, i.Name
|
||||
FROM lt_ItemID_TemplateItemID tl
|
||||
JOIN Items i ON i.ID = tl.TemplateItemID
|
||||
|
|
@ -23,7 +23,7 @@ for (row in qTemplates) {
|
|||
}
|
||||
|
||||
// Get items that should be categories (ParentItemID=0, not templates)
|
||||
qCategories = queryExecute("
|
||||
qCategories = queryTimed("
|
||||
SELECT i.ID, i.Name, i.ParentItemID, i.IsCollapsible
|
||||
FROM Items i
|
||||
WHERE i.BusinessID = :bizId
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ if (len(phone) == 0) {
|
|||
}
|
||||
|
||||
// Find user by phone
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
SELECT ID, FirstName, LastName, EmailAddress, ContactNumber
|
||||
FROM Users
|
||||
WHERE REPLACE(REPLACE(REPLACE(ContactNumber, '-', ''), '(', ''), ')', '') LIKE ?
|
||||
|
|
@ -37,7 +37,7 @@ if (qUser.recordCount == 0) {
|
|||
userId = qUser.ID;
|
||||
|
||||
// Get all employee records for this user
|
||||
qEmployees = queryExecute("
|
||||
qEmployees = queryTimed("
|
||||
SELECT e.ID, e.BusinessID, e.StatusID,
|
||||
CAST(e.IsActive AS UNSIGNED) AS IsActive,
|
||||
b.Name
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ try {
|
|||
response["ERROR"] = "BusinessID required";
|
||||
} else {
|
||||
// Get address ID first
|
||||
qBiz = queryExecute("SELECT AddressID FROM Businesses WHERE ID = :id", { id: bizID }, { datasource = "payfrit" });
|
||||
qBiz = queryTimed("SELECT AddressID FROM Businesses WHERE ID = :id", { id: bizID }, { datasource = "payfrit" });
|
||||
|
||||
if (qBiz.recordCount == 0) {
|
||||
response["ERROR"] = "Business not found";
|
||||
|
|
@ -36,11 +36,11 @@ try {
|
|||
addrID = qBiz.AddressID;
|
||||
|
||||
// Delete business
|
||||
queryExecute("DELETE FROM Businesses WHERE ID = :id", { id: bizID }, { datasource = "payfrit" });
|
||||
queryTimed("DELETE FROM Businesses WHERE ID = :id", { id: bizID }, { datasource = "payfrit" });
|
||||
|
||||
// Delete address if exists
|
||||
if (val(addrID) > 0) {
|
||||
queryExecute("DELETE FROM Addresses WHERE ID = :id", { id: addrID }, { datasource = "payfrit" });
|
||||
queryTimed("DELETE FROM Addresses WHERE ID = :id", { id: addrID }, { datasource = "payfrit" });
|
||||
}
|
||||
|
||||
response["OK"] = true;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ try {
|
|||
|
||||
// Get all level-1 modifiers that are NOT templates
|
||||
// These are the duplicates we want to delete
|
||||
qOrphans = queryExecute("
|
||||
qOrphans = queryTimed("
|
||||
SELECT
|
||||
m.ItemID,
|
||||
m.Name,
|
||||
|
|
@ -49,12 +49,12 @@ try {
|
|||
for (orphan in qOrphans) {
|
||||
try {
|
||||
// Delete children of this orphan (options within the modifier group)
|
||||
qDeleteChildren = queryExecute("
|
||||
qDeleteChildren = queryTimed("
|
||||
DELETE FROM Items WHERE ParentItemID = :orphanID
|
||||
", { orphanID: orphan.ItemID }, { datasource: "payfrit" });
|
||||
|
||||
// Delete the orphan itself
|
||||
qDeleteOrphan = queryExecute("
|
||||
qDeleteOrphan = queryTimed("
|
||||
DELETE FROM Items WHERE ID = :orphanID
|
||||
", { orphanID: orphan.ItemID }, { datasource: "payfrit" });
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ response = { "OK": false, "deleted": 0, "orphans": [] };
|
|||
|
||||
try {
|
||||
// Find orphans
|
||||
qOrphans = queryExecute("
|
||||
qOrphans = queryTimed("
|
||||
SELECT i.ID, i.Name, i.BusinessID
|
||||
FROM Items i
|
||||
WHERE i.ParentItemID = 0
|
||||
|
|
@ -43,7 +43,7 @@ try {
|
|||
|
||||
// Delete them by ID list
|
||||
if (arrayLen(orphanIDs) > 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM Items WHERE ID IN (#arrayToList(orphanIDs)#)
|
||||
", {}, { datasource: "payfrit" });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||
|
||||
<cfscript>
|
||||
qDesc = queryExecute("SHOW COLUMNS FROM Items", {}, { datasource: "payfrit" });
|
||||
qDesc = queryTimed("SHOW COLUMNS FROM Items", {}, { datasource: "payfrit" });
|
||||
|
||||
cols = [];
|
||||
for (row in qDesc) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ try {
|
|||
}
|
||||
|
||||
// Get table structure
|
||||
cols = queryExecute("DESCRIBE #tableName#", {}, { datasource: "payfrit" });
|
||||
cols = queryTimed("DESCRIBE #tableName#", {}, { datasource: "payfrit" });
|
||||
|
||||
columns = [];
|
||||
for (c in cols) {
|
||||
|
|
@ -31,7 +31,7 @@ try {
|
|||
}
|
||||
|
||||
// Get sample data
|
||||
sampleData = queryExecute("SELECT * FROM #tableName# LIMIT 5", {}, { datasource: "payfrit" });
|
||||
sampleData = queryTimed("SELECT * FROM #tableName# LIMIT 5", {}, { datasource: "payfrit" });
|
||||
|
||||
samples = [];
|
||||
for (row in sampleData) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ try {
|
|||
// Step 1: Add BusinessID column if it doesn't exist
|
||||
try {
|
||||
if (!dryRun) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Items ADD COLUMN BusinessID INT DEFAULT 0 AFTER ItemID
|
||||
", {}, { datasource: "payfrit" });
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ try {
|
|||
// Step 2: Add index on BusinessID
|
||||
try {
|
||||
if (!dryRun) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE INDEX idx_item_business ON Items (BusinessID)
|
||||
", {}, { datasource: "payfrit" });
|
||||
}
|
||||
|
|
@ -69,7 +69,7 @@ try {
|
|||
// Step 3: Drop foreign key constraint on CategoryID if it exists
|
||||
try {
|
||||
if (!dryRun) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Items DROP FOREIGN KEY Items_ibfk_1
|
||||
", {}, { datasource: "payfrit" });
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ try {
|
|||
}
|
||||
|
||||
// Step 4: Get all Categories
|
||||
qCategories = queryExecute("
|
||||
qCategories = queryTimed("
|
||||
SELECT ID, BusinessID, Name
|
||||
FROM Categories
|
||||
ORDER BY BusinessID, Name
|
||||
|
|
@ -104,7 +104,7 @@ try {
|
|||
if (!dryRun) {
|
||||
// Create new Item for this category (ParentID=0, no template flag needed)
|
||||
// Note: CategoryID set to 0 temporarily until we drop that column
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
BusinessID,
|
||||
CategoryID,
|
||||
|
|
@ -136,7 +136,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Get the new Item ID
|
||||
qNewItem = queryExecute("
|
||||
qNewItem = queryTimed("
|
||||
SELECT ID FROM Items
|
||||
WHERE BusinessID = :businessID
|
||||
AND Name = :categoryName
|
||||
|
|
@ -154,7 +154,7 @@ try {
|
|||
// Update menu items in this category:
|
||||
// - Set ParentItemID = newItemID (for top-level items only)
|
||||
// - Set BusinessID = businessID (for all items)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET BusinessID = :businessID,
|
||||
ParentItemID = :newItemID
|
||||
|
|
@ -167,7 +167,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Set BusinessID on ALL items in this category (including nested)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET BusinessID = :businessID
|
||||
WHERE CategoryID = :categoryID
|
||||
|
|
@ -178,7 +178,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Count how many were updated
|
||||
qCount = queryExecute("
|
||||
qCount = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Items
|
||||
WHERE ParentItemID = :newItemID
|
||||
", { newItemID: newItemID }, { datasource: "payfrit" });
|
||||
|
|
@ -186,7 +186,7 @@ try {
|
|||
migration["itemsUpdated"] = qCount.cnt;
|
||||
} else {
|
||||
// Dry run - count what would be updated
|
||||
qCount = queryExecute("
|
||||
qCount = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Items
|
||||
WHERE CategoryID = :categoryID
|
||||
AND ParentItemID = 0
|
||||
|
|
@ -201,7 +201,7 @@ try {
|
|||
// Step 5: Set BusinessID for templates (items in lt_ItemID_TemplateItemID)
|
||||
// Templates get their BusinessID from the items they're linked to
|
||||
if (!dryRun) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items t
|
||||
INNER JOIN lt_ItemID_TemplateItemID tl ON tl.TemplateItemID = t.ItemID
|
||||
INNER JOIN Items i ON i.ID = tl.ItemID
|
||||
|
|
@ -213,7 +213,7 @@ try {
|
|||
arrayAppend(response.steps, "Set BusinessID on templates from linked items");
|
||||
|
||||
// Set BusinessID on template children (options)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items c
|
||||
INNER JOIN Items t ON t.ItemID = c.ParentItemID
|
||||
SET c.BusinessID = t.BusinessID
|
||||
|
|
@ -224,7 +224,7 @@ try {
|
|||
arrayAppend(response.steps, "Set BusinessID on template children");
|
||||
|
||||
// Make sure templates have ParentID=0 (they live at top level)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items t
|
||||
INNER JOIN lt_ItemID_TemplateItemID tl ON tl.TemplateItemID = t.ItemID
|
||||
SET t.ParentItemID = 0
|
||||
|
|
|
|||
|
|
@ -13,20 +13,20 @@ fakeCategories = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204,
|
|||
|
||||
// Deactivate these items (or we could delete them, but deactivate is safer)
|
||||
for (itemId in fakeCategories) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items SET IsActive = 0 WHERE ItemID = :itemId AND BusinessID = :bizId
|
||||
", { itemId: itemId, bizId: bizId }, { datasource: "payfrit" });
|
||||
}
|
||||
|
||||
// Also deactivate their children (modifier options that belong to these fake parents)
|
||||
for (itemId in fakeCategories) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items SET IsActive = 0 WHERE ParentItemID = :itemId AND BusinessID = :bizId
|
||||
", { itemId: itemId, bizId: bizId }, { datasource: "payfrit" });
|
||||
}
|
||||
|
||||
// Now verify what categories remain
|
||||
qCategories = queryExecute("
|
||||
qCategories = queryTimed("
|
||||
SELECT i.ID, i.Name
|
||||
FROM Items i
|
||||
WHERE i.BusinessID = :bizId
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ burgerIds = [11286, 11287, 11288, 11289, 11290]; // Big Dean's, Single w/Cheese,
|
|||
actions = [];
|
||||
|
||||
// First, let's see what templates already exist and are active for burgers
|
||||
qExistingLinks = queryExecute("
|
||||
qExistingLinks = queryTimed("
|
||||
SELECT tl.ItemID as MenuItemID, tl.TemplateItemID, t.Name as TemplateName
|
||||
FROM lt_ItemID_TemplateItemID tl
|
||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||
|
|
@ -33,21 +33,21 @@ for (row in qExistingLinks) {
|
|||
|
||||
// Reactivate template 11196 (Extras with Add Cheese)
|
||||
if (!dryRun) {
|
||||
queryExecute("UPDATE Items SET IsActive = 1 WHERE ItemID = 11196", {}, { datasource: "payfrit" });
|
||||
queryExecute("UPDATE Items SET IsActive = 1 WHERE ParentItemID = 11196", {}, { datasource: "payfrit" });
|
||||
queryTimed("UPDATE Items SET IsActive = 1 WHERE ItemID = 11196", {}, { datasource: "payfrit" });
|
||||
queryTimed("UPDATE Items SET IsActive = 1 WHERE ParentItemID = 11196", {}, { datasource: "payfrit" });
|
||||
}
|
||||
arrayAppend(actions, { action: dryRun ? "WOULD_REACTIVATE" : "REACTIVATED", itemID: 11196, name: "Extras (Add Cheese, Add Onions)" });
|
||||
|
||||
// Link template 11196 to all burgers
|
||||
for (burgerId in burgerIds) {
|
||||
// Check if link already exists
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID WHERE ItemID = :burgerId AND TemplateItemID = 11196
|
||||
", { burgerId: burgerId }, { datasource: "payfrit" });
|
||||
|
||||
if (qCheck.cnt EQ 0) {
|
||||
if (!dryRun) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||
VALUES (:burgerId, 11196, 2)
|
||||
", { burgerId: burgerId }, { datasource: "payfrit" });
|
||||
|
|
@ -58,7 +58,7 @@ for (burgerId in burgerIds) {
|
|||
|
||||
// Verify the result
|
||||
if (!dryRun) {
|
||||
qVerify = queryExecute("
|
||||
qVerify = queryTimed("
|
||||
SELECT mi.ID, mi.Name, GROUP_CONCAT(t.Name ORDER BY tl.SortOrder) as Templates
|
||||
FROM Items mi
|
||||
LEFT JOIN lt_ItemID_TemplateItemID tl ON tl.ItemID = mi.ID
|
||||
|
|
|
|||
|
|
@ -2,21 +2,21 @@
|
|||
<cfcontent type="application/json" reset="true">
|
||||
<cfscript>
|
||||
// One-time fix: remove # prefix from BrandColor
|
||||
qBefore = queryExecute("
|
||||
qBefore = queryTimed("
|
||||
SELECT ID, BrandColor
|
||||
FROM Businesses
|
||||
WHERE BrandColor LIKE :pattern
|
||||
", { pattern: { value: "##%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
||||
|
||||
if (qBefore.recordCount > 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Businesses
|
||||
SET BrandColor = SUBSTRING(BrandColor, 2)
|
||||
WHERE BrandColor LIKE :pattern
|
||||
", { pattern: { value: "##%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
||||
}
|
||||
|
||||
qAfter = queryExecute("
|
||||
qAfter = queryTimed("
|
||||
SELECT ID, BrandColor
|
||||
FROM Businesses
|
||||
WHERE BrandColor IS NOT NULL AND LENGTH(BrandColor) > 0
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// Update them to use new category ID 25 (new Service Point)
|
||||
try {
|
||||
// First check how many tasks are affected
|
||||
qCount = queryExecute("
|
||||
qCount = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Tasks WHERE TaskCategoryID = 4
|
||||
", [], { datasource: "payfrit" });
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ try {
|
|||
|
||||
if (affectedCount > 0) {
|
||||
// Update them to the new category
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Tasks SET TaskCategoryID = 25 WHERE TaskCategoryID = 4
|
||||
", [], { datasource: "payfrit" });
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ try {
|
|||
categoryID = 46; // Fries and Shakes
|
||||
|
||||
// Step 1: Create "Choose Flavor" modifier group under Shake
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Items (
|
||||
CategoryID,
|
||||
Name,
|
||||
|
|
@ -80,7 +80,7 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Get the new Choose Flavor ID
|
||||
qNewGroup = queryExecute("
|
||||
qNewGroup = queryTimed("
|
||||
SELECT ID FROM Items
|
||||
WHERE Name = 'Choose Flavor'
|
||||
AND ParentItemID = :shakeItemID
|
||||
|
|
@ -92,7 +92,7 @@ try {
|
|||
arrayAppend(response.steps, "Created 'Choose Flavor' group with ID: " & chooseFlavorID);
|
||||
|
||||
// Step 2: Re-parent the three flavors under Choose Flavor
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET ParentItemID = :chooseFlavorID,
|
||||
IsModifierTemplate = 0,
|
||||
|
|
@ -108,14 +108,14 @@ try {
|
|||
arrayAppend(response.steps, "Re-parented Chocolate, Strawberry, Vanilla under Choose Flavor");
|
||||
|
||||
// Step 3: Set Vanilla as default (common choice)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items SET IsCheckedByDefault = 1 WHERE ItemID = :vanillaID
|
||||
", { vanillaID: vanillaID }, { datasource: "payfrit" });
|
||||
|
||||
arrayAppend(response.steps, "Set Vanilla as default flavor");
|
||||
|
||||
// Step 4: Remove old template links for the flavors
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM lt_ItemID_TemplateItemID
|
||||
WHERE TemplateItemID IN (:chocolateID, :strawberryID, :vanillaID)
|
||||
", {
|
||||
|
|
@ -127,7 +127,7 @@ try {
|
|||
arrayAppend(response.steps, "Removed old template links for flavor items");
|
||||
|
||||
// Step 5: Create lt_ItemID_TemplateItemID for Shake -> Choose Flavor
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||
VALUES (:shakeItemID, :chooseFlavorID, 0)
|
||||
ON DUPLICATE KEY UPDATE SortOrder = 0
|
||||
|
|
@ -139,7 +139,7 @@ try {
|
|||
arrayAppend(response.steps, "Created template link: Shake -> Choose Flavor");
|
||||
|
||||
// Step 6: Set RequiresChildSelection on shake
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET RequiresChildSelection = 1
|
||||
WHERE ItemID = :shakeItemID
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ try {
|
|||
if (childID <= 0) {
|
||||
response["ERROR"] = "ChildBusinessID required";
|
||||
} else {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Businesses SET ParentBusinessID = :parentId WHERE ID = :childId
|
||||
", {
|
||||
parentId: { value = parentID > 0 ? parentID : javaCast("null", ""), cfsqltype = "cf_sql_integer", null = parentID == 0 },
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<cfscript>
|
||||
try {
|
||||
// List all tables
|
||||
tables = queryExecute("SHOW TABLES", {}, { datasource: "payfrit" });
|
||||
tables = queryTimed("SHOW TABLES", {}, { datasource: "payfrit" });
|
||||
|
||||
tableList = [];
|
||||
for (t in tables) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ try {
|
|||
businessID = 17; // In and Out Burger
|
||||
|
||||
// Step 1: Get all parent items (burgers, combos, etc.)
|
||||
qParentItems = queryExecute("
|
||||
qParentItems = queryTimed("
|
||||
SELECT i.ID, i.Name
|
||||
FROM Items i
|
||||
INNER JOIN Categories c ON c.ID = i.CategoryID
|
||||
|
|
@ -38,7 +38,7 @@ try {
|
|||
arrayAppend(response.steps, "Found " & qParentItems.recordCount & " parent items");
|
||||
|
||||
// Step 2: Get all direct children (level 1 modifiers) of parent items
|
||||
qModifiers = queryExecute("
|
||||
qModifiers = queryTimed("
|
||||
SELECT
|
||||
m.ItemID,
|
||||
m.Name,
|
||||
|
|
@ -90,7 +90,7 @@ try {
|
|||
templateItemID = templateItem.ItemID;
|
||||
|
||||
// Mark as template
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items SET IsModifierTemplate = 1 WHERE ItemID = :itemID
|
||||
", { itemID: templateItemID }, { datasource: "payfrit" });
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ try {
|
|||
|
||||
// Insert link (ignore duplicates)
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||
VALUES (:itemID, :templateID, :sortOrder)
|
||||
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
|
||||
|
|
@ -142,12 +142,12 @@ try {
|
|||
} else {
|
||||
// Single instance - still mark as template for consistency
|
||||
singleItem = instances[1];
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items SET IsModifierTemplate = 1 WHERE ItemID = :itemID
|
||||
", { itemID: singleItem.ItemID }, { datasource: "payfrit" });
|
||||
|
||||
// Create link
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||
VALUES (:itemID, :templateID, :sortOrder)
|
||||
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ try {
|
|||
|
||||
// Find all businesses with items in unified schema
|
||||
if (len(businessFilter)) {
|
||||
qBusinesses = queryExecute("
|
||||
qBusinesses = queryTimed("
|
||||
SELECT DISTINCT BusinessID as BusinessID
|
||||
FROM Items
|
||||
WHERE BusinessID = :bid AND BusinessID > 0
|
||||
", { bid: businessFilter }, { datasource: "payfrit" });
|
||||
} else {
|
||||
qBusinesses = queryExecute("
|
||||
qBusinesses = queryTimed("
|
||||
SELECT DISTINCT BusinessID as BusinessID
|
||||
FROM Items
|
||||
WHERE BusinessID > 0
|
||||
|
|
@ -45,7 +45,7 @@ try {
|
|||
|
||||
try {
|
||||
// Find category-like Items (parent=0, not collapsible, has children, not in template links)
|
||||
qCategoryItems = queryExecute("
|
||||
qCategoryItems = queryTimed("
|
||||
SELECT DISTINCT
|
||||
p.ID,
|
||||
p.Name,
|
||||
|
|
@ -64,20 +64,20 @@ try {
|
|||
sortOrder = 0;
|
||||
for (catItem in qCategoryItems) {
|
||||
// Check if category already exists for this business with same name
|
||||
qExisting = queryExecute("
|
||||
qExisting = queryTimed("
|
||||
SELECT ID FROM Categories
|
||||
WHERE BusinessID = :bizId AND Name = :name
|
||||
", { bizId: bizId, name: left(catItem.Name, 30) }, { datasource: "payfrit" });
|
||||
|
||||
if (qExisting.recordCount == 0) {
|
||||
// Get next CategoryID
|
||||
qMaxId = queryExecute("
|
||||
qMaxId = queryTimed("
|
||||
SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Categories
|
||||
", {}, { datasource: "payfrit" });
|
||||
newCatId = qMaxId.nextId;
|
||||
|
||||
// Create new category with explicit ID
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Categories
|
||||
(ID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn)
|
||||
VALUES (:catId, :bizId, 0, :name, :sortOrder, NOW())
|
||||
|
|
@ -94,7 +94,7 @@ try {
|
|||
}
|
||||
|
||||
// Update all children of this category Item to have the new CategoryID
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET CategoryID = :catId
|
||||
WHERE ParentItemID = :parentId
|
||||
|
|
@ -105,7 +105,7 @@ try {
|
|||
bizId: bizId
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qUpdated = queryExecute("SELECT ROW_COUNT() as cnt", {}, { datasource: "payfrit" });
|
||||
qUpdated = queryTimed("SELECT ROW_COUNT() as cnt", {}, { datasource: "payfrit" });
|
||||
bizResult.ItemsUpdated += qUpdated.cnt;
|
||||
|
||||
sortOrder++;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ businessId = 27; // Big Dean's
|
|||
// Modifiers are children of menu items or modifier templates
|
||||
|
||||
// Get category IDs (NOT modifier templates)
|
||||
categoryIds = queryExecute("
|
||||
categoryIds = queryTimed("
|
||||
SELECT ID
|
||||
FROM Items
|
||||
WHERE BusinessID = :bizId
|
||||
|
|
@ -26,7 +26,7 @@ for (cat in categoryIds) {
|
|||
|
||||
// Now get actual menu items (direct children of categories)
|
||||
// Exclude items that are template options (their parent is a collapsible modifier group)
|
||||
items = queryExecute("
|
||||
items = queryTimed("
|
||||
SELECT i.ID, i.Name
|
||||
FROM Items i
|
||||
WHERE i.BusinessID = :bizId
|
||||
|
|
@ -97,7 +97,7 @@ for (item in items) {
|
|||
newPrice = randRange(15, 23) - 0.01; // $14.99 - $22.99
|
||||
}
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET Price = :price
|
||||
WHERE ItemID = :itemId
|
||||
|
|
@ -112,7 +112,7 @@ for (item in items) {
|
|||
|
||||
// Update modifier prices (children of menu items, NOT direct children of categories)
|
||||
// Modifiers are items whose parent is NOT a category (i.e., parent is a menu item or modifier group)
|
||||
modifiers = queryExecute("
|
||||
modifiers = queryTimed("
|
||||
SELECT ID, Name
|
||||
FROM Items
|
||||
WHERE BusinessID = :bizId
|
||||
|
|
@ -148,7 +148,7 @@ for (mod in modifiers) {
|
|||
}
|
||||
}
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET Price = :price
|
||||
WHERE ItemID = :itemId
|
||||
|
|
@ -156,7 +156,7 @@ for (mod in modifiers) {
|
|||
}
|
||||
|
||||
// Reset category prices to $0 (shouldn't have prices for reporting)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET Price = 0
|
||||
WHERE BusinessID = :bizId
|
||||
|
|
@ -164,7 +164,7 @@ queryExecute("
|
|||
", { bizId: businessId }, { datasource: "payfrit" });
|
||||
|
||||
// Reset modifier group prices to $0 (only options have prices)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Items
|
||||
SET Price = 0
|
||||
WHERE BusinessID = :bizId
|
||||
|
|
|
|||
|
|
@ -10,36 +10,36 @@
|
|||
|
||||
<cftry>
|
||||
<!--- Disable foreign key checks temporarily --->
|
||||
<cfset queryExecute("SET FOREIGN_KEY_CHECKS = 0", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("SET FOREIGN_KEY_CHECKS = 0", [], { datasource = "payfrit" })>
|
||||
|
||||
<!--- Clear Tasks --->
|
||||
<cfset queryExecute("DELETE FROM Tasks", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("DELETE FROM Tasks", [], { datasource = "payfrit" })>
|
||||
|
||||
<!--- Clear Payments --->
|
||||
<cftry>
|
||||
<cfset queryExecute("DELETE FROM Payments", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("DELETE FROM Payments", [], { datasource = "payfrit" })>
|
||||
<cfcatch></cfcatch>
|
||||
</cftry>
|
||||
|
||||
<!--- Clear OrderLineItemModifiers if exists --->
|
||||
<cftry>
|
||||
<cfset queryExecute("DELETE FROM OrderLineItemModifiers", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("DELETE FROM OrderLineItemModifiers", [], { datasource = "payfrit" })>
|
||||
<cfcatch></cfcatch>
|
||||
</cftry>
|
||||
|
||||
<!--- Clear OrderLineItems --->
|
||||
<cfset queryExecute("DELETE FROM OrderLineItems", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("DELETE FROM OrderLineItems", [], { datasource = "payfrit" })>
|
||||
|
||||
<!--- Clear Orders --->
|
||||
<cfset queryExecute("DELETE FROM Orders", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("DELETE FROM Orders", [], { datasource = "payfrit" })>
|
||||
|
||||
<!--- Re-enable foreign key checks --->
|
||||
<cfset queryExecute("SET FOREIGN_KEY_CHECKS = 1", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("SET FOREIGN_KEY_CHECKS = 1", [], { datasource = "payfrit" })>
|
||||
|
||||
<!--- Reset auto-increment counters --->
|
||||
<cfset queryExecute("ALTER TABLE Tasks AUTO_INCREMENT = 1", [], { datasource = "payfrit" })>
|
||||
<cfset queryExecute("ALTER TABLE Orders AUTO_INCREMENT = 1", [], { datasource = "payfrit" })>
|
||||
<cfset queryExecute("ALTER TABLE OrderLineItems AUTO_INCREMENT = 1", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("ALTER TABLE Tasks AUTO_INCREMENT = 1", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("ALTER TABLE Orders AUTO_INCREMENT = 1", [], { datasource = "payfrit" })>
|
||||
<cfset queryTimed("ALTER TABLE OrderLineItems AUTO_INCREMENT = 1", [], { datasource = "payfrit" })>
|
||||
|
||||
<cfset apiAbort({
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ if (businessId <= 0 || userId <= 0) {
|
|||
|
||||
try {
|
||||
// Update employee record
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Employees
|
||||
SET IsActive = ?
|
||||
WHERE BusinessID = ? AND UserID = ?
|
||||
|
|
@ -31,7 +31,7 @@ try {
|
|||
], { datasource: "payfrit" });
|
||||
|
||||
// Get updated record
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT e.ID, e.BusinessID, e.UserID, e.StatusID,
|
||||
CAST(e.IsActive AS UNSIGNED) AS IsActive,
|
||||
b.Name, u.FirstName, u.LastName
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
response = { "OK": false };
|
||||
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Businesses SET HeaderImageExtension = 'jpg' WHERE ID = 37
|
||||
", {}, { datasource: "payfrit" });
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ try {
|
|||
lazyDaisyID = 37;
|
||||
|
||||
// Get all service points for Lazy Daisy
|
||||
qServicePoints = queryExecute("
|
||||
qServicePoints = queryTimed("
|
||||
SELECT ID, Name AS Name
|
||||
FROM ServicePoints
|
||||
WHERE BusinessID = :bizID AND IsActive = 1
|
||||
|
|
@ -28,7 +28,7 @@ try {
|
|||
beaconName = "Beacon - " & sp.Name;
|
||||
|
||||
// Check if beacon already exists for this business with this name
|
||||
qExisting = queryExecute("
|
||||
qExisting = queryTimed("
|
||||
SELECT ID FROM Beacons
|
||||
WHERE BusinessID = :bizId AND Name = :name
|
||||
", { bizId: lazyDaisyID, name: beaconName }, { datasource: "payfrit" });
|
||||
|
|
@ -37,7 +37,7 @@ try {
|
|||
// Generate a unique UUID for this beacon (32 hex chars, no dashes)
|
||||
beaconUUID = "PAYFRIT00037" & numberFormat(sp.ID, "0000000000000000000");
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Beacons (BusinessID, Name, UUID, IsActive)
|
||||
VALUES (:bizId, :name, :uuid, 1)
|
||||
", {
|
||||
|
|
@ -46,11 +46,11 @@ try {
|
|||
uuid: beaconUUID
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qNewBeacon = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
qNewBeacon = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
newBeaconId = qNewBeacon.id;
|
||||
|
||||
// Assign beacon directly to service point
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints
|
||||
SET BeaconID = :beaconId, AssignedByUserID = 1
|
||||
WHERE ID = :spId AND BusinessID = :bizId
|
||||
|
|
@ -68,7 +68,7 @@ try {
|
|||
}
|
||||
|
||||
// Get final status
|
||||
qFinal = queryExecute("
|
||||
qFinal = queryTimed("
|
||||
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID,
|
||||
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||
biz.Name AS BusinessName
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ try {
|
|||
// Hours: Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm
|
||||
|
||||
// Get California StateID
|
||||
qState = queryExecute("SELECT ID FROM tt_States WHERE Abbreviation = 'CA' LIMIT 1");
|
||||
qState = queryTimed("SELECT ID FROM tt_States WHERE Abbreviation = 'CA' LIMIT 1");
|
||||
stateId = qState.recordCount > 0 ? qState.ID : 5; // Default to 5 if not found
|
||||
|
||||
// Check if Big Dean's already has an address
|
||||
existingAddr = queryExecute("
|
||||
existingAddr = queryTimed("
|
||||
SELECT ID FROM Addresses
|
||||
WHERE BusinessID = :bizId AND UserID = 0
|
||||
", { bizId: businessId });
|
||||
|
||||
if (existingAddr.recordCount == 0) {
|
||||
// Insert new address
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Addresses (UserID, BusinessID, AddressTypeID, Line1, City, StateID, ZIPCode, IsDeleted, AddedOn)
|
||||
VALUES (0, :bizId, '2', :line1, :city, :stateId, :zip, 0, NOW())
|
||||
", {
|
||||
|
|
@ -37,7 +37,7 @@ try {
|
|||
response["ADDRESS_ACTION"] = "inserted";
|
||||
} else {
|
||||
// Update existing address
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Addresses
|
||||
SET Line1 = :line1, City = :city, StateID = :stateId, ZIPCode = :zip
|
||||
WHERE BusinessID = :bizId AND UserID = 0
|
||||
|
|
@ -52,7 +52,7 @@ try {
|
|||
}
|
||||
|
||||
// Check existing hours for this business
|
||||
existingHours = queryExecute("
|
||||
existingHours = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Hours WHERE BusinessID = :bizId
|
||||
", { bizId: businessId });
|
||||
|
||||
|
|
@ -64,39 +64,39 @@ try {
|
|||
// Sun: 11am-10pm (day 1)
|
||||
|
||||
// Sunday (1): 11am-10pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 1, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 1, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
|
||||
// Monday (2): 11am-10pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 2, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 2, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
|
||||
// Tuesday (3): 11am-10pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 3, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 3, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
|
||||
// Wednesday (4): 11am-10pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 4, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 4, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
|
||||
// Thursday (5): 11am-10pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 5, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 5, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||
|
||||
// Friday (6): 11am-11pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 6, '11:00:00', '23:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 6, '11:00:00', '23:00:00')", { bizId: businessId });
|
||||
|
||||
// Saturday (7): 11am-11pm
|
||||
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 7, '11:00:00', '23:00:00')", { bizId: businessId });
|
||||
queryTimed("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 7, '11:00:00', '23:00:00')", { bizId: businessId });
|
||||
|
||||
response["HOURS_ACTION"] = "inserted 7 days";
|
||||
} else {
|
||||
// Update existing hours
|
||||
// Mon-Thu: 11am-10pm
|
||||
queryExecute("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '22:00:00' WHERE BusinessID = :bizId AND DayID IN (1, 2, 3, 4, 5)", { bizId: businessId });
|
||||
queryTimed("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '22:00:00' WHERE BusinessID = :bizId AND DayID IN (1, 2, 3, 4, 5)", { bizId: businessId });
|
||||
// Fri-Sat: 11am-11pm
|
||||
queryExecute("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '23:00:00' WHERE BusinessID = :bizId AND DayID IN (6, 7)", { bizId: businessId });
|
||||
queryTimed("UPDATE Hours SET OpenTime = '11:00:00', ClosingTime = '23:00:00' WHERE BusinessID = :bizId AND DayID IN (6, 7)", { bizId: businessId });
|
||||
response["HOURS_ACTION"] = "updated";
|
||||
}
|
||||
|
||||
// Update phone on Businesses table (if column exists)
|
||||
try {
|
||||
queryExecute("UPDATE Businesses SET Phone = :phone WHERE ID = :bizId", {
|
||||
queryTimed("UPDATE Businesses SET Phone = :phone WHERE ID = :bizId", {
|
||||
phone: "(310) 393-2666",
|
||||
bizId: businessId
|
||||
});
|
||||
|
|
@ -106,14 +106,14 @@ try {
|
|||
}
|
||||
|
||||
// Verify the data
|
||||
address = queryExecute("
|
||||
address = queryTimed("
|
||||
SELECT a.*, s.Abbreviation
|
||||
FROM Addresses a
|
||||
LEFT JOIN tt_States s ON s.ID = a.StateID
|
||||
WHERE a.BusinessID = :bizId AND a.UserID = 0
|
||||
", { bizId: businessId });
|
||||
|
||||
hours = queryExecute("
|
||||
hours = queryTimed("
|
||||
SELECT h.*, d.Name AS DayName
|
||||
FROM Hours h
|
||||
JOIN tt_Days d ON d.ID = h.DayID
|
||||
|
|
|
|||
|
|
@ -8,19 +8,19 @@ response = { "OK": false };
|
|||
|
||||
try {
|
||||
// Check if Big Dean's already has stations
|
||||
existing = queryExecute("
|
||||
existing = queryTimed("
|
||||
SELECT COUNT(*) as cnt FROM Stations WHERE BusinessID = :bizId
|
||||
", { bizId: businessId });
|
||||
|
||||
if (existing.cnt == 0) {
|
||||
// Insert Kitchen station
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Stations (BusinessID, Name, Color, SortOrder, IsActive)
|
||||
VALUES (:bizId, 'Kitchen', :color1, 1, 1)
|
||||
", { bizId: businessId, color1: "##FF5722" });
|
||||
|
||||
// Insert Bar station
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Stations (BusinessID, Name, Color, SortOrder, IsActive)
|
||||
VALUES (:bizId, 'Bar', :color2, 2, 1)
|
||||
", { bizId: businessId, color2: "##2196F3" });
|
||||
|
|
@ -31,7 +31,7 @@ try {
|
|||
}
|
||||
|
||||
// Get current stations
|
||||
stations = queryExecute("
|
||||
stations = queryTimed("
|
||||
SELECT ID, Name, Color, SortOrder
|
||||
FROM Stations
|
||||
WHERE BusinessID = :bizId AND IsActive = 1
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@ try {
|
|||
lazyDaisyID = 37;
|
||||
|
||||
// Get all beacons
|
||||
qBeacons = queryExecute("SELECT ID, UUID FROM Beacons", {}, { datasource: "payfrit" });
|
||||
qBeacons = queryTimed("SELECT ID, UUID FROM Beacons", {}, { datasource: "payfrit" });
|
||||
response.steps.append("Found " & qBeacons.recordCount & " beacons");
|
||||
|
||||
// Create service point for Table 1 if it doesn't exist
|
||||
qSP = queryExecute("
|
||||
qSP = queryTimed("
|
||||
SELECT ID FROM ServicePoints
|
||||
WHERE BusinessID = :bizID AND Name = 'Table 1'
|
||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
|
||||
if (qSP.recordCount == 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO ServicePoints (BusinessID, Name)
|
||||
VALUES (:bizID, 'Table 1')
|
||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
qSP = queryTimed("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||
servicePointID = qSP.id;
|
||||
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
|
||||
} else {
|
||||
|
|
@ -36,13 +36,13 @@ try {
|
|||
beaconID = qBeacons.ID[i];
|
||||
|
||||
// Unassign this beacon from any other service point first
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL
|
||||
WHERE BeaconID = :beaconID
|
||||
", { beaconID: beaconID }, { datasource: "payfrit" });
|
||||
|
||||
// Assign beacon to Table 1 service point
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1
|
||||
WHERE ID = :spID AND BusinessID = :bizID
|
||||
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
||||
|
|
@ -50,7 +50,7 @@ try {
|
|||
}
|
||||
|
||||
// Get final status
|
||||
qFinal = queryExecute("
|
||||
qFinal = queryTimed("
|
||||
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID,
|
||||
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||
biz.Name AS BusinessName
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ response = { "OK": false, "steps": [] };
|
|||
try {
|
||||
// Step 1: Add IsModifierTemplate column if it doesn't exist
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE Items ADD COLUMN IsModifierTemplate TINYINT(1) DEFAULT 0
|
||||
", {}, { datasource: "payfrit" });
|
||||
arrayAppend(response.steps, "Added IsModifierTemplate column");
|
||||
|
|
@ -34,7 +34,7 @@ try {
|
|||
|
||||
// Step 2: Create lt_ItemID_TemplateItemID table if it doesn't exist
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE TABLE IF NOT EXISTS lt_ItemID_TemplateItemID (
|
||||
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||
ItemID INT NOT NULL,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<cftry>
|
||||
<!--- Create Stations table if it doesn't exist --->
|
||||
<cfset queryExecute("
|
||||
<cfset queryTimed("
|
||||
CREATE TABLE IF NOT EXISTS Stations (
|
||||
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||
BusinessID INT NOT NULL,
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<!--- Add StationID column to Items table if it doesn't exist --->
|
||||
<cftry>
|
||||
<cfset queryExecute("
|
||||
<cfset queryTimed("
|
||||
ALTER TABLE Items ADD COLUMN StationID INT DEFAULT NULL
|
||||
", [], { datasource = "payfrit" })>
|
||||
<cfset stationColumnAdded = true>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
<!--- Add foreign key if column was just added --->
|
||||
<cfif stationColumnAdded>
|
||||
<cftry>
|
||||
<cfset queryExecute("
|
||||
<cfset queryTimed("
|
||||
ALTER TABLE Items ADD FOREIGN KEY (StationID) REFERENCES Stations(ID)
|
||||
", [], { datasource = "payfrit" })>
|
||||
<cfcatch></cfcatch>
|
||||
|
|
@ -46,12 +46,12 @@
|
|||
</cfif>
|
||||
|
||||
<!--- Create some default stations for business 1 (In and Out Burger) if none exist --->
|
||||
<cfset qCheck = queryExecute("
|
||||
<cfset qCheck = queryTimed("
|
||||
SELECT COUNT(*) AS cnt FROM Stations WHERE BusinessID = 1
|
||||
", [], { datasource = "payfrit" })>
|
||||
|
||||
<cfif qCheck.cnt EQ 0>
|
||||
<cfset queryExecute("
|
||||
<cfset queryTimed("
|
||||
INSERT INTO Stations (BusinessID, Name, Color, SortOrder) VALUES
|
||||
(1, 'Grill', '##FF5722', 1),
|
||||
(1, 'Fry', '##FFC107', 2),
|
||||
|
|
|
|||
|
|
@ -9,27 +9,27 @@ fromBiz = 17; // In-N-Out
|
|||
toBiz = 27; // Big Dean's
|
||||
|
||||
// Remove mapping for source business
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM lt_BeaconsID_BusinessesID
|
||||
WHERE BusinessID = :fromBiz
|
||||
", { fromBiz: fromBiz }, { datasource: "payfrit" });
|
||||
|
||||
// Add mapping for target business (for beacons owned by source)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
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("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints
|
||||
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||
WHERE BusinessID = :fromBiz AND BeaconID IS NOT NULL
|
||||
", { fromBiz: fromBiz }, { datasource: "payfrit" });
|
||||
|
||||
// Get current state
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID AS BusinessID,
|
||||
b.Name AS BeaconName, biz.Name AS BusinessName,
|
||||
sp.Name AS ServicePointName
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<cfset result = {}>
|
||||
<cftry>
|
||||
<cfset queryExecute(
|
||||
<cfset queryTimed(
|
||||
"
|
||||
INSERT INTO Tasks (
|
||||
BusinessID,
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
{ datasource = "payfrit" }
|
||||
)>
|
||||
|
||||
<cfset qCount = queryExecute("SELECT COUNT(*) AS cnt FROM Tasks", [], { datasource = "payfrit" })>
|
||||
<cfset qCount = queryTimed("SELECT COUNT(*) AS cnt FROM Tasks", [], { datasource = "payfrit" })>
|
||||
|
||||
<cfset result = {
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<cfsetting showdebugoutput="false">
|
||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||
<cfscript>
|
||||
qTask = queryExecute("
|
||||
qTask = queryTimed("
|
||||
SELECT ID, TaskTypeID, ClaimedByUserID, CompletedOn
|
||||
FROM Tasks
|
||||
WHERE ID = 57
|
||||
|
|
|
|||
|
|
@ -9,27 +9,27 @@ oldBusinessId = 37; // previous mapping
|
|||
newBusinessId = 17;
|
||||
|
||||
// Remove old mapping
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM lt_BeaconsID_BusinessesID
|
||||
WHERE BeaconID = :beaconId AND BusinessID = :oldBizId
|
||||
", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" });
|
||||
|
||||
// Add new mapping
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
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("
|
||||
queryTimed("
|
||||
UPDATE ServicePoints
|
||||
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||
WHERE BeaconID = :beaconId AND BusinessID = :oldBizId
|
||||
", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" });
|
||||
|
||||
// Get current state
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT
|
||||
b.ID AS BeaconID,
|
||||
b.UUID,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ hours = "Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm";
|
|||
|
||||
try {
|
||||
// Update phone and hours on Businesses table
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Businesses
|
||||
SET Phone = :phone,
|
||||
Hours = :hours
|
||||
|
|
@ -24,14 +24,14 @@ try {
|
|||
}, { datasource: "payfrit" });
|
||||
|
||||
// Update or insert address in Addresses table
|
||||
qAddr = queryExecute("
|
||||
qAddr = queryTimed("
|
||||
SELECT ID FROM Addresses
|
||||
WHERE BusinessID = :bizId AND IsDeleted = 0
|
||||
LIMIT 1
|
||||
", { bizId: businessId }, { datasource: "payfrit" });
|
||||
|
||||
if (qAddr.recordCount > 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Addresses
|
||||
SET Line1 = :line1, City = :city, ZIPCode = :zip
|
||||
WHERE ID = :addrId
|
||||
|
|
@ -42,7 +42,7 @@ try {
|
|||
addrId: qAddr.ID
|
||||
}, { datasource: "payfrit" });
|
||||
} else {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Addresses (BusinessID, UserID, AddressTypeID, Line1, City, ZIPCode, AddedOn)
|
||||
VALUES (:bizId, 0, 'business', :line1, :city, :zip, NOW())
|
||||
", {
|
||||
|
|
@ -54,7 +54,7 @@ try {
|
|||
}
|
||||
|
||||
// Get updated record
|
||||
updated = queryExecute("
|
||||
updated = queryTimed("
|
||||
SELECT ID, Name, Phone, Hours
|
||||
FROM Businesses
|
||||
WHERE ID = :bizId
|
||||
|
|
|
|||
313
api/admin/perf-dashboard.cfm
Normal file
313
api/admin/perf-dashboard.cfm
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
<cfsetting showdebugoutput="false">
|
||||
<cfsetting enablecfoutputonly="false">
|
||||
<cfscript>
|
||||
// Localhost-only protection
|
||||
remoteAddr = cgi.REMOTE_ADDR;
|
||||
if (remoteAddr != "127.0.0.1" && remoteAddr != "::1" && remoteAddr != "0:0:0:0:0:0:0:1" && remoteAddr != "10.10.0.2") {
|
||||
writeOutput("Forbidden"); abort;
|
||||
}
|
||||
</cfscript>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>API Performance Dashboard</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; background: #0f1117; color: #e1e4e8; padding: 20px; }
|
||||
h1 { font-size: 22px; font-weight: 600; margin-bottom: 16px; color: #fff; }
|
||||
.controls { display: flex; gap: 10px; margin-bottom: 20px; align-items: center; flex-wrap: wrap; }
|
||||
.controls label { font-size: 13px; color: #8b949e; }
|
||||
.controls select, .controls input { background: #1c1f26; border: 1px solid #30363d; color: #e1e4e8; padding: 6px 10px; border-radius: 6px; font-size: 13px; }
|
||||
.controls button { background: #238636; color: #fff; border: none; padding: 6px 16px; border-radius: 6px; font-size: 13px; cursor: pointer; font-weight: 500; }
|
||||
.controls button:hover { background: #2ea043; }
|
||||
.controls button.secondary { background: #30363d; }
|
||||
.controls button.secondary:hover { background: #3d444d; }
|
||||
|
||||
.summary-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 24px; }
|
||||
.card { background: #1c1f26; border: 1px solid #30363d; border-radius: 8px; padding: 16px; }
|
||||
.card .label { font-size: 11px; color: #8b949e; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
|
||||
.card .value { font-size: 28px; font-weight: 700; color: #fff; }
|
||||
.card .unit { font-size: 13px; color: #8b949e; font-weight: 400; }
|
||||
.card .sub { font-size: 13px; color: #8b949e; font-weight: 400; }
|
||||
|
||||
.section { margin-bottom: 28px; }
|
||||
.section h2 { font-size: 15px; font-weight: 600; margin-bottom: 10px; color: #c9d1d9; display: flex; align-items: center; gap: 8px; }
|
||||
.section h2 .badge { background: #30363d; padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 500; color: #8b949e; }
|
||||
|
||||
table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
thead th { text-align: left; padding: 8px 12px; border-bottom: 1px solid #30363d; color: #8b949e; font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; }
|
||||
thead th.num { text-align: right; }
|
||||
tbody td { padding: 8px 12px; border-bottom: 1px solid #1c1f26; }
|
||||
tbody td.num { text-align: right; font-variant-numeric: tabular-nums; }
|
||||
tbody tr:hover { background: #1c1f26; }
|
||||
tbody td.endpoint { font-family: 'SF Mono', 'Fira Code', monospace; font-size: 12px; color: #58a6ff; }
|
||||
|
||||
.bar-cell { position: relative; }
|
||||
.bar-bg { position: absolute; left: 0; top: 2px; bottom: 2px; border-radius: 3px; opacity: 0.15; }
|
||||
.bar-db { background: #f0883e; }
|
||||
.bar-app { background: #58a6ff; }
|
||||
.bar-wrap { display: flex; height: 18px; border-radius: 3px; overflow: hidden; min-width: 80px; }
|
||||
.bar-seg-db { background: #f0883e; height: 100%; }
|
||||
.bar-seg-app { background: #58a6ff; height: 100%; }
|
||||
|
||||
.legend { display: flex; gap: 16px; font-size: 11px; color: #8b949e; margin-bottom: 12px; }
|
||||
.legend span { display: flex; align-items: center; gap: 4px; }
|
||||
.legend .dot { width: 10px; height: 10px; border-radius: 2px; }
|
||||
.legend .dot.db { background: #f0883e; }
|
||||
.legend .dot.app { background: #58a6ff; }
|
||||
|
||||
.status { padding: 8px 12px; background: #1c1f26; border-radius: 6px; font-size: 12px; color: #8b949e; margin-bottom: 16px; }
|
||||
.status.error { border: 1px solid #da3633; color: #f85149; }
|
||||
.status.loading { border: 1px solid #30363d; }
|
||||
|
||||
.tag { display: inline-block; padding: 1px 6px; border-radius: 4px; font-size: 11px; font-weight: 500; }
|
||||
.tag.fast { background: #23863620; color: #3fb950; }
|
||||
.tag.ok { background: #d29b0020; color: #d29922; }
|
||||
.tag.slow { background: #da363320; color: #f85149; }
|
||||
|
||||
.auto-refresh { display: flex; align-items: center; gap: 6px; margin-left: auto; }
|
||||
.auto-refresh input[type=checkbox] { accent-color: #238636; }
|
||||
.timestamp { font-size: 11px; color: #484f58; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>API Performance Dashboard</h1>
|
||||
|
||||
<div class="controls">
|
||||
<label>Time range:
|
||||
<select id="hours">
|
||||
<option value="1">Last 1 hour</option>
|
||||
<option value="6">Last 6 hours</option>
|
||||
<option value="24" selected>Last 24 hours</option>
|
||||
<option value="72">Last 3 days</option>
|
||||
<option value="168">Last 7 days</option>
|
||||
<option value="720">Last 30 days</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Rows:
|
||||
<input type="number" id="limit" value="20" min="5" max="100" style="width:60px">
|
||||
</label>
|
||||
<button onclick="loadAll()">Refresh</button>
|
||||
<div class="auto-refresh">
|
||||
<input type="checkbox" id="autoRefresh">
|
||||
<label for="autoRefresh" style="font-size:12px;color:#8b949e;cursor:pointer">Auto-refresh 30s</label>
|
||||
</div>
|
||||
<span class="timestamp" id="lastUpdated"></span>
|
||||
</div>
|
||||
|
||||
<div id="status" class="status loading">Loading...</div>
|
||||
|
||||
<div id="summarySection" class="section" style="display:none">
|
||||
<div class="summary-cards" id="summaryCards"></div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span><span class="dot db"></span> DB time</span>
|
||||
<span><span class="dot app"></span> App time</span>
|
||||
</div>
|
||||
|
||||
<div id="countSection" class="section" style="display:none">
|
||||
<h2>Top Endpoints by Volume <span class="badge" id="countBadge"></span></h2>
|
||||
<div style="overflow-x:auto"><table id="countTable"><thead></thead><tbody></tbody></table></div>
|
||||
</div>
|
||||
|
||||
<div id="latencySection" class="section" style="display:none">
|
||||
<h2>Top Endpoints by Latency <span class="badge" id="latencyBadge"></span></h2>
|
||||
<div style="overflow-x:auto"><table id="latencyTable"><thead></thead><tbody></tbody></table></div>
|
||||
</div>
|
||||
|
||||
<div id="slowSection" class="section" style="display:none">
|
||||
<h2>Slowest Individual Requests <span class="badge" id="slowBadge"></span></h2>
|
||||
<div style="overflow-x:auto"><table id="slowTable"><thead></thead><tbody></tbody></table></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const API = 'perf.cfm';
|
||||
let refreshTimer = null;
|
||||
|
||||
function qs(s) { return document.querySelector(s); }
|
||||
function fmt(n) { return n == null ? '-' : Number(n).toLocaleString(); }
|
||||
function fmtDate(s) {
|
||||
if (!s || s === 'none') return 'none';
|
||||
var d = new Date(s.replace(' ', 'T'));
|
||||
if (isNaN(d)) return s;
|
||||
var mo = d.getMonth() + 1, dy = d.getDate(), yr = String(d.getFullYear()).slice(-2);
|
||||
var h = d.getHours(), mi = String(d.getMinutes()).padStart(2, '0'), ap = h >= 12 ? 'p' : 'a';
|
||||
h = h % 12 || 12;
|
||||
return { date: mo + '/' + dy + '/' + yr, time: h + ':' + mi + ap };
|
||||
}
|
||||
function fmtMs(n) {
|
||||
if (n == null) return '-';
|
||||
n = Number(n);
|
||||
if (n < 100) return '<span class="tag fast">' + n + 'ms</span>';
|
||||
if (n < 500) return '<span class="tag ok">' + n + 'ms</span>';
|
||||
return '<span class="tag slow">' + n + 'ms</span>';
|
||||
}
|
||||
function fmtBytes(n) {
|
||||
if (!n) return '-';
|
||||
n = Number(n);
|
||||
if (n < 1024) return n + ' B';
|
||||
if (n < 1048576) return (n / 1024).toFixed(1) + ' KB';
|
||||
return (n / 1048576).toFixed(1) + ' MB';
|
||||
}
|
||||
function pct(part, total) { return total > 0 ? Math.round(part / total * 100) : 0; }
|
||||
|
||||
function timeBar(dbMs, appMs) {
|
||||
var total = (dbMs || 0) + (appMs || 0);
|
||||
if (total === 0) return '';
|
||||
var dbPct = pct(dbMs, total);
|
||||
var appPct = 100 - dbPct;
|
||||
return '<div class="bar-wrap" title="DB: ' + dbMs + 'ms / App: ' + appMs + 'ms">'
|
||||
+ '<div class="bar-seg-db" style="width:' + dbPct + '%"></div>'
|
||||
+ '<div class="bar-seg-app" style="width:' + appPct + '%"></div>'
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
function endpointName(ep) {
|
||||
return ep.replace(/^\/api\//, '');
|
||||
}
|
||||
|
||||
async function fetchView(view) {
|
||||
var h = qs('#hours').value;
|
||||
var l = qs('#limit').value;
|
||||
var r = await fetch(API + '?view=' + view + '&hours=' + h + '&limit=' + l);
|
||||
return r.json();
|
||||
}
|
||||
|
||||
async function loadAll() {
|
||||
qs('#status').className = 'status loading';
|
||||
qs('#status').textContent = 'Loading...';
|
||||
qs('#status').style.display = '';
|
||||
|
||||
try {
|
||||
var [summary, count, latency, slow] = await Promise.all([
|
||||
fetchView('summary'), fetchView('count'), fetchView('latency'), fetchView('slow')
|
||||
]);
|
||||
|
||||
if (!summary.OK) throw new Error(summary.MESSAGE || summary.ERROR);
|
||||
|
||||
qs('#status').style.display = 'none';
|
||||
|
||||
// Summary cards
|
||||
var s = summary.DATA;
|
||||
qs('#summaryCards').innerHTML =
|
||||
card('Total Requests', fmt(s.TotalRequests), '') +
|
||||
card('Unique Endpoints', fmt(s.UniqueEndpoints), '') +
|
||||
card('Avg Latency', s.OverallAvgMs || 0, 'ms') +
|
||||
card('Max Latency', s.OverallMaxMs || 0, 'ms') +
|
||||
card('Avg DB Time', s.OverallAvgDbMs || 0, 'ms') +
|
||||
card('Avg App Time', s.OverallAvgAppMs || 0, 'ms') +
|
||||
card('Avg Queries', s.OverallAvgQueries || 0, '/req') +
|
||||
cardDate('Data Since', fmtDate(s.FirstLog));
|
||||
qs('#summarySection').style.display = '';
|
||||
|
||||
// Count table
|
||||
renderCountTable(count.DATA || []);
|
||||
|
||||
// Latency table
|
||||
renderLatencyTable(latency.DATA || []);
|
||||
|
||||
// Slow table
|
||||
renderSlowTable(slow.DATA || []);
|
||||
|
||||
qs('#lastUpdated').textContent = 'Updated ' + new Date().toLocaleTimeString();
|
||||
|
||||
} catch (e) {
|
||||
qs('#status').className = 'status error';
|
||||
qs('#status').textContent = 'Error: ' + e.message;
|
||||
qs('#status').style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
function card(label, value, unit) {
|
||||
return '<div class="card"><div class="label">' + label + '</div><div class="value">' + value + ' <span class="unit">' + unit + '</span></div></div>';
|
||||
}
|
||||
function cardDate(label, dt) {
|
||||
if (!dt || !dt.date) return card(label, 'none', '');
|
||||
return '<div class="card"><div class="label">' + label + '</div><div class="value">' + dt.date + '</div><div class="sub">' + dt.time + '</div></div>';
|
||||
}
|
||||
|
||||
function renderCountTable(data) {
|
||||
if (!data.length) { qs('#countSection').style.display = 'none'; return; }
|
||||
qs('#countBadge').textContent = data.length + ' endpoints';
|
||||
var maxCalls = Math.max(...data.map(r => r.Calls));
|
||||
var html = '<thead><tr><th>Endpoint</th><th class="num">Calls</th><th class="num">Avg</th><th class="num">DB</th><th class="num">App</th><th>DB / App Split</th><th class="num">Max</th><th class="num">Queries</th><th class="num">Avg Size</th></tr></thead><tbody>';
|
||||
data.forEach(function(r) {
|
||||
html += '<tr>'
|
||||
+ '<td class="endpoint">' + endpointName(r.Endpoint) + '</td>'
|
||||
+ '<td class="num">' + fmt(r.Calls) + '</td>'
|
||||
+ '<td class="num">' + fmtMs(r.AvgMs) + '</td>'
|
||||
+ '<td class="num">' + fmt(r.AvgDbMs) + 'ms</td>'
|
||||
+ '<td class="num">' + fmt(r.AvgAppMs) + 'ms</td>'
|
||||
+ '<td>' + timeBar(r.AvgDbMs, r.AvgAppMs) + '</td>'
|
||||
+ '<td class="num">' + fmtMs(r.MaxMs) + '</td>'
|
||||
+ '<td class="num">' + r.AvgQueries + '</td>'
|
||||
+ '<td class="num">' + fmtBytes(r.AvgBytes) + '</td>'
|
||||
+ '</tr>';
|
||||
});
|
||||
html += '</tbody>';
|
||||
qs('#countTable').innerHTML = html;
|
||||
qs('#countSection').style.display = '';
|
||||
}
|
||||
|
||||
function renderLatencyTable(data) {
|
||||
if (!data.length) { qs('#latencySection').style.display = 'none'; return; }
|
||||
qs('#latencyBadge').textContent = data.length + ' endpoints';
|
||||
var html = '<thead><tr><th>Endpoint</th><th class="num">Calls</th><th class="num">Avg</th><th class="num">DB</th><th class="num">App</th><th>DB / App Split</th><th class="num">Max</th><th class="num">Queries</th></tr></thead><tbody>';
|
||||
data.forEach(function(r) {
|
||||
html += '<tr>'
|
||||
+ '<td class="endpoint">' + endpointName(r.Endpoint) + '</td>'
|
||||
+ '<td class="num">' + fmt(r.Calls) + '</td>'
|
||||
+ '<td class="num">' + fmtMs(r.AvgMs) + '</td>'
|
||||
+ '<td class="num">' + fmt(r.AvgDbMs) + 'ms</td>'
|
||||
+ '<td class="num">' + fmt(r.AvgAppMs) + 'ms</td>'
|
||||
+ '<td>' + timeBar(r.AvgDbMs, r.AvgAppMs) + '</td>'
|
||||
+ '<td class="num">' + fmtMs(r.MaxMs) + '</td>'
|
||||
+ '<td class="num">' + r.AvgQueries + '</td>'
|
||||
+ '</tr>';
|
||||
});
|
||||
html += '</tbody>';
|
||||
qs('#latencyTable').innerHTML = html;
|
||||
qs('#latencySection').style.display = '';
|
||||
}
|
||||
|
||||
function renderSlowTable(data) {
|
||||
if (!data.length) { qs('#slowSection').style.display = 'none'; return; }
|
||||
qs('#slowBadge').textContent = data.length + ' requests';
|
||||
var html = '<thead><tr><th>Endpoint</th><th class="num">Total</th><th class="num">DB</th><th class="num">App</th><th>DB / App Split</th><th class="num">Queries</th><th class="num">Size</th><th class="num">Biz</th><th>When</th></tr></thead><tbody>';
|
||||
data.forEach(function(r) {
|
||||
html += '<tr>'
|
||||
+ '<td class="endpoint">' + endpointName(r.Endpoint) + '</td>'
|
||||
+ '<td class="num">' + fmtMs(r.TotalMs) + '</td>'
|
||||
+ '<td class="num">' + fmt(r.DbMs) + 'ms</td>'
|
||||
+ '<td class="num">' + fmt(r.AppMs) + 'ms</td>'
|
||||
+ '<td>' + timeBar(r.DbMs, r.AppMs) + '</td>'
|
||||
+ '<td class="num">' + r.QueryCount + '</td>'
|
||||
+ '<td class="num">' + fmtBytes(r.ResponseBytes) + '</td>'
|
||||
+ '<td class="num">' + (r.BusinessID || '-') + '</td>'
|
||||
+ '<td style="font-size:11px;color:#8b949e;white-space:nowrap">' + (r.LoggedAt || '') + '</td>'
|
||||
+ '</tr>';
|
||||
});
|
||||
html += '</tbody>';
|
||||
qs('#slowTable').innerHTML = html;
|
||||
qs('#slowSection').style.display = '';
|
||||
}
|
||||
|
||||
// Auto-refresh
|
||||
qs('#autoRefresh').addEventListener('change', function() {
|
||||
if (this.checked) {
|
||||
refreshTimer = setInterval(loadAll, 30000);
|
||||
} else {
|
||||
clearInterval(refreshTimer);
|
||||
refreshTimer = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Load on page open
|
||||
loadAll();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
179
api/admin/perf.cfm
Normal file
179
api/admin/perf.cfm
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<cfsetting showdebugoutput="false">
|
||||
<cfsetting enablecfoutputonly="true">
|
||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||
<cfheader name="Cache-Control" value="no-store">
|
||||
|
||||
<cfscript>
|
||||
function apiAbort(payload) {
|
||||
writeOutput(serializeJSON(payload));
|
||||
abort;
|
||||
}
|
||||
|
||||
// Localhost-only protection
|
||||
remoteAddr = cgi.REMOTE_ADDR;
|
||||
if (remoteAddr != "127.0.0.1" && remoteAddr != "::1" && remoteAddr != "0:0:0:0:0:0:0:1" && remoteAddr != "10.10.0.2") {
|
||||
apiAbort({ "OK": false, "ERROR": "forbidden" });
|
||||
}
|
||||
|
||||
try {
|
||||
// Parse parameters
|
||||
view = structKeyExists(url, "view") ? lcase(url.view) : "count";
|
||||
hours = structKeyExists(url, "hours") ? val(url.hours) : 24;
|
||||
if (hours <= 0 || hours > 720) hours = 24;
|
||||
limitRows = structKeyExists(url, "limit") ? val(url.limit) : 20;
|
||||
if (limitRows <= 0 || limitRows > 100) limitRows = 20;
|
||||
|
||||
// Flush any buffered metrics first
|
||||
flushPerfBuffer();
|
||||
|
||||
response = { "OK": true, "VIEW": view, "HOURS": hours };
|
||||
|
||||
if (view == "count") {
|
||||
// Top endpoints by call count
|
||||
q = queryExecute("
|
||||
SELECT
|
||||
Endpoint,
|
||||
COUNT(*) as Calls,
|
||||
ROUND(AVG(TotalMs)) as AvgMs,
|
||||
ROUND(AVG(DbMs)) as AvgDbMs,
|
||||
ROUND(AVG(AppMs)) as AvgAppMs,
|
||||
MAX(TotalMs) as MaxMs,
|
||||
ROUND(AVG(QueryCount), 1) as AvgQueries,
|
||||
ROUND(AVG(ResponseBytes)) as AvgBytes
|
||||
FROM ApiPerfLogs
|
||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||
GROUP BY Endpoint
|
||||
ORDER BY Calls DESC
|
||||
LIMIT :lim
|
||||
", {
|
||||
hours: { value: hours, cfsqltype: "cf_sql_integer" },
|
||||
lim: { value: limitRows, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
rows = [];
|
||||
for (row in q) {
|
||||
arrayAppend(rows, {
|
||||
"Endpoint": row.Endpoint,
|
||||
"Calls": row.Calls,
|
||||
"AvgMs": row.AvgMs,
|
||||
"AvgDbMs": row.AvgDbMs,
|
||||
"AvgAppMs": row.AvgAppMs,
|
||||
"MaxMs": row.MaxMs,
|
||||
"AvgQueries": row.AvgQueries,
|
||||
"AvgBytes": row.AvgBytes
|
||||
});
|
||||
}
|
||||
response["DATA"] = rows;
|
||||
|
||||
} else if (view == "latency") {
|
||||
// Top endpoints by average latency
|
||||
q = queryExecute("
|
||||
SELECT
|
||||
Endpoint,
|
||||
COUNT(*) as Calls,
|
||||
ROUND(AVG(TotalMs)) as AvgMs,
|
||||
ROUND(AVG(DbMs)) as AvgDbMs,
|
||||
ROUND(AVG(AppMs)) as AvgAppMs,
|
||||
MAX(TotalMs) as MaxMs,
|
||||
ROUND(AVG(QueryCount), 1) as AvgQueries
|
||||
FROM ApiPerfLogs
|
||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||
GROUP BY Endpoint
|
||||
HAVING Calls >= 3
|
||||
ORDER BY AvgMs DESC
|
||||
LIMIT :lim
|
||||
", {
|
||||
hours: { value: hours, cfsqltype: "cf_sql_integer" },
|
||||
lim: { value: limitRows, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
rows = [];
|
||||
for (row in q) {
|
||||
arrayAppend(rows, {
|
||||
"Endpoint": row.Endpoint,
|
||||
"Calls": row.Calls,
|
||||
"AvgMs": row.AvgMs,
|
||||
"AvgDbMs": row.AvgDbMs,
|
||||
"AvgAppMs": row.AvgAppMs,
|
||||
"MaxMs": row.MaxMs,
|
||||
"AvgQueries": row.AvgQueries
|
||||
});
|
||||
}
|
||||
response["DATA"] = rows;
|
||||
|
||||
} else if (view == "slow") {
|
||||
// Slowest individual requests
|
||||
q = queryExecute("
|
||||
SELECT Endpoint, TotalMs, DbMs, AppMs, QueryCount, ResponseBytes,
|
||||
BusinessID, UserID, LoggedAt
|
||||
FROM ApiPerfLogs
|
||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||
ORDER BY TotalMs DESC
|
||||
LIMIT :lim
|
||||
", {
|
||||
hours: { value: hours, cfsqltype: "cf_sql_integer" },
|
||||
lim: { value: limitRows, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
rows = [];
|
||||
for (row in q) {
|
||||
arrayAppend(rows, {
|
||||
"Endpoint": row.Endpoint,
|
||||
"TotalMs": row.TotalMs,
|
||||
"DbMs": row.DbMs,
|
||||
"AppMs": row.AppMs,
|
||||
"QueryCount": row.QueryCount,
|
||||
"ResponseBytes": row.ResponseBytes,
|
||||
"BusinessID": row.BusinessID,
|
||||
"UserID": row.UserID,
|
||||
"LoggedAt": dateTimeFormat(row.LoggedAt, "yyyy-mm-dd HH:nn:ss")
|
||||
});
|
||||
}
|
||||
response["DATA"] = rows;
|
||||
|
||||
} else if (view == "summary") {
|
||||
// Overall summary stats
|
||||
q = queryExecute("
|
||||
SELECT
|
||||
COUNT(*) as TotalRequests,
|
||||
COUNT(DISTINCT Endpoint) as UniqueEndpoints,
|
||||
ROUND(AVG(TotalMs)) as OverallAvgMs,
|
||||
MAX(TotalMs) as OverallMaxMs,
|
||||
ROUND(AVG(DbMs)) as OverallAvgDbMs,
|
||||
ROUND(AVG(AppMs)) as OverallAvgAppMs,
|
||||
ROUND(AVG(QueryCount), 1) as OverallAvgQueries,
|
||||
MIN(LoggedAt) as FirstLog,
|
||||
MAX(LoggedAt) as LastLog
|
||||
FROM ApiPerfLogs
|
||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||
", {
|
||||
hours: { value: hours, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
response["DATA"] = {
|
||||
"TotalRequests": q.TotalRequests,
|
||||
"UniqueEndpoints": q.UniqueEndpoints,
|
||||
"OverallAvgMs": q.OverallAvgMs,
|
||||
"OverallMaxMs": q.OverallMaxMs,
|
||||
"OverallAvgDbMs": q.OverallAvgDbMs,
|
||||
"OverallAvgAppMs": q.OverallAvgAppMs,
|
||||
"OverallAvgQueries": q.OverallAvgQueries,
|
||||
"FirstLog": isDate(q.FirstLog) ? dateTimeFormat(q.FirstLog, "yyyy-mm-dd HH:nn:ss") : "",
|
||||
"LastLog": isDate(q.LastLog) ? dateTimeFormat(q.LastLog, "yyyy-mm-dd HH:nn:ss") : ""
|
||||
};
|
||||
|
||||
} else {
|
||||
apiAbort({ "OK": false, "ERROR": "invalid_view", "MESSAGE": "Use ?view=count|latency|slow|summary" });
|
||||
}
|
||||
|
||||
apiAbort(response);
|
||||
|
||||
} catch (any e) {
|
||||
apiAbort({
|
||||
"OK": false,
|
||||
"ERROR": "server_error",
|
||||
"MESSAGE": e.message,
|
||||
"DETAIL": e.detail
|
||||
});
|
||||
}
|
||||
</cfscript>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
// Add TaskTypeID column to QuickTaskTemplates table if it doesn't exist
|
||||
try {
|
||||
// Check if column exists
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'payfrit'
|
||||
AND TABLE_NAME = 'QuickTaskTemplates'
|
||||
|
|
@ -13,7 +13,7 @@ try {
|
|||
", [], { datasource: "payfrit" });
|
||||
|
||||
if (qCheck.recordCount == 0) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE QuickTaskTemplates
|
||||
ADD COLUMN TaskTypeID INT NULL AFTER TaskCategoryID
|
||||
", [], { datasource: "payfrit" });
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// One-time cleanup: delete test tasks and reset
|
||||
try {
|
||||
// Delete tasks 30, 31, 32 (test tasks with bad data)
|
||||
queryExecute("DELETE FROM Tasks WHERE ID IN (30, 31, 32)", [], { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM Tasks WHERE ID IN (30, 31, 32)", [], { datasource: "payfrit" });
|
||||
|
||||
writeOutput(serializeJSON({
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ try {
|
|||
}
|
||||
|
||||
// Get template details
|
||||
qTemplate = queryExecute("
|
||||
qTemplate = queryTimed("
|
||||
SELECT
|
||||
Title as Title,
|
||||
Details as Details,
|
||||
|
|
@ -67,7 +67,7 @@ try {
|
|||
}
|
||||
|
||||
// Create the task (ClaimedByUserID=0 means unclaimed/pending)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Tasks (
|
||||
BusinessID, CategoryID, TaskTypeID,
|
||||
Title, Details, CreatedOn, ClaimedByUserID
|
||||
|
|
@ -83,7 +83,7 @@ try {
|
|||
details: { value: qTemplate.Details, cfsqltype: "cf_sql_longvarchar", null: isNull(qTemplate.Details) }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
|
||||
apiAbort({
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<cfscript>
|
||||
try {
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT ID, Title, Details, TaskCategoryID, ClaimedByUserID, CompletedOn, CreatedOn
|
||||
FROM Tasks
|
||||
WHERE BusinessID = 47
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ try {
|
|||
}
|
||||
|
||||
// Verify template exists and belongs to this business
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT ID FROM QuickTaskTemplates
|
||||
WHERE ID = :id AND BusinessID = :businessID
|
||||
", {
|
||||
|
|
@ -61,7 +61,7 @@ try {
|
|||
}
|
||||
|
||||
// Soft delete by setting IsActive to 0
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE QuickTaskTemplates SET IsActive = 0
|
||||
WHERE ID = :id
|
||||
", {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ try {
|
|||
}
|
||||
|
||||
// Get quick task templates for this business
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT
|
||||
qt.ID,
|
||||
qt.Name as Name,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<cfscript>
|
||||
try {
|
||||
// Delete all Quick Task templates for business 1
|
||||
queryExecute("DELETE FROM QuickTaskTemplates WHERE BusinessID = 1", [], { datasource: "payfrit" });
|
||||
queryTimed("DELETE FROM QuickTaskTemplates WHERE BusinessID = 1", [], { datasource: "payfrit" });
|
||||
|
||||
writeOutput(serializeJSON({
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ try {
|
|||
|
||||
if (templateID > 0) {
|
||||
// UPDATE existing template
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT ID FROM QuickTaskTemplates
|
||||
WHERE ID = :id AND BusinessID = :businessID
|
||||
", {
|
||||
|
|
@ -80,7 +80,7 @@ try {
|
|||
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Template not found" });
|
||||
}
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE QuickTaskTemplates SET
|
||||
Name = :name,
|
||||
Title = :title,
|
||||
|
|
@ -108,7 +108,7 @@ try {
|
|||
} else {
|
||||
// INSERT new template
|
||||
// Get next sort order
|
||||
qSort = queryExecute("
|
||||
qSort = queryTimed("
|
||||
SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort
|
||||
FROM QuickTaskTemplates WHERE BusinessID = :businessID
|
||||
", {
|
||||
|
|
@ -117,7 +117,7 @@ try {
|
|||
|
||||
nextSort = qSort.nextSort;
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO QuickTaskTemplates (
|
||||
BusinessID, Name, Title,
|
||||
Details, TaskCategoryID,
|
||||
|
|
@ -136,7 +136,7 @@ try {
|
|||
sortOrder: { value: nextSort, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
|
||||
apiAbort({
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ function apiAbort(required struct payload) {
|
|||
|
||||
try {
|
||||
// Create QuickTaskTemplates table
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE TABLE IF NOT EXISTS QuickTaskTemplates (
|
||||
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||
BusinessID INT NOT NULL,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ try {
|
|||
}
|
||||
|
||||
// Verify exists and belongs to business
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT ID FROM ScheduledTaskDefinitions
|
||||
WHERE ID = :id AND BusinessID = :businessID
|
||||
", {
|
||||
|
|
@ -61,7 +61,7 @@ try {
|
|||
}
|
||||
|
||||
// Hard delete the definition
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
DELETE FROM ScheduledTaskDefinitions WHERE ID = :id
|
||||
", {
|
||||
id: { value: taskID, cfsqltype: "cf_sql_integer" }
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ try {
|
|||
}
|
||||
|
||||
// Get scheduled task definitions for this business
|
||||
q = queryExecute("
|
||||
q = queryTimed("
|
||||
SELECT
|
||||
st.ID,
|
||||
st.Name as Name,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ try {
|
|||
}
|
||||
|
||||
// Get scheduled task definition
|
||||
qDef = queryExecute("
|
||||
qDef = queryTimed("
|
||||
SELECT
|
||||
Title as Title,
|
||||
Details as Details,
|
||||
|
|
@ -66,7 +66,7 @@ try {
|
|||
}
|
||||
|
||||
// Create the task (ClaimedByUserID=0 means unclaimed/pending)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Tasks (
|
||||
BusinessID, CategoryID, TaskTypeID,
|
||||
Title, Details, CreatedOn, ClaimedByUserID
|
||||
|
|
@ -82,7 +82,7 @@ try {
|
|||
details: { value: qDef.Details, cfsqltype: "cf_sql_longvarchar", null: isNull(qDef.Details) }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
|
||||
apiAbort({
|
||||
"OK": true,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ function calculateNextRun(required string cronExpression) {
|
|||
|
||||
try {
|
||||
// Find all active scheduled tasks that are due
|
||||
dueTasks = queryExecute("
|
||||
dueTasks = queryTimed("
|
||||
SELECT
|
||||
ID AS ScheduledTaskID,
|
||||
BusinessID as BusinessID,
|
||||
|
|
@ -84,7 +84,7 @@ try {
|
|||
|
||||
for (task in dueTasks) {
|
||||
// Create the actual task (ClaimedByUserID=0 means unclaimed/pending)
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Tasks (
|
||||
BusinessID, CategoryID, TaskTypeID,
|
||||
Title, Details, CreatedOn, ClaimedByUserID
|
||||
|
|
@ -100,7 +100,7 @@ try {
|
|||
details: { value: task.Details, cfsqltype: "cf_sql_longvarchar", null: isNull(task.Details) }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
|
||||
// Calculate next run based on schedule type
|
||||
if (task.ScheduleType == "interval_after_completion" && !isNull(task.IntervalMinutes) && task.IntervalMinutes > 0) {
|
||||
|
|
@ -115,7 +115,7 @@ try {
|
|||
nextRun = calculateNextRun(task.CronExpression);
|
||||
}
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ScheduledTaskDefinitions SET
|
||||
LastRunOn = NOW(),
|
||||
NextRunOn = :nextRun
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ try {
|
|||
|
||||
if (taskID > 0) {
|
||||
// UPDATE existing
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT ID FROM ScheduledTaskDefinitions
|
||||
WHERE ID = :id AND BusinessID = :businessID
|
||||
", {
|
||||
|
|
@ -168,7 +168,7 @@ try {
|
|||
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Scheduled task not found" });
|
||||
}
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ScheduledTaskDefinitions SET
|
||||
Name = :name,
|
||||
Title = :title,
|
||||
|
|
@ -202,7 +202,7 @@ try {
|
|||
|
||||
} else {
|
||||
// INSERT new
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO ScheduledTaskDefinitions (
|
||||
BusinessID, Name, Title,
|
||||
Details, TaskCategoryID,
|
||||
|
|
@ -224,11 +224,11 @@ try {
|
|||
nextRun: { value: nextRunOn, cfsqltype: "cf_sql_timestamp" }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qNew = queryExecute("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
qNew = queryTimed("SELECT LAST_INSERT_ID() as newID", [], { datasource: "payfrit" });
|
||||
newScheduledTaskID = qNew.newID;
|
||||
|
||||
// Create the first task immediately
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Tasks (
|
||||
BusinessID, CategoryID, TaskTypeID,
|
||||
Title, Details, CreatedOn, ClaimedByUserID
|
||||
|
|
@ -244,7 +244,7 @@ try {
|
|||
details: { value: taskDetails, cfsqltype: "cf_sql_longvarchar", null: !len(taskDetails) }
|
||||
}, { datasource: "payfrit" });
|
||||
|
||||
qTask = queryExecute("SELECT LAST_INSERT_ID() as taskID", [], { datasource: "payfrit" });
|
||||
qTask = queryTimed("SELECT LAST_INSERT_ID() as taskID", [], { datasource: "payfrit" });
|
||||
|
||||
// Now set the NEXT run time (not the immediate one we just created)
|
||||
if (scheduleType == "interval" || scheduleType == "interval_after_completion") {
|
||||
|
|
@ -260,7 +260,7 @@ try {
|
|||
actualNextRun = calculateNextRun(cronExpression);
|
||||
}
|
||||
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ScheduledTaskDefinitions
|
||||
SET LastRunOn = NOW(),
|
||||
NextRunOn = :nextRun
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ function apiAbort(required struct payload) {
|
|||
|
||||
try {
|
||||
// Create ScheduledTaskDefinitions table
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
CREATE TABLE IF NOT EXISTS ScheduledTaskDefinitions (
|
||||
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||
BusinessID INT NOT NULL,
|
||||
|
|
@ -37,7 +37,7 @@ try {
|
|||
|
||||
// Add new columns if they don't exist (for existing tables)
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE ScheduledTaskDefinitions
|
||||
ADD COLUMN ScheduleType VARCHAR(20) DEFAULT 'cron' AFTER CronExpression
|
||||
", [], { datasource: "payfrit" });
|
||||
|
|
@ -46,7 +46,7 @@ try {
|
|||
}
|
||||
|
||||
try {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
ALTER TABLE ScheduledTaskDefinitions
|
||||
ADD COLUMN IntervalMinutes INT NULL AFTER ScheduleType
|
||||
", [], { datasource: "payfrit" });
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ try {
|
|||
}
|
||||
|
||||
// Verify exists and get cron expression and schedule type
|
||||
qCheck = queryExecute("
|
||||
qCheck = queryTimed("
|
||||
SELECT ID, CronExpression as CronExpression,
|
||||
COALESCE(ScheduleType, 'cron') as ScheduleType,
|
||||
IntervalMinutes as IntervalMinutes
|
||||
|
|
@ -128,7 +128,7 @@ try {
|
|||
|
||||
// Update status
|
||||
if (isActive) {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ScheduledTaskDefinitions SET
|
||||
IsActive = :isActive,
|
||||
NextRunOn = :nextRun
|
||||
|
|
@ -139,7 +139,7 @@ try {
|
|||
id: { value: taskID, cfsqltype: "cf_sql_integer" }
|
||||
}, { datasource: "payfrit" });
|
||||
} else {
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE ScheduledTaskDefinitions SET IsActive = :isActive
|
||||
WHERE ID = :id
|
||||
", {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U
|
|||
|
||||
if (len(userToken)) {
|
||||
try {
|
||||
qTok = queryExecute(
|
||||
qTok = queryTimed(
|
||||
"SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1",
|
||||
[ { value = userToken, cfsqltype = "cf_sql_varchar" } ],
|
||||
{ datasource = "payfrit" }
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ try {
|
|||
}
|
||||
|
||||
// Check if email is already used by another verified account
|
||||
qEmailCheck = queryExecute("
|
||||
qEmailCheck = queryTimed("
|
||||
SELECT ID FROM Users
|
||||
WHERE EmailAddress = :email
|
||||
AND IsEmailVerified = 1
|
||||
|
|
@ -86,13 +86,13 @@ try {
|
|||
}
|
||||
|
||||
// Get current user UUID for email confirmation link
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
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("
|
||||
queryTimed("
|
||||
UPDATE Users
|
||||
SET FirstName = :firstName,
|
||||
LastName = :lastName,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ if (!len(username) || !len(password)) {
|
|||
}
|
||||
|
||||
try {
|
||||
q = queryExecute(
|
||||
q = queryTimed(
|
||||
"
|
||||
SELECT ID, FirstName
|
||||
FROM Users
|
||||
|
|
@ -81,7 +81,7 @@ try {
|
|||
|
||||
token = replace(createUUID(), "-", "", "all");
|
||||
|
||||
queryExecute(
|
||||
queryTimed(
|
||||
"INSERT INTO UserTokens (UserID, Token) VALUES (?, ?)",
|
||||
[
|
||||
{ value = q.ID, cfsqltype = "cf_sql_integer" },
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ try {
|
|||
}
|
||||
|
||||
// Find verified account with this phone
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
SELECT ID, UUID
|
||||
FROM Users
|
||||
WHERE ContactNumber = :phone
|
||||
|
|
@ -68,7 +68,7 @@ try {
|
|||
userUUID = qUser.UUID;
|
||||
if (!len(trim(userUUID))) {
|
||||
userUUID = replace(createUUID(), "-", "", "all");
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Users SET UUID = :uuid WHERE ID = :userId
|
||||
", {
|
||||
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
|
||||
|
|
@ -82,7 +82,7 @@ try {
|
|||
&& structKeyExists(application, "MAGIC_OTP_CODE") && len(application.MAGIC_OTP_CODE)) {
|
||||
otp = application.MAGIC_OTP_CODE;
|
||||
}
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Users
|
||||
SET MobileVerifyCode = :otp
|
||||
WHERE ID = :userId
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.U
|
|||
userToken = getHeader("X-User-Token");
|
||||
if (len(userToken)) {
|
||||
try {
|
||||
qTok = queryExecute(
|
||||
qTok = queryTimed(
|
||||
"SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1",
|
||||
[ { value = userToken, cfsqltype = "cf_sql_varchar" } ],
|
||||
{ datasource = "payfrit" }
|
||||
|
|
@ -57,7 +57,7 @@ if (userId <= 0) {
|
|||
// Handle GET - return profile
|
||||
if (cgi.REQUEST_METHOD == "GET") {
|
||||
try {
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
SELECT
|
||||
ID,
|
||||
FirstName,
|
||||
|
|
@ -124,14 +124,14 @@ if (cgi.REQUEST_METHOD == "POST") {
|
|||
}
|
||||
|
||||
// Execute update
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Users
|
||||
SET #arrayToList(updates, ', ')#
|
||||
WHERE ID = :userId
|
||||
", params);
|
||||
|
||||
// Return updated profile
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
SELECT
|
||||
ID,
|
||||
FirstName,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ genericResponse = { "OK": true, "MESSAGE": "If an account exists, a code has bee
|
|||
|
||||
try {
|
||||
// Look up user by email
|
||||
qUser = queryExecute("
|
||||
qUser = queryTimed("
|
||||
SELECT ID, FirstName
|
||||
FROM Users
|
||||
WHERE EmailAddress = :email
|
||||
|
|
@ -56,7 +56,7 @@ try {
|
|||
userId = qUser.ID;
|
||||
|
||||
// Rate limit: max 3 codes per user in last 10 minutes
|
||||
qRateCheck = queryExecute("
|
||||
qRateCheck = queryTimed("
|
||||
SELECT COUNT(*) AS cnt
|
||||
FROM OTPCodes
|
||||
WHERE UserID = :userId
|
||||
|
|
@ -81,7 +81,7 @@ try {
|
|||
}
|
||||
|
||||
// Store in DB with 10-minute expiry
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO OTPCodes (UserID, Code, ExpiresAt)
|
||||
VALUES (:userId, :code, DATE_ADD(NOW(), INTERVAL 10 MINUTE))
|
||||
", {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ 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("
|
||||
qExisting = queryTimed("
|
||||
SELECT ID, UUID, FirstName
|
||||
FROM Users
|
||||
WHERE ContactNumber = :phone
|
||||
|
|
@ -72,7 +72,7 @@ try {
|
|||
|
||||
// Check for incomplete account with this phone (verified but no profile, OR unverified)
|
||||
// These accounts can be reused for signup
|
||||
qIncomplete = queryExecute("
|
||||
qIncomplete = queryTimed("
|
||||
SELECT ID, UUID
|
||||
FROM Users
|
||||
WHERE ContactNumber = :phone
|
||||
|
|
@ -90,7 +90,7 @@ try {
|
|||
if (qIncomplete.recordCount > 0) {
|
||||
// Update existing incomplete record with new OTP and reset for re-registration
|
||||
userUUID = qIncomplete.UUID;
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
UPDATE Users
|
||||
SET MobileVerifyCode = :otp,
|
||||
IsContactVerified = 0,
|
||||
|
|
@ -103,7 +103,7 @@ try {
|
|||
} else {
|
||||
// Create new user record
|
||||
userUUID = replace(createUUID(), "-", "", "all");
|
||||
queryExecute("
|
||||
queryTimed("
|
||||
INSERT INTO Users (
|
||||
ContactNumber,
|
||||
UUID,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ try {
|
|||
}
|
||||
|
||||
// Look up the token
|
||||
qToken = queryExecute("
|
||||
qToken = queryTimed("
|
||||
SELECT ut.UserID, u.FirstName, u.LastName
|
||||
FROM UserTokens ut
|
||||
JOIN Users u ON u.ID = ut.UserID
|
||||
|
|
@ -47,7 +47,7 @@ try {
|
|||
userID = qToken.UserID;
|
||||
|
||||
// Determine if user is a worker (has any active employment)
|
||||
qWorker = queryExecute("
|
||||
qWorker = queryTimed("
|
||||
SELECT COUNT(*) as cnt
|
||||
FROM Employees
|
||||
WHERE UserID = :userID AND IsActive = 1
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue