This repository has been archived on 2026-03-21. You can view files and clone it, but cannot push or open issues or pull requests.
payfrit-biz/api/admin/migrateToCategories.cfm
John Mizerek 8acf2f3249 Complete DB column normalization: strip redundant table-name prefixes from all SQL queries
Updated 70 files to match the payfrit_dev schema where columns like
BusinessName→Name, UserFirstName→FirstName, AddressCity→City, etc.
PKs renamed to ID, FKs keep referenced table name (e.g. BusinessID).
SQL aliases preserve original JSON response keys for API compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:03:40 -08:00

134 lines
4.7 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">
<cfscript>
/**
* Migrate Unified Schema to Categories
*
* This script:
* 1. Finds all "category" Items (ParentID=0, not templates, not collapsible)
* 2. Creates corresponding entries in Categories table
* 3. Updates child Items with the new CategoryID
*
* GET: ?BusinessID=27 (or all if not specified)
*/
response = { "OK": false, "BusinessesProcessed": [], "Errors": [] };
try {
// Get BusinessID from URL if specified
businessFilter = "";
if (structKeyExists(url, "BusinessID") && val(url.BusinessID) > 0) {
businessFilter = val(url.BusinessID);
}
// Find all businesses with items in unified schema
if (len(businessFilter)) {
qBusinesses = queryExecute("
SELECT DISTINCT BusinessID as BusinessID
FROM Items
WHERE BusinessID = :bid AND BusinessID > 0
", { bid: businessFilter }, { datasource: "payfrit" });
} else {
qBusinesses = queryExecute("
SELECT DISTINCT BusinessID as BusinessID
FROM Items
WHERE BusinessID > 0
", {}, { datasource: "payfrit" });
}
for (biz in qBusinesses) {
bizId = biz.ID;
bizResult = { "BusinessID": bizId, "CategoriesCreated": 0, "ItemsUpdated": 0 };
try {
// Find category-like Items (parent=0, not collapsible, has children, not in template links)
qCategoryItems = queryExecute("
SELECT DISTINCT
p.ID,
p.Name,
p.SortOrder
FROM Items p
INNER JOIN Items c ON c.ParentItemID = p.ID
WHERE p.BusinessID = :bizId
AND p.ParentItemID = 0
AND (p.IsCollapsible = 0 OR p.IsCollapsible IS NULL)
AND NOT EXISTS (
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ID
)
ORDER BY p.SortOrder, p.Name
", { bizId: bizId }, { datasource: "payfrit" });
sortOrder = 0;
for (catItem in qCategoryItems) {
// Check if category already exists for this business with same name
qExisting = queryExecute("
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("
SELECT COALESCE(MAX(ID), 0) + 1 as nextId FROM Categories
", {}, { datasource: "payfrit" });
newCatId = qMaxId.nextId;
// Create new category with explicit ID
queryExecute("
INSERT INTO Categories
(ID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn)
VALUES (:catId, :bizId, 0, :name, :sortOrder, NOW())
", {
catId: newCatId,
bizId: bizId,
name: left(catItem.Name, 30),
sortOrder: sortOrder
}, { datasource: "payfrit" });
bizResult.CategoriesCreated++;
} else {
newCatId = qExisting.ID;
}
// Update all children of this category Item to have the new CategoryID
queryExecute("
UPDATE Items
SET CategoryID = :catId
WHERE ParentItemID = :parentId
AND BusinessID = :bizId
", {
catId: newCatId,
parentId: catItem.ID,
bizId: bizId
}, { datasource: "payfrit" });
qUpdated = queryExecute("SELECT ROW_COUNT() as cnt", {}, { datasource: "payfrit" });
bizResult.ItemsUpdated += qUpdated.cnt;
sortOrder++;
}
arrayAppend(response.BusinessesProcessed, bizResult);
} catch (any bizErr) {
arrayAppend(response.Errors, {
"BusinessID": bizId,
"Error": bizErr.message
});
}
}
response["OK"] = true;
response["TotalBusinesses"] = qBusinesses.recordCount;
} catch (any e) {
response["ERROR"] = "server_error";
response["MESSAGE"] = e.message;
response["DETAIL"] = e.detail;
}
writeOutput(serializeJSON(response));
</cfscript>