Normalize database column and table names across entire codebase
Update all SQL queries, query result references, and ColdFusion code to match
the renamed database schema. Tables use plural CamelCase, PKs are all `ID`,
column prefixes stripped (e.g. BusinessName→Name, UserFirstName→FirstName).
Key changes:
- Strip table-name prefixes from all column references (Businesses, Users,
Addresses, Hours, Menus, Categories, Items, Stations, Orders,
OrderLineItems, Tasks, TaskCategories, TaskRatings, QuickTaskTemplates,
ScheduledTaskDefinitions, ChatMessages, Beacons, ServicePoints, Employees,
VisitorTrackings, ApiPerfLogs, tt_States, tt_Days, tt_AddressTypes,
tt_OrderTypes, tt_TaskTypes)
- Rename PK references from {TableName}ID to ID in all queries
- Rewrite 7 admin beacon files to use ServicePoints.BeaconID instead of
dropped lt_Beacon_Businesses_ServicePoints link table
- Rewrite beacon assignment files (list, save, delete) for new schema
- Fix FK references incorrectly changed to ID (OrderLineItems.OrderID,
Categories.MenuID, Tasks.CategoryID, ServicePoints.BeaconID)
- Update Addresses: AddressLat→Latitude, AddressLng→Longitude
- Update Users: UserPassword→Password, UserIsEmailVerified→IsEmailVerified,
UserIsActive→IsActive, UserBalance→Balance, etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
dc9db32b58
commit
1210249f54
240 changed files with 6644 additions and 5542 deletions
|
|
@ -24,9 +24,9 @@
|
||||||
<cfif request.UserID NEQ 0>
|
<cfif request.UserID NEQ 0>
|
||||||
|
|
||||||
<cfquery name="check_user" datasource="#application.datasource#">
|
<cfquery name="check_user" datasource="#application.datasource#">
|
||||||
SELECT UserFirstName, UserBalance, UserImageExtension
|
SELECT FirstName, Balance, ImageExtension
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE UserID = #request.UserID#
|
WHERE ID = #request.UserID#
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
@ -320,8 +320,8 @@
|
||||||
<cfif find("logout.cfm", request.cgiPath) EQ 0>
|
<cfif find("logout.cfm", request.cgiPath) EQ 0>
|
||||||
|
|
||||||
<cfif request.UserID NEQ 0>
|
<cfif request.UserID NEQ 0>
|
||||||
<cfif check_user.UserImageExtension gt ""><img src="#application.image_display_prefix#users/thumbs/#request.UserID#.#check_user.UserImageExtension#" border="0" alt=""><br></cfif>
|
<cfif check_user.ImageExtension gt ""><img src="#application.image_display_prefix#users/thumbs/#request.UserID#.#check_user.ImageExtension#" border="0" alt=""><br></cfif>
|
||||||
Hi, <cfif check_user.UserFirstName gt "">#check_user.UserFirstName#<br>#dollarformat(check_user.UserBalance)#<cfelse>Payfrit User</cfif><br>
|
Hi, <cfif check_user.FirstName gt "">#check_user.FirstName#<br>#dollarformat(check_user.Balance)#<cfelse>Payfrit User</cfif><br>
|
||||||
<cfelse>
|
<cfelse>
|
||||||
|
|
||||||
<form action="#application.wwwrootprefix#index.cfm" method="post" name="login_form" id="login_form">
|
<form action="#application.wwwrootprefix#index.cfm" method="post" name="login_form" id="login_form">
|
||||||
|
|
|
||||||
14
_process.cfm
14
_process.cfm
|
|
@ -116,13 +116,13 @@
|
||||||
<cfset cart_total = 0>
|
<cfset cart_total = 0>
|
||||||
|
|
||||||
<CFQUERY name="get_queued_food" datasource="#application.datasource#" dbtype="ODBC">
|
<CFQUERY name="get_queued_food" datasource="#application.datasource#" dbtype="ODBC">
|
||||||
SELECT A.CartID, A.AddedOn, A.Quantity, A.SpecialRemark, B.BusinessName, B.UserID, C.ItemName, A.Price, D.UserFirstName, D.LaerFirstName, D.Balance
|
SELECT A.CartID, A.AddedOn, A.Quantity, A.SpecialRemark, B.Name, B.UserID, C.Name, A.Price, D.FirstName, D.LaerFirstName, D.Balance
|
||||||
FROM dbo.Business_CartMaster A, dbo.BusinessMaster B, dbo.Business_ItemMaster C, Users D
|
FROM dbo.Business_CartMaster A, dbo.BusinessMaster B, dbo.Business_ItemMaster C, Users D
|
||||||
WHERE A.UserID = D.UserID
|
WHERE A.UserID = D.UserID
|
||||||
AND
|
AND
|
||||||
A.ItemID = C.ItemID
|
A.ItemID = C.ItemID
|
||||||
AND
|
AND
|
||||||
B.BusinessID = C.BusinessID
|
B.ID = C.BusinessID
|
||||||
AND
|
AND
|
||||||
C.BusinessID = #form.bizid#
|
C.BusinessID = #form.bizid#
|
||||||
AND
|
AND
|
||||||
|
|
@ -170,11 +170,11 @@
|
||||||
</CFQUERY>
|
</CFQUERY>
|
||||||
|
|
||||||
<CFQUERY name="get_last_inserted" datasource="#application.datasource#" dbtype="ODBC">
|
<CFQUERY name="get_last_inserted" datasource="#application.datasource#" dbtype="ODBC">
|
||||||
SELECT TOP 1 O.OrderID, M.UserID as person_to_pay_for_orderID, U.Balance
|
SELECT TOP 1 O.ID, M.UserID as person_to_pay_for_orderID, U.Balance
|
||||||
FROM dbo.Business_OrderMaster O, dbo.BusinessMaster M, Users U
|
FROM dbo.Business_OrderMaster O, dbo.BusinessMaster M, Users U
|
||||||
WHERE O.BusinessID = M.BusinessID
|
WHERE O.BusinessID = M.BusinessID
|
||||||
AND
|
AND
|
||||||
M.UserID = U.UserID
|
M.UserID = U.ID
|
||||||
ORDER BY O.AddedOn DESC
|
ORDER BY O.AddedOn DESC
|
||||||
</CFQUERY>
|
</CFQUERY>
|
||||||
|
|
||||||
|
|
@ -185,7 +185,7 @@
|
||||||
)
|
)
|
||||||
VALUES
|
VALUES
|
||||||
(
|
(
|
||||||
#get_last_inserted.OrderID#,
|
#get_last_inserted.ID#,
|
||||||
#get_queued_food.CartID#
|
#get_queued_food.CartID#
|
||||||
)
|
)
|
||||||
</CFQUERY>
|
</CFQUERY>
|
||||||
|
|
@ -268,7 +268,7 @@
|
||||||
<CFQUERY name="get_user_104_balance" datasource="#application.datasource#" dbtype="ODBC">
|
<CFQUERY name="get_user_104_balance" datasource="#application.datasource#" dbtype="ODBC">
|
||||||
SELECT balance
|
SELECT balance
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE UserID = 104
|
WHERE ID = 104
|
||||||
</CFQUERY>
|
</CFQUERY>
|
||||||
|
|
||||||
<CFQUERY name="transfer_fees_to_UserID_104" datasource="#application.datasource#" dbtype="ODBC">
|
<CFQUERY name="transfer_fees_to_UserID_104" datasource="#application.datasource#" dbtype="ODBC">
|
||||||
|
|
@ -346,7 +346,7 @@
|
||||||
<CFQUERY name="get_user_104_balance" datasource="#application.datasource#" dbtype="ODBC">
|
<CFQUERY name="get_user_104_balance" datasource="#application.datasource#" dbtype="ODBC">
|
||||||
SELECT balance
|
SELECT balance
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE UserID = 104
|
WHERE ID = 104
|
||||||
</CFQUERY>
|
</CFQUERY>
|
||||||
|
|
||||||
<CFQUERY name="transfer_fees_to_UserID_104" datasource="#application.datasource#" dbtype="ODBC">
|
<CFQUERY name="transfer_fees_to_UserID_104" datasource="#application.datasource#" dbtype="ODBC">
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,8 @@ async function refreshAssignments(){
|
||||||
const tr = document.createElement("tr");
|
const tr = document.createElement("tr");
|
||||||
tr.innerHTML = `
|
tr.innerHTML = `
|
||||||
<td>${a.lt_Beacon_Businesses_ServicePointID}</td>
|
<td>${a.lt_Beacon_Businesses_ServicePointID}</td>
|
||||||
<td>${escapeHtml((a.BeaconName || "") + " (ID " + a.BeaconID + ")")}</td>
|
<td>${escapeHtml((a.Name || "") + " (ID " + a.BeaconID + ")")}</td>
|
||||||
<td>${escapeHtml((a.ServicePointName || "") + " (ID " + a.ServicePointID + ")")}</td>
|
<td>${escapeHtml((a.Name || "") + " (ID " + a.ServicePointID + ")")}</td>
|
||||||
<td>${escapeHtml(a.lt_Beacon_Businesses_ServicePointNotes || "")}</td>
|
<td>${escapeHtml(a.lt_Beacon_Businesses_ServicePointNotes || "")}</td>
|
||||||
<td>${escapeHtml(a.CreatedAt || "")}</td>
|
<td>${escapeHtml(a.CreatedAt || "")}</td>
|
||||||
`;
|
`;
|
||||||
|
|
@ -183,12 +183,12 @@ async function refreshBeacons(assignedBeaconIDs, keepSelectedBeaconID){
|
||||||
setSelectPlaceholder(sel, "-- Select Beacon --");
|
setSelectPlaceholder(sel, "-- Select Beacon --");
|
||||||
|
|
||||||
(out.BEACONS || []).forEach(b => {
|
(out.BEACONS || []).forEach(b => {
|
||||||
const isAssigned = assignedBeaconIDs.has(String(b.BeaconID));
|
const isAssigned = assignedBeaconIDs.has(String(b.ID));
|
||||||
if (HIDE_ASSIGNED_BEACONS && isAssigned) return;
|
if (HIDE_ASSIGNED_BEACONS && isAssigned) return;
|
||||||
|
|
||||||
const opt = document.createElement("option");
|
const opt = document.createElement("option");
|
||||||
opt.value = b.BeaconID;
|
opt.value = b.ID;
|
||||||
opt.textContent = String(b.BeaconID) + " - " + (b.BeaconName || "");
|
opt.textContent = String(b.ID) + " - " + (b.Name || "");
|
||||||
sel.appendChild(opt);
|
sel.appendChild(opt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -203,12 +203,12 @@ async function refreshServicePoints(assignedServicePointIDs, keepSelectedService
|
||||||
setSelectPlaceholder(sel, "-- Select ServicePoint --");
|
setSelectPlaceholder(sel, "-- Select ServicePoint --");
|
||||||
|
|
||||||
(out.SERVICEPOINTS || []).forEach(sp => {
|
(out.SERVICEPOINTS || []).forEach(sp => {
|
||||||
const isAssigned = assignedServicePointIDs.has(String(sp.ServicePointID));
|
const isAssigned = assignedServicePointIDs.has(String(sp.ID));
|
||||||
if (HIDE_ASSIGNED_SERVICEPOINTS && isAssigned) return;
|
if (HIDE_ASSIGNED_SERVICEPOINTS && isAssigned) return;
|
||||||
|
|
||||||
const opt = document.createElement("option");
|
const opt = document.createElement("option");
|
||||||
opt.value = sp.ServicePointID;
|
opt.value = sp.ID;
|
||||||
opt.textContent = String(sp.ServicePointID) + " - " + (sp.ServicePointName || "");
|
opt.textContent = String(sp.ID) + " - " + (sp.Name || "");
|
||||||
sel.appendChild(opt);
|
sel.appendChild(opt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>Beacons</h2>
|
<h2>Beacons</h2>
|
||||||
<div class="warn">Required: BeaconName</div>
|
<div class="warn">Required: Name</div>
|
||||||
<div class="ok" id="jsStatus">(JS not loaded yet)</div>
|
<div class="ok" id="jsStatus">(JS not loaded yet)</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -38,8 +38,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label>BeaconName (required)</label><br>
|
<label>Name (required)</label><br>
|
||||||
<input id="BeaconName" placeholder="Front Door" required>
|
<input id="Name" placeholder="Front Door" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -160,13 +160,13 @@ function escapeHtml(s){
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadIntoForm(b){
|
function loadIntoForm(b){
|
||||||
document.getElementById("BeaconID").value = b.BeaconID || "";
|
document.getElementById("BeaconID").value = b.ID || "";
|
||||||
document.getElementById("BeaconName").value = b.BeaconName || "";
|
document.getElementById("Name").value = b.Name || "";
|
||||||
document.getElementById("UUID").value = b.UUID || "";
|
document.getElementById("UUID").value = b.UUID || "";
|
||||||
document.getElementById("NamespaceId").value = b.NamespaceId || "";
|
document.getElementById("NamespaceId").value = b.NamespaceId || "";
|
||||||
document.getElementById("InstanceId").value = b.InstanceId || "";
|
document.getElementById("InstanceId").value = b.InstanceId || "";
|
||||||
document.getElementById("IsActive").value = ("" + (b.IsActive ?? 1));
|
document.getElementById("IsActive").value = ("" + (b.IsActive ?? 1));
|
||||||
document.getElementById("DelBeaconID").value = b.BeaconID || "";
|
document.getElementById("DelBeaconID").value = b.ID || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refresh() {
|
async function refresh() {
|
||||||
|
|
@ -180,8 +180,8 @@ async function refresh() {
|
||||||
for (const b of items) {
|
for (const b of items) {
|
||||||
const tr = document.createElement("tr");
|
const tr = document.createElement("tr");
|
||||||
tr.innerHTML = `
|
tr.innerHTML = `
|
||||||
<td>${b.BeaconID}</td>
|
<td>${b.ID}</td>
|
||||||
<td>${escapeHtml(b.BeaconName||"")}</td>
|
<td>${escapeHtml(b.Name||"")}</td>
|
||||||
<td>${escapeHtml(b.UUID||"")}</td>
|
<td>${escapeHtml(b.UUID||"")}</td>
|
||||||
<td>${escapeHtml(b.NamespaceId||"")}</td>
|
<td>${escapeHtml(b.NamespaceId||"")}</td>
|
||||||
<td>${escapeHtml(b.InstanceId||"")}</td>
|
<td>${escapeHtml(b.InstanceId||"")}</td>
|
||||||
|
|
@ -194,15 +194,15 @@ async function refresh() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveBeacon() {
|
async function saveBeacon() {
|
||||||
const name = (document.getElementById("BeaconName").value || "").trim();
|
const name = (document.getElementById("Name").value || "").trim();
|
||||||
if (!name) {
|
if (!name) {
|
||||||
show({ OK:false, ERROR:"missing_beacon_name", MESSAGE:"BeaconName is required" });
|
show({ OK:false, ERROR:"missing_beacon_name", MESSAGE:"Name is required" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
BeaconID: valIntOrNull("BeaconID"),
|
BeaconID: valIntOrNull("BeaconID"),
|
||||||
BeaconName: name,
|
Name: name,
|
||||||
UUID: (document.getElementById("UUID").value || "").trim(),
|
UUID: (document.getElementById("UUID").value || "").trim(),
|
||||||
NamespaceId: (document.getElementById("NamespaceId").value || "").trim(),
|
NamespaceId: (document.getElementById("NamespaceId").value || "").trim(),
|
||||||
InstanceId: (document.getElementById("InstanceId").value || "").trim(),
|
InstanceId: (document.getElementById("InstanceId").value || "").trim(),
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,16 @@
|
||||||
<cfparam name="users_to_email" default="">
|
<cfparam name="users_to_email" default="">
|
||||||
|
|
||||||
<cfquery name="select_users_to_email" datasource="#application.datasource#">
|
<cfquery name="select_users_to_email" datasource="#application.datasource#">
|
||||||
SELECT U.UserEmailAddress
|
SELECT U.EmailAddress
|
||||||
FROM Users U
|
FROM Users U
|
||||||
WHERE UserID in (0,1,2)
|
WHERE UserID in (0,1,2)
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfoutput query="select_users_to_email">
|
<cfoutput query="select_users_to_email">
|
||||||
|
|
||||||
#UserEmailAddress#,
|
#EmailAddress#,
|
||||||
|
|
||||||
<cfset users_to_email=listappend(users_to_email, #UserEmailAddress#)>
|
<cfset users_to_email=listappend(users_to_email, #EmailAddress#)>
|
||||||
|
|
||||||
</cfoutput><br><br>
|
</cfoutput><br><br>
|
||||||
|
|
||||||
|
|
@ -95,18 +95,18 @@
|
||||||
<cfloop index="the_email_address" list="#users_to_email#">
|
<cfloop index="the_email_address" list="#users_to_email#">
|
||||||
|
|
||||||
<cfquery name="get_user_email" datasource="#application.datasource#">
|
<cfquery name="get_user_email" datasource="#application.datasource#">
|
||||||
SELECT UserUUID
|
SELECT UUID
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE UserEmailAddress = '#the_email_address#'
|
WHERE EmailAddress = '#the_email_address#'
|
||||||
AND
|
AND
|
||||||
UserIsEmailverified = 1
|
UserIsEmailverified = 1
|
||||||
AND
|
AND
|
||||||
UserIsContactVerified > 0
|
IsContactVerified > 0
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfset form.this_email_body = form.email_body & "
|
<cfset form.this_email_body = form.email_body & "
|
||||||
|
|
||||||
instant unsubscribe link: https://www.payfrit.com/remove_me.cfm?UserUUID="&#get_user_email.UserUUID#>
|
instant unsubscribe link: https://www.payfrit.com/remove_me.cfm?UUID="&#get_user_email.UUID#>
|
||||||
|
|
||||||
<cfmail to="#the_email_address#" from="admin@payfrit.com" subject="#form.email_subject#" type="HTML">
|
<cfmail to="#the_email_address#" from="admin@payfrit.com" subject="#form.email_subject#" type="HTML">
|
||||||
#HTMLCodeFormat(form.this_email_body)#</cfmail>
|
#HTMLCodeFormat(form.this_email_body)#</cfmail>
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
<cfif form.mode eq "start">
|
<cfif form.mode eq "start">
|
||||||
|
|
||||||
<CFQUERY name="get_verified_users" datasource="#application.datasource#">
|
<CFQUERY name="get_verified_users" datasource="#application.datasource#">
|
||||||
SELECT U.UserID, U.UserEmailAddress, U.UserContactNumber,U.UserAddedOn
|
SELECT U.ID, U.EmailAddress, U.ContactNumber,U.AddedOn
|
||||||
FROM Users U
|
FROM Users U
|
||||||
WHERE U.UserIsEmailVerified = 1
|
WHERE U.IsEmailVerified = 1
|
||||||
AND
|
AND
|
||||||
U.UserIsCOntactVerified > 0
|
U.UserIsCOntactVerified > 0
|
||||||
AND
|
AND
|
||||||
U.UserID > 435
|
U.ID > 435
|
||||||
ORDER BY U.UserID DESC
|
ORDER BY U.ID DESC
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -48,16 +48,16 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>#UserEmailAddress#</td>
|
<td>#EmailAddress#</td>
|
||||||
<td>#UserContactNumber#</td>
|
<td>#ContactNumber#</td>
|
||||||
<td>#dateformat(UserAddedOn, "mmmm dd, YYYY")# at #timeformat(UserAddedOn, "hh:nn tt")#</td>
|
<td>#dateformat(AddedOn, "mmmm dd, YYYY")# at #timeformat(AddedOn, "hh:nn tt")#</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
<CFQUERY name="get_orders" datasource="#application.datasource#">
|
<CFQUERY name="get_orders" datasource="#application.datasource#">
|
||||||
SELECT O.OrderUUID
|
SELECT O.UUID
|
||||||
FROM Orders O
|
FROM Orders O
|
||||||
WHERE O.OrderUserID = #get_verified_users.UserID#
|
WHERE O.UserID = #get_verified_users.ID#
|
||||||
ORDER BY O.OrderID DESC
|
ORDER BY O.ID DESC
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfparam name="looper" default="">
|
<cfparam name="looper" default="">
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
<cfloop query="get_orders">
|
<cfloop query="get_orders">
|
||||||
<cfset looper=incrementvalue(looper)>
|
<cfset looper=incrementvalue(looper)>
|
||||||
<a href="https://payfr.it/show_order.cfm?OrderUUID=#get_orders.OrderUUID#&is_admin_view=1" target="_blank">#looper#</a>,
|
<a href="https://payfr.it/show_order.cfm?UUID=#get_orders.UUID#&is_admin_view=1" target="_blank">#looper#</a>,
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -79,10 +79,10 @@
|
||||||
<cfelseif form.mode eq "user_traffic">
|
<cfelseif form.mode eq "user_traffic">
|
||||||
|
|
||||||
<CFQUERY name="get_user_traffic" datasource="#application.datasource#">
|
<CFQUERY name="get_user_traffic" datasource="#application.datasource#">
|
||||||
SELECT V.VisitorTrackingPageMode, V.VisitorTrackingAddedOn
|
SELECT V.PageMode, V.AddedOn
|
||||||
FROM VisitorTracking V
|
FROM VisitorTrackings V
|
||||||
WHERE V.VisitorTrackingUserID = #form.chip#
|
WHERE V.UserID = #form.chip#
|
||||||
ORDER BY V.VisitorTrackingAddedOn DESC
|
ORDER BY V.AddedOn DESC
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
|
|
@ -92,8 +92,8 @@
|
||||||
</tr>
|
</tr>
|
||||||
<cfoutput query="get_user_traffic">
|
<cfoutput query="get_user_traffic">
|
||||||
<tr>
|
<tr>
|
||||||
<td>#VisitorTrackingPageMode#</td>
|
<td>#PageMode#</td>
|
||||||
<td>#VisitorTrackingAddedOn#</td>
|
<td>#AddedOn#</td>
|
||||||
</tr>
|
</tr>
|
||||||
</cfoutput>
|
</cfoutput>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>ServicePoints</h2>
|
<h2>ServicePoints</h2>
|
||||||
<div class="warn">Required: ServicePointName</div>
|
<div class="warn">Required: Name</div>
|
||||||
<div class="ok" id="jsStatus">(JS not loaded yet)</div>
|
<div class="ok" id="jsStatus">(JS not loaded yet)</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -38,18 +38,18 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label>ServicePointName (required)</label><br>
|
<label>Name (required)</label><br>
|
||||||
<input id="ServicePointName" placeholder="Front Counter" required>
|
<input id="Name" placeholder="Front Counter" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label>ServicePointTypeID</label><br>
|
<label>TypeID</label><br>
|
||||||
<input id="ServicePointTypeID" placeholder="0">
|
<input id="TypeID" placeholder="0">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label>ServicePointCode</label><br>
|
<label>Code</label><br>
|
||||||
<input id="ServicePointCode" placeholder="COUNTER">
|
<input id="Code" placeholder="COUNTER">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -160,14 +160,14 @@ function escapeHtml(s){
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadIntoForm(sp){
|
function loadIntoForm(sp){
|
||||||
document.getElementById("ServicePointID").value = sp.ServicePointID || "";
|
document.getElementById("ServicePointID").value = sp.ID || "";
|
||||||
document.getElementById("ServicePointName").value = sp.ServicePointName || "";
|
document.getElementById("Name").value = sp.Name || "";
|
||||||
document.getElementById("ServicePointTypeID").value = (sp.ServicePointTypeID ?? 0);
|
document.getElementById("TypeID").value = (sp.TypeID ?? 0);
|
||||||
document.getElementById("ServicePointCode").value = sp.ServicePointCode || "";
|
document.getElementById("Code").value = sp.Code || "";
|
||||||
document.getElementById("Description").value = sp.Description || "";
|
document.getElementById("Description").value = sp.Description || "";
|
||||||
document.getElementById("SortOrder").value = (sp.SortOrder ?? 0);
|
document.getElementById("SortOrder").value = (sp.SortOrder ?? 0);
|
||||||
document.getElementById("IsActive").value = ("" + (sp.IsActive ?? 1));
|
document.getElementById("IsActive").value = ("" + (sp.IsActive ?? 1));
|
||||||
document.getElementById("DelServicePointID").value = sp.ServicePointID || "";
|
document.getElementById("DelServicePointID").value = sp.ID || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refresh() {
|
async function refresh() {
|
||||||
|
|
@ -181,10 +181,10 @@ async function refresh() {
|
||||||
for (const sp of items) {
|
for (const sp of items) {
|
||||||
const tr = document.createElement("tr");
|
const tr = document.createElement("tr");
|
||||||
tr.innerHTML = `
|
tr.innerHTML = `
|
||||||
<td>${sp.ServicePointID}</td>
|
<td>${sp.ID}</td>
|
||||||
<td>${escapeHtml(sp.ServicePointName||"")}</td>
|
<td>${escapeHtml(sp.Name||"")}</td>
|
||||||
<td>${sp.ServicePointTypeID}</td>
|
<td>${sp.TypeID}</td>
|
||||||
<td>${escapeHtml(sp.ServicePointCode||"")}</td>
|
<td>${escapeHtml(sp.Code||"")}</td>
|
||||||
<td>${sp.SortOrder}</td>
|
<td>${sp.SortOrder}</td>
|
||||||
<td>${sp.IsActive}</td>
|
<td>${sp.IsActive}</td>
|
||||||
`;
|
`;
|
||||||
|
|
@ -195,17 +195,17 @@ async function refresh() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveSP() {
|
async function saveSP() {
|
||||||
const name = (document.getElementById("ServicePointName").value || "").trim();
|
const name = (document.getElementById("Name").value || "").trim();
|
||||||
if (!name) {
|
if (!name) {
|
||||||
show({ OK:false, ERROR:"missing_servicepoint_name", MESSAGE:"ServicePointName is required" });
|
show({ OK:false, ERROR:"missing_servicepoint_name", MESSAGE:"Name is required" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
ServicePointID: valIntOrNull("ServicePointID"),
|
ServicePointID: valIntOrNull("ServicePointID"),
|
||||||
ServicePointName: name,
|
Name: name,
|
||||||
ServicePointTypeID: valIntOrZero("ServicePointTypeID"),
|
TypeID: valIntOrZero("TypeID"),
|
||||||
ServicePointCode: (document.getElementById("ServicePointCode").value || "").trim(),
|
Code: (document.getElementById("Code").value || "").trim(),
|
||||||
Description: (document.getElementById("Description").value || "").trim(),
|
Description: (document.getElementById("Description").value || "").trim(),
|
||||||
SortOrder: valIntOrZero("SortOrder"),
|
SortOrder: valIntOrZero("SortOrder"),
|
||||||
IsActive: parseInt(document.getElementById("IsActive").value, 10)
|
IsActive: parseInt(document.getElementById("IsActive").value, 10)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
<cfsetting showdebugoutput="false">
|
<cfsetting showdebugoutput="false">
|
||||||
<cfsetting enablecfoutputonly="true">
|
<cfsetting enablecfoutputonly="true">
|
||||||
|
|
||||||
<!--- Performance timing: start clock as early as possible --->
|
|
||||||
<cfset request._perf_start = getTickCount()>
|
|
||||||
<cfset request._perf_queryCount = 0>
|
|
||||||
<cfset request._perf_queryTimeMs = 0>
|
|
||||||
|
|
||||||
<!---
|
<!---
|
||||||
Payfrit API Application.cfm (updated 2026-01-22)
|
Payfrit API Application.cfm (updated 2026-01-22)
|
||||||
|
|
||||||
|
|
@ -178,6 +173,11 @@ if (len(request._api_path)) {
|
||||||
|
|
||||||
// Worker app endpoints
|
// Worker app endpoints
|
||||||
if (findNoCase("/api/workers/myBusinesses.cfm", request._api_path)) request._api_isPublic = true;
|
if (findNoCase("/api/workers/myBusinesses.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
if (findNoCase("/api/workers/tierStatus.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
if (findNoCase("/api/workers/createAccount.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
if (findNoCase("/api/workers/onboardingLink.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
if (findNoCase("/api/workers/earlyUnlock.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
if (findNoCase("/api/workers/ledger.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
|
||||||
// Portal endpoints
|
// Portal endpoints
|
||||||
if (findNoCase("/api/portal/stats.cfm", request._api_path)) request._api_isPublic = true;
|
if (findNoCase("/api/portal/stats.cfm", request._api_path)) request._api_isPublic = true;
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Addresses
|
UPDATE Addresses
|
||||||
SET AddressIsDefaultDelivery = 0
|
SET AddressIsDefaultDelivery = 0
|
||||||
WHERE AddressUserID = :userId
|
WHERE UserID = :userId
|
||||||
AND (AddressBusinessID = 0 OR AddressBusinessID IS NULL)
|
AND (BusinessID = 0 OR BusinessID IS NULL)
|
||||||
AND AddressTypeID = :typeId
|
AND AddressTypeID = :typeId
|
||||||
", {
|
", {
|
||||||
userId: { value: userId, cfsqltype: "cf_sql_integer" },
|
userId: { value: userId, cfsqltype: "cf_sql_integer" },
|
||||||
|
|
@ -75,18 +75,18 @@ try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Addresses (
|
INSERT INTO Addresses (
|
||||||
AddressID,
|
AddressID,
|
||||||
AddressUserID,
|
UserID,
|
||||||
AddressBusinessID,
|
BusinessID,
|
||||||
AddressTypeID,
|
AddressTypeID,
|
||||||
AddressLabel,
|
AddressLabel,
|
||||||
AddressIsDefaultDelivery,
|
AddressIsDefaultDelivery,
|
||||||
AddressLine1,
|
Line1,
|
||||||
AddressLine2,
|
Line2,
|
||||||
AddressCity,
|
City,
|
||||||
AddressStateID,
|
StateID,
|
||||||
AddressZIPCode,
|
ZIPCode,
|
||||||
AddressIsDeleted,
|
IsDeleted,
|
||||||
AddressAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:addressId,
|
:addressId,
|
||||||
:userId,
|
:userId,
|
||||||
|
|
@ -117,7 +117,7 @@ try {
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Get state info for response
|
// Get state info for response
|
||||||
qState = queryExecute("SELECT tt_StateAbbreviation as StateAbbreviation, tt_StateName as StateName FROM tt_States WHERE tt_StateID = :stateId", {
|
qState = queryExecute("SELECT Abbreviation as StateAbbreviation, Name as StateName FROM tt_States WHERE ID = :stateId", {
|
||||||
stateId: { value: stateId, cfsqltype: "cf_sql_integer" }
|
stateId: { value: stateId, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,11 @@ if (addressId <= 0) {
|
||||||
try {
|
try {
|
||||||
// First, get the address details so we can find all matching duplicates
|
// First, get the address details so we can find all matching duplicates
|
||||||
qAddr = queryExecute("
|
qAddr = queryExecute("
|
||||||
SELECT AddressLine1, AddressLine2, AddressCity, AddressStateID, AddressZIPCode
|
SELECT Line1, Line2, City, StateID, ZIPCode
|
||||||
FROM Addresses
|
FROM Addresses
|
||||||
WHERE AddressID = :addressId
|
WHERE ID = :addressId
|
||||||
AND AddressUserID = :userId
|
AND UserID = :userId
|
||||||
AND AddressIsDeleted = 0
|
AND IsDeleted = 0
|
||||||
", {
|
", {
|
||||||
addressId: { value = addressId, cfsqltype = "cf_sql_integer" },
|
addressId: { value = addressId, cfsqltype = "cf_sql_integer" },
|
||||||
userId: { value = userId, cfsqltype = "cf_sql_integer" }
|
userId: { value = userId, cfsqltype = "cf_sql_integer" }
|
||||||
|
|
@ -93,21 +93,21 @@ try {
|
||||||
// Soft-delete ALL addresses that match the same Line1, Line2, City, StateID, ZIPCode
|
// Soft-delete ALL addresses that match the same Line1, Line2, City, StateID, ZIPCode
|
||||||
qDelete = queryExecute("
|
qDelete = queryExecute("
|
||||||
UPDATE Addresses
|
UPDATE Addresses
|
||||||
SET AddressIsDeleted = 1
|
SET IsDeleted = 1
|
||||||
WHERE AddressUserID = :userId
|
WHERE UserID = :userId
|
||||||
AND AddressLine1 = :line1
|
AND Line1 = :line1
|
||||||
AND AddressLine2 = :line2
|
AND Line2 = :line2
|
||||||
AND AddressCity = :city
|
AND City = :city
|
||||||
AND AddressStateID = :stateId
|
AND StateID = :stateId
|
||||||
AND AddressZIPCode = :zip
|
AND ZIPCode = :zip
|
||||||
AND AddressIsDeleted = 0
|
AND IsDeleted = 0
|
||||||
", {
|
", {
|
||||||
userId: { value = userId, cfsqltype = "cf_sql_integer" },
|
userId: { value = userId, cfsqltype = "cf_sql_integer" },
|
||||||
line1: { value = qAddr.AddressLine1, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressLine1) },
|
line1: { value = qAddr.Line1, cfsqltype = "cf_sql_varchar", null = !len(qAddr.Line1) },
|
||||||
line2: { value = qAddr.AddressLine2, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressLine2) },
|
line2: { value = qAddr.Line2, cfsqltype = "cf_sql_varchar", null = !len(qAddr.Line2) },
|
||||||
city: { value = qAddr.AddressCity, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressCity) },
|
city: { value = qAddr.City, cfsqltype = "cf_sql_varchar", null = !len(qAddr.City) },
|
||||||
stateId: { value = qAddr.AddressStateID, cfsqltype = "cf_sql_integer" },
|
stateId: { value = qAddr.StateID, cfsqltype = "cf_sql_integer" },
|
||||||
zip: { value = qAddr.AddressZIPCode, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressZIPCode) }
|
zip: { value = qAddr.ZIPCode, cfsqltype = "cf_sql_varchar", null = !len(qAddr.ZIPCode) }
|
||||||
});
|
});
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -49,22 +49,22 @@ try {
|
||||||
// Get user's delivery addresses
|
// Get user's delivery addresses
|
||||||
qAddresses = queryExecute("
|
qAddresses = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
a.AddressID,
|
a.ID,
|
||||||
a.AddressIsDefaultDelivery,
|
a.IsDefaultDelivery,
|
||||||
a.AddressLine1,
|
a.Line1,
|
||||||
a.AddressLine2,
|
a.Line2,
|
||||||
a.AddressCity,
|
a.City,
|
||||||
a.AddressStateID,
|
a.StateID,
|
||||||
s.tt_StateAbbreviation as StateAbbreviation,
|
s.Abbreviation as StateAbbreviation,
|
||||||
s.tt_StateName as StateName,
|
s.Name as StateName,
|
||||||
a.AddressZIPCode
|
a.ZIPCode
|
||||||
FROM Addresses a
|
FROM Addresses a
|
||||||
LEFT JOIN tt_States s ON a.AddressStateID = s.tt_StateID
|
LEFT JOIN tt_States s ON a.StateID = s.ID
|
||||||
WHERE a.AddressUserID = :userId
|
WHERE a.UserID = :userId
|
||||||
AND (a.AddressBusinessID = 0 OR a.AddressBusinessID IS NULL)
|
AND (a.BusinessID = 0 OR a.BusinessID IS NULL)
|
||||||
AND a.AddressTypeID = 2
|
AND a.AddressTypeID = 2
|
||||||
AND a.AddressIsDeleted = 0
|
AND a.IsDeleted = 0
|
||||||
ORDER BY a.AddressIsDefaultDelivery DESC, a.AddressID DESC
|
ORDER BY a.IsDefaultDelivery DESC, a.ID DESC
|
||||||
", {
|
", {
|
||||||
userId: { value = userId, cfsqltype = "cf_sql_integer" }
|
userId: { value = userId, cfsqltype = "cf_sql_integer" }
|
||||||
});
|
});
|
||||||
|
|
@ -72,15 +72,15 @@ try {
|
||||||
addresses = [];
|
addresses = [];
|
||||||
for (row in qAddresses) {
|
for (row in qAddresses) {
|
||||||
arrayAppend(addresses, {
|
arrayAppend(addresses, {
|
||||||
"AddressID": row.AddressID,
|
"AddressID": row.ID,
|
||||||
"IsDefault": row.AddressIsDefaultDelivery == 1,
|
"IsDefault": row.IsDefaultDelivery == 1,
|
||||||
"Line1": row.AddressLine1,
|
"Line1": row.Line1,
|
||||||
"Line2": row.AddressLine2 ?: "",
|
"Line2": row.Line2 ?: "",
|
||||||
"City": row.AddressCity,
|
"City": row.City,
|
||||||
"StateID": row.AddressStateID,
|
"StateID": row.StateID,
|
||||||
"StateAbbr": row.StateAbbreviation ?: "",
|
"StateAbbr": row.StateAbbreviation ?: "",
|
||||||
"ZIPCode": row.AddressZIPCode,
|
"ZIPCode": row.ZIPCode,
|
||||||
"DisplayText": row.AddressLine1 & (len(row.AddressLine2) ? ", " & row.AddressLine2 : "") & ", " & row.AddressCity & ", " & (row.StateAbbreviation ?: "") & " " & row.AddressZIPCode
|
"DisplayText": row.Line1 & (len(row.Line2) ? ", " & row.Line2 : "") & ", " & row.City & ", " & (row.StateAbbreviation ?: "") & " " & row.ZIPCode
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,11 @@ try {
|
||||||
|
|
||||||
// Verify address belongs to user
|
// Verify address belongs to user
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT AddressID
|
SELECT ID
|
||||||
FROM Addresses
|
FROM Addresses
|
||||||
WHERE AddressID = :addressId
|
WHERE ID = :addressId
|
||||||
AND AddressUserID = :userId
|
AND UserID = :userId
|
||||||
AND AddressIsDeleted = 0
|
AND IsDeleted = 0
|
||||||
", {
|
", {
|
||||||
addressId: { value: addressId, cfsqltype: "cf_sql_integer" },
|
addressId: { value: addressId, cfsqltype: "cf_sql_integer" },
|
||||||
userId: { value: userId, cfsqltype: "cf_sql_integer" }
|
userId: { value: userId, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -64,8 +64,8 @@ try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Addresses
|
UPDATE Addresses
|
||||||
SET AddressIsDefaultDelivery = 0
|
SET AddressIsDefaultDelivery = 0
|
||||||
WHERE AddressUserID = :userId
|
WHERE UserID = :userId
|
||||||
AND (AddressBusinessID = 0 OR AddressBusinessID IS NULL)
|
AND (BusinessID = 0 OR BusinessID IS NULL)
|
||||||
AND AddressTypeID LIKE '%2%'
|
AND AddressTypeID LIKE '%2%'
|
||||||
", {
|
", {
|
||||||
userId: { value: userId, cfsqltype: "cf_sql_integer" }
|
userId: { value: userId, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -75,7 +75,7 @@ try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Addresses
|
UPDATE Addresses
|
||||||
SET AddressIsDefaultDelivery = 1
|
SET AddressIsDefaultDelivery = 1
|
||||||
WHERE AddressID = :addressId
|
WHERE ID = :addressId
|
||||||
", {
|
", {
|
||||||
addressId: { value: addressId, cfsqltype: "cf_sql_integer" }
|
addressId: { value: addressId, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,13 @@
|
||||||
<cfsetting enablecfoutputonly="true">
|
<cfsetting enablecfoutputonly="true">
|
||||||
<cfcontent type="application/json; charset=utf-8">
|
<cfcontent type="application/json; charset=utf-8">
|
||||||
|
|
||||||
<!--- List US states for address forms (cached 24h - static data) --->
|
<!--- List US states for address forms --->
|
||||||
<cfscript>
|
<cfscript>
|
||||||
try {
|
try {
|
||||||
cached = appCacheGet("states", 86400);
|
|
||||||
if (!isNull(cached)) {
|
|
||||||
writeOutput(cached);
|
|
||||||
abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
qStates = queryExecute("
|
qStates = queryExecute("
|
||||||
SELECT tt_StateID as StateID, tt_StateAbbreviation as StateAbbreviation, tt_StateName as StateName
|
SELECT tt_StateID as StateID, Abbreviation as StateAbbreviation, Name as StateName
|
||||||
FROM tt_States
|
FROM tt_States
|
||||||
ORDER BY tt_StateName
|
ORDER BY Name
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
states = [];
|
states = [];
|
||||||
|
|
@ -26,12 +20,10 @@ try {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonResponse = serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"STATES": states
|
"STATES": states
|
||||||
});
|
}));
|
||||||
appCachePut("states", jsonResponse);
|
|
||||||
writeOutput(jsonResponse);
|
|
||||||
|
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,25 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Add TaskCategoryIsActive column to TaskCategories table
|
// Add IsActive column to TaskCategories table
|
||||||
try {
|
try {
|
||||||
// Check if column exists
|
// Check if column exists
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'TaskCategories'
|
AND TABLE_NAME = 'TaskCategories'
|
||||||
AND COLUMN_NAME = 'TaskCategoryIsActive'
|
AND COLUMN_NAME = 'IsActive'
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qCheck.recordCount == 0) {
|
if (qCheck.recordCount == 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE TaskCategories
|
ALTER TABLE TaskCategories
|
||||||
ADD COLUMN TaskCategoryIsActive TINYINT(1) NOT NULL DEFAULT 1
|
ADD COLUMN IsActive TINYINT(1) NOT NULL DEFAULT 1
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Column TaskCategoryIsActive added to TaskCategories"
|
"MESSAGE": "Column IsActive added to TaskCategories"
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
* Add Schedule Fields to Categories Table
|
* Add Schedule Fields to Categories Table
|
||||||
*
|
*
|
||||||
* Adds time-based scheduling fields:
|
* Adds time-based scheduling fields:
|
||||||
* - CategoryScheduleStart: TIME - Start time when category is available (e.g., 06:00:00 for breakfast)
|
* - ScheduleStart: TIME - Start time when category is available (e.g., 06:00:00 for breakfast)
|
||||||
* - CategoryScheduleEnd: TIME - End time when category stops being available (e.g., 11:00:00)
|
* - ScheduleEnd: TIME - End time when category stops being available (e.g., 11:00:00)
|
||||||
* - CategoryScheduleDays: VARCHAR(20) - Comma-separated list of day IDs (1=Sun, 2=Mon, etc.) or NULL for all days
|
* - ScheduleDays: VARCHAR(20) - Comma-separated list of day IDs (1=Sun, 2=Mon, etc.) or NULL for all days
|
||||||
*
|
*
|
||||||
* Run this once to migrate the schema.
|
* Run this once to migrate the schema.
|
||||||
*/
|
*/
|
||||||
|
|
@ -24,38 +24,38 @@ try {
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'Categories'
|
AND TABLE_NAME = 'Categories'
|
||||||
AND COLUMN_NAME IN ('CategoryScheduleStart', 'CategoryScheduleEnd', 'CategoryScheduleDays')
|
AND COLUMN_NAME IN ('ScheduleStart', 'ScheduleEnd', 'ScheduleDays')
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
existingCols = valueList(qCheck.COLUMN_NAME);
|
existingCols = valueList(qCheck.COLUMN_NAME);
|
||||||
|
|
||||||
added = [];
|
added = [];
|
||||||
|
|
||||||
// Add CategoryScheduleStart if not exists
|
// Add ScheduleStart if not exists
|
||||||
if (!listFindNoCase(existingCols, "CategoryScheduleStart")) {
|
if (!listFindNoCase(existingCols, "ScheduleStart")) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Categories
|
ALTER TABLE Categories
|
||||||
ADD COLUMN CategoryScheduleStart TIME NULL
|
ADD COLUMN ScheduleStart TIME NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(added, "CategoryScheduleStart");
|
arrayAppend(added, "ScheduleStart");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add CategoryScheduleEnd if not exists
|
// Add ScheduleEnd if not exists
|
||||||
if (!listFindNoCase(existingCols, "CategoryScheduleEnd")) {
|
if (!listFindNoCase(existingCols, "ScheduleEnd")) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Categories
|
ALTER TABLE Categories
|
||||||
ADD COLUMN CategoryScheduleEnd TIME NULL
|
ADD COLUMN ScheduleEnd TIME NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(added, "CategoryScheduleEnd");
|
arrayAppend(added, "ScheduleEnd");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add CategoryScheduleDays if not exists
|
// Add ScheduleDays if not exists
|
||||||
if (!listFindNoCase(existingCols, "CategoryScheduleDays")) {
|
if (!listFindNoCase(existingCols, "ScheduleDays")) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Categories
|
ALTER TABLE Categories
|
||||||
ADD COLUMN CategoryScheduleDays VARCHAR(20) NULL
|
ADD COLUMN ScheduleDays VARCHAR(20) NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(added, "CategoryScheduleDays");
|
arrayAppend(added, "ScheduleDays");
|
||||||
}
|
}
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ try {
|
||||||
|
|
||||||
// Find the Fountain Soda item we created
|
// Find the Fountain Soda item we created
|
||||||
qFountain = queryExecute("
|
qFountain = queryExecute("
|
||||||
SELECT ItemID, ItemName FROM Items
|
SELECT ID, Name FROM Items
|
||||||
WHERE ItemBusinessID = :bizId AND ItemName = 'Fountain Soda'
|
WHERE BusinessID = :bizId AND Name = 'Fountain Soda'
|
||||||
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qFountain.recordCount == 0) {
|
if (qFountain.recordCount == 0) {
|
||||||
|
|
@ -31,13 +31,13 @@ try {
|
||||||
// Update Fountain Soda to require child selection and be collapsible
|
// Update Fountain Soda to require child selection and be collapsible
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemRequiresChildSelection = 1, ItemIsCollapsible = 1
|
SET RequiresChildSelection = 1, IsCollapsible = 1
|
||||||
WHERE ItemID = :itemId
|
WHERE ItemID = :itemId
|
||||||
", { itemId: fountainId }, { datasource: "payfrit" });
|
", { itemId: fountainId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Check if modifiers already exist
|
// Check if modifiers already exist
|
||||||
qExisting = queryExecute("
|
qExisting = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Items WHERE ItemParentItemID = :parentId
|
SELECT COUNT(*) as cnt FROM Items WHERE ParentItemID = :parentId
|
||||||
", { parentId: fountainId }, { datasource: "payfrit" });
|
", { parentId: fountainId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qExisting.cnt > 0) {
|
if (qExisting.cnt > 0) {
|
||||||
|
|
@ -53,10 +53,10 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
|
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||||
ItemName, ItemDescription, ItemPrice, ItemIsActive,
|
Name, Description, Price, IsActive,
|
||||||
ItemSortOrder, ItemIsCollapsible, ItemRequiresChildSelection,
|
SortOrder, IsCollapsible, RequiresChildSelection,
|
||||||
ItemMaxNumSelectionReq, ItemAddedOn
|
MaxNumSelectionReq, AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:itemId, :bizId, 0, :parentId,
|
:itemId, :bizId, 0, :parentId,
|
||||||
'Size', 'Choose your size', 0, 1,
|
'Size', 'Choose your size', 0, 1,
|
||||||
|
|
@ -80,10 +80,10 @@ try {
|
||||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
qMaxItem = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
|
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||||
ItemName, ItemDescription, ItemPrice, ItemIsActive,
|
Name, Description, Price, IsActive,
|
||||||
ItemSortOrder, ItemIsCollapsible, ItemIsCheckedByDefault,
|
SortOrder, IsCollapsible, IsCheckedByDefault,
|
||||||
ItemAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:itemId, :bizId, 0, :parentId,
|
:itemId, :bizId, 0, :parentId,
|
||||||
:name, '', :price, 1,
|
:name, '', :price, 1,
|
||||||
|
|
@ -108,10 +108,10 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
|
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||||
ItemName, ItemDescription, ItemPrice, ItemIsActive,
|
Name, Description, Price, IsActive,
|
||||||
ItemSortOrder, ItemIsCollapsible, ItemRequiresChildSelection,
|
SortOrder, IsCollapsible, RequiresChildSelection,
|
||||||
ItemMaxNumSelectionReq, ItemAddedOn
|
MaxNumSelectionReq, AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:itemId, :bizId, 0, :parentId,
|
:itemId, :bizId, 0, :parentId,
|
||||||
'Flavor', 'Choose your drink', 0, 1,
|
'Flavor', 'Choose your drink', 0, 1,
|
||||||
|
|
@ -139,10 +139,10 @@ try {
|
||||||
qMaxItem = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
qMaxItem = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
|
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||||
ItemName, ItemDescription, ItemPrice, ItemIsActive,
|
Name, Description, Price, IsActive,
|
||||||
ItemSortOrder, ItemIsCollapsible, ItemIsCheckedByDefault,
|
SortOrder, IsCollapsible, IsCheckedByDefault,
|
||||||
ItemAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:itemId, :bizId, 0, :parentId,
|
:itemId, :bizId, 0, :parentId,
|
||||||
:name, '', 0, 1,
|
:name, '', 0, 1,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
/**
|
/**
|
||||||
* Add ItemCategoryID column to Items table
|
* Add CategoryID column to Items table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
response = { "OK": false };
|
response = { "OK": false };
|
||||||
|
|
@ -17,30 +17,30 @@ try {
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'Items'
|
AND TABLE_NAME = 'Items'
|
||||||
AND COLUMN_NAME = 'ItemCategoryID'
|
AND COLUMN_NAME = 'CategoryID'
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qCheck.recordCount > 0) {
|
if (qCheck.recordCount > 0) {
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
response["MESSAGE"] = "ItemCategoryID column already exists";
|
response["MESSAGE"] = "CategoryID column already exists";
|
||||||
} else {
|
} else {
|
||||||
// Add the column
|
// Add the column
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Items
|
ALTER TABLE Items
|
||||||
ADD COLUMN ItemCategoryID INT NULL DEFAULT 0 AFTER ItemParentItemID
|
ADD COLUMN CategoryID INT NULL DEFAULT 0 AFTER ParentItemID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Add index for performance
|
// Add index for performance
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE INDEX idx_items_categoryid ON Items(ItemCategoryID)
|
CREATE INDEX idx_items_categoryid ON Items(CategoryID)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
} catch (any indexErr) {
|
} catch (any indexErr) {
|
||||||
// Index might already exist
|
// Index might already exist
|
||||||
}
|
}
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
response["MESSAGE"] = "ItemCategoryID column added successfully";
|
response["MESSAGE"] = "CategoryID column added successfully";
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
try {
|
try {
|
||||||
// Check if columns already exist
|
// Check if columns already exist
|
||||||
checkCols = queryExecute(
|
checkCols = queryExecute(
|
||||||
"SHOW COLUMNS FROM Addresses LIKE 'AddressLat'",
|
"SHOW COLUMNS FROM Addresses LIKE 'Latitude'",
|
||||||
[],
|
[],
|
||||||
{ datasource = "payfrit" }
|
{ datasource = "payfrit" }
|
||||||
);
|
);
|
||||||
|
|
@ -15,8 +15,8 @@ try {
|
||||||
// Add the columns
|
// Add the columns
|
||||||
queryExecute(
|
queryExecute(
|
||||||
"ALTER TABLE Addresses
|
"ALTER TABLE Addresses
|
||||||
ADD COLUMN AddressLat DECIMAL(10,7) NULL,
|
ADD COLUMN Latitude DECIMAL(10,7) NULL,
|
||||||
ADD COLUMN AddressLng DECIMAL(10,7) NULL",
|
ADD COLUMN Longitude DECIMAL(10,7) NULL",
|
||||||
[],
|
[],
|
||||||
{ datasource = "payfrit" }
|
{ datasource = "payfrit" }
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,18 @@ try {
|
||||||
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'tt_TaskTypes'
|
AND TABLE_NAME = 'tt_TaskTypes'
|
||||||
AND COLUMN_NAME = 'tt_TaskTypeCategoryID'
|
AND COLUMN_NAME = 'TaskCategoryID'
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qCheck.recordCount == 0) {
|
if (qCheck.recordCount == 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE tt_TaskTypes
|
ALTER TABLE tt_TaskTypes
|
||||||
ADD COLUMN tt_TaskTypeCategoryID INT NULL
|
ADD COLUMN TaskCategoryID INT NULL
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Column tt_TaskTypeCategoryID added to tt_TaskTypes"
|
"MESSAGE": "Column TaskCategoryID added to tt_TaskTypes"
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Add TaskSourceType and TaskSourceID columns to Tasks table
|
// Add SourceType and SourceID columns to Tasks table
|
||||||
// These are needed for chat persistence feature
|
// These are needed for chat persistence feature
|
||||||
|
|
||||||
result = { "OK": true, "STEPS": [] };
|
result = { "OK": true, "STEPS": [] };
|
||||||
|
|
@ -15,30 +15,30 @@ try {
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'Tasks'
|
AND TABLE_NAME = 'Tasks'
|
||||||
AND COLUMN_NAME IN ('TaskSourceType', 'TaskSourceID')
|
AND COLUMN_NAME IN ('SourceType', 'SourceID')
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
existingCols = valueList(cols.COLUMN_NAME);
|
existingCols = valueList(cols.COLUMN_NAME);
|
||||||
arrayAppend(result.STEPS, "Existing columns: #existingCols#");
|
arrayAppend(result.STEPS, "Existing columns: #existingCols#");
|
||||||
|
|
||||||
// Add TaskSourceType if missing
|
// Add SourceType if missing
|
||||||
if (!listFindNoCase(existingCols, "TaskSourceType")) {
|
if (!listFindNoCase(existingCols, "SourceType")) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Tasks ADD COLUMN TaskSourceType VARCHAR(50) NULL
|
ALTER TABLE Tasks ADD COLUMN SourceType VARCHAR(50) NULL
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
arrayAppend(result.STEPS, "Added TaskSourceType column");
|
arrayAppend(result.STEPS, "Added SourceType column");
|
||||||
} else {
|
} else {
|
||||||
arrayAppend(result.STEPS, "TaskSourceType already exists");
|
arrayAppend(result.STEPS, "SourceType already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add TaskSourceID if missing
|
// Add SourceID if missing
|
||||||
if (!listFindNoCase(existingCols, "TaskSourceID")) {
|
if (!listFindNoCase(existingCols, "SourceID")) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Tasks ADD COLUMN TaskSourceID INT NULL
|
ALTER TABLE Tasks ADD COLUMN SourceID INT NULL
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
arrayAppend(result.STEPS, "Added TaskSourceID column");
|
arrayAppend(result.STEPS, "Added SourceID column");
|
||||||
} else {
|
} else {
|
||||||
arrayAppend(result.STEPS, "TaskSourceID already exists");
|
arrayAppend(result.STEPS, "SourceID already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify columns now exist
|
// Verify columns now exist
|
||||||
|
|
@ -47,7 +47,7 @@ try {
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'Tasks'
|
AND TABLE_NAME = 'Tasks'
|
||||||
AND COLUMN_NAME IN ('TaskSourceType', 'TaskSourceID')
|
AND COLUMN_NAME IN ('SourceType', 'SourceID')
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
result.COLUMNS = [];
|
result.COLUMNS = [];
|
||||||
|
|
|
||||||
|
|
@ -6,49 +6,49 @@
|
||||||
// Show all beacons with their current business/service point assignments
|
// Show all beacons with their current business/service point assignments
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
b.BeaconID,
|
b.ID,
|
||||||
b.BeaconUUID,
|
b.UUID,
|
||||||
b.BeaconName,
|
b.Name,
|
||||||
lt.BusinessID,
|
sp_link.BusinessID,
|
||||||
lt.ServicePointID,
|
sp_link.ID,
|
||||||
biz.BusinessName,
|
biz.Name,
|
||||||
sp.ServicePointName
|
sp.Name
|
||||||
FROM Beacons b
|
FROM Beacons b
|
||||||
LEFT JOIN lt_Beacon_Businesses_ServicePoints lt ON lt.BeaconID = b.BeaconID
|
LEFT JOIN ServicePoints sp_link ON sp_link.BeaconID = b.ID
|
||||||
LEFT JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
LEFT JOIN Businesses biz ON biz.ID = sp_link.BusinessID
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
LEFT JOIN ServicePoints sp ON sp.ID = sp_link.ID
|
||||||
WHERE b.BeaconIsActive = 1
|
WHERE b.IsActive = 1
|
||||||
ORDER BY b.BeaconID
|
ORDER BY b.ID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
for (row in q) {
|
for (row in q) {
|
||||||
arrayAppend(rows, {
|
arrayAppend(rows, {
|
||||||
"BeaconID": row.BeaconID,
|
"BeaconID": row.ID,
|
||||||
"BeaconUUID": row.BeaconUUID,
|
"UUID": row.UUID,
|
||||||
"BeaconName": row.BeaconName ?: "",
|
"Name": row.Name ?: "",
|
||||||
"BusinessID": row.BusinessID ?: 0,
|
"BusinessID": row.BusinessID ?: 0,
|
||||||
"BusinessName": row.BusinessName ?: "",
|
"Name": row.Name ?: "",
|
||||||
"ServicePointID": row.ServicePointID ?: 0,
|
"ServicePointID": row.ServicePointID ?: 0,
|
||||||
"ServicePointName": row.ServicePointName ?: ""
|
"Name": row.Name ?: ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also get service points for reference
|
// Also get service points for reference
|
||||||
spQuery = queryExecute("
|
spQuery = queryExecute("
|
||||||
SELECT sp.ServicePointID, sp.ServicePointName, sp.ServicePointBusinessID, b.BusinessName
|
SELECT sp.ID, sp.Name, sp.BusinessID, b.Name
|
||||||
FROM ServicePoints sp
|
FROM ServicePoints sp
|
||||||
JOIN Businesses b ON b.BusinessID = sp.ServicePointBusinessID
|
JOIN Businesses b ON b.ID = sp.BusinessID
|
||||||
ORDER BY sp.ServicePointBusinessID, sp.ServicePointID
|
ORDER BY sp.BusinessID, sp.ID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
servicePoints = [];
|
servicePoints = [];
|
||||||
for (sp in spQuery) {
|
for (sp in spQuery) {
|
||||||
arrayAppend(servicePoints, {
|
arrayAppend(servicePoints, {
|
||||||
"ServicePointID": sp.ServicePointID,
|
"ServicePointID": sp.ID,
|
||||||
"ServicePointName": sp.ServicePointName,
|
"Name": sp.Name,
|
||||||
"BusinessID": sp.ServicePointBusinessID,
|
"BusinessID": sp.BusinessID,
|
||||||
"BusinessName": sp.BusinessName
|
"Name": sp.Name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,16 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Check Big Dean's owner
|
// Check Big Dean's owner
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT b.BusinessID, b.BusinessName, b.BusinessUserID
|
SELECT b.ID, b.Name, b.UserID
|
||||||
FROM Businesses b
|
FROM Businesses b
|
||||||
WHERE b.BusinessID = 27
|
WHERE b.ID = 27
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Get users
|
// Get users
|
||||||
users = queryExecute("
|
users = queryExecute("
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM Users
|
FROM Users
|
||||||
ORDER BY UserID
|
ORDER BY ID
|
||||||
LIMIT 20
|
LIMIT 20
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
@ -23,9 +23,9 @@ colNames = users.getColumnNames();
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"BigDeans": {
|
"BigDeans": {
|
||||||
"BusinessID": q.BusinessID,
|
"BusinessID": q.ID,
|
||||||
"BusinessName": q.BusinessName,
|
"Name": q.Name,
|
||||||
"BusinessUserID": q.BusinessUserID
|
"UserID": q.UserID
|
||||||
},
|
},
|
||||||
"UserColumns": colNames,
|
"UserColumns": colNames,
|
||||||
"UserCount": users.recordCount
|
"UserCount": users.recordCount
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ if (!len(phone)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT UserID, UserFirstName, UserLastName, UserEmail, UserPhone, UserIsContactVerified
|
SELECT ID, FirstName, LastName, EmailAddress, ContactNumber, IsContactVerified
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE UserPhone = :phone OR UserEmail = :phone
|
WHERE ContactNumber = :phone OR EmailAddress = :phone
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
", { phone: phone }, { datasource: "payfrit" });
|
", { phone: phone }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
@ -25,11 +25,11 @@ if (q.recordCount EQ 0) {
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"UserID": q.UserID,
|
"UserID": q.ID,
|
||||||
"FirstName": q.UserFirstName,
|
"FirstName": q.FirstName,
|
||||||
"LastName": q.UserLastName,
|
"LastName": q.LastName,
|
||||||
"Email": q.UserEmail,
|
"Email": q.EmailAddress,
|
||||||
"Phone": q.UserPhone,
|
"Phone": q.ContactNumber,
|
||||||
"Verified": q.UserIsContactVerified
|
"Verified": q.IsContactVerified
|
||||||
}));
|
}));
|
||||||
</cfscript>
|
</cfscript>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
/**
|
/**
|
||||||
* Cleanup Lazy Daisy Beacons
|
* Cleanup Lazy Daisy Beacons
|
||||||
* - Removes duplicate beacons created by setupBeaconTables
|
* - Unassigns beacons 7, 8, 9 from service points
|
||||||
|
* - Deletes beacons 7, 8, 9
|
||||||
* - Updates original beacons with proper names
|
* - Updates original beacons with proper names
|
||||||
*/
|
*/
|
||||||
response = { "OK": false, "steps": [] };
|
response = { "OK": false, "steps": [] };
|
||||||
|
|
@ -13,52 +14,50 @@ response = { "OK": false, "steps": [] };
|
||||||
try {
|
try {
|
||||||
lazyDaisyID = 37;
|
lazyDaisyID = 37;
|
||||||
|
|
||||||
// Delete duplicate assignments for beacons 7, 8, 9
|
// Unassign beacons 7, 8, 9 from any service points
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM lt_Beacon_Businesses_ServicePoints
|
UPDATE ServicePoints
|
||||||
|
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||||
WHERE BeaconID IN (7, 8, 9) AND BusinessID = :bizId
|
WHERE BeaconID IN (7, 8, 9) AND BusinessID = :bizId
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted duplicate assignments for beacons 7, 8, 9");
|
response.steps.append("Unassigned beacons 7, 8, 9 from service points");
|
||||||
|
|
||||||
// Delete duplicate beacons 7, 8, 9
|
// Delete duplicate beacons 7, 8, 9
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Beacons
|
DELETE FROM Beacons
|
||||||
WHERE BeaconID IN (7, 8, 9) AND BeaconBusinessID = :bizId
|
WHERE ID IN (7, 8, 9) AND BusinessID = :bizId
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted duplicate beacons 7, 8, 9");
|
response.steps.append("Deleted duplicate beacons 7, 8, 9");
|
||||||
|
|
||||||
// Update original beacons with names based on their service point assignments
|
// Update original beacons with names based on their service point assignments
|
||||||
// Beacon 4 -> Table 1 (ServicePointID 4)
|
|
||||||
// Beacon 5 -> Table 2 (ServicePointID 5)
|
|
||||||
// Beacon 6 -> Table 3 (ServicePointID 6)
|
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Beacons SET BeaconName = 'Beacon - Table 1'
|
UPDATE Beacons SET Name = 'Beacon - Table 1'
|
||||||
WHERE BeaconID = 4 AND BeaconBusinessID = :bizId
|
WHERE ID = 4 AND BusinessID = :bizId
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Updated Beacon 4 name to 'Beacon - Table 1'");
|
response.steps.append("Updated Beacon 4 name to 'Beacon - Table 1'");
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Beacons SET BeaconName = 'Beacon - Table 2'
|
UPDATE Beacons SET Name = 'Beacon - Table 2'
|
||||||
WHERE BeaconID = 5 AND BeaconBusinessID = :bizId
|
WHERE ID = 5 AND BusinessID = :bizId
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Updated Beacon 5 name to 'Beacon - Table 2'");
|
response.steps.append("Updated Beacon 5 name to 'Beacon - Table 2'");
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Beacons SET BeaconName = 'Beacon - Table 3'
|
UPDATE Beacons SET Name = 'Beacon - Table 3'
|
||||||
WHERE BeaconID = 6 AND BeaconBusinessID = :bizId
|
WHERE ID = 6 AND BusinessID = :bizId
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Updated Beacon 6 name to 'Beacon - Table 3'");
|
response.steps.append("Updated Beacon 6 name to 'Beacon - Table 3'");
|
||||||
|
|
||||||
// Get final status
|
// Get final status
|
||||||
qFinal = queryExecute("
|
qFinal = queryExecute("
|
||||||
SELECT lt.BeaconID, b.BeaconUUID, b.BeaconName, lt.BusinessID, biz.BusinessName, lt.ServicePointID, sp.ServicePointName
|
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||||
JOIN Beacons b ON b.BeaconID = lt.BeaconID
|
biz.Name AS BusinessName
|
||||||
JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
FROM ServicePoints sp
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
WHERE lt.BusinessID = :bizId
|
JOIN Businesses biz ON biz.ID = sp.BusinessID
|
||||||
ORDER BY lt.BeaconID
|
WHERE sp.BusinessID = :bizId AND sp.BeaconID IS NOT NULL
|
||||||
|
ORDER BY sp.BeaconID
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
beacons = [];
|
beacons = [];
|
||||||
|
|
@ -66,8 +65,9 @@ try {
|
||||||
arrayAppend(beacons, {
|
arrayAppend(beacons, {
|
||||||
"BeaconID": qFinal.BeaconID[i],
|
"BeaconID": qFinal.BeaconID[i],
|
||||||
"BeaconName": qFinal.BeaconName[i],
|
"BeaconName": qFinal.BeaconName[i],
|
||||||
"UUID": qFinal.BeaconUUID[i],
|
"UUID": qFinal.UUID[i],
|
||||||
"BusinessName": qFinal.BusinessName[i],
|
"BusinessName": qFinal.BusinessName[i],
|
||||||
|
"ServicePointID": qFinal.ServicePointID[i],
|
||||||
"ServicePointName": qFinal.ServicePointName[i]
|
"ServicePointName": qFinal.ServicePointName[i]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
* Cleanup Categories - Final step after migration verification
|
* Cleanup Categories - Final step after migration verification
|
||||||
*
|
*
|
||||||
* This script:
|
* This script:
|
||||||
* 1. Verifies all Items have ItemBusinessID set
|
* 1. Verifies all Items have BusinessID set
|
||||||
* 2. Finds orphan items (ParentID=0, no children, not in links)
|
* 2. Finds orphan items (ParentID=0, no children, not in links)
|
||||||
* 3. Drops ItemCategoryID column
|
* 3. Drops CategoryID column
|
||||||
* 4. Drops ItemIsModifierTemplate column (derived from ItemTemplateLinks now)
|
* 4. Drops IsModifierTemplate column (derived from lt_ItemID_TemplateItemID now)
|
||||||
* 5. Drops Categories table
|
* 5. Drops Categories table
|
||||||
*
|
*
|
||||||
* Query param: ?confirm=YES to actually execute (otherwise shows verification only)
|
* Query param: ?confirm=YES to actually execute (otherwise shows verification only)
|
||||||
|
|
@ -30,7 +30,7 @@ try {
|
||||||
// Verification Step 1: Check for items without BusinessID
|
// Verification Step 1: Check for items without BusinessID
|
||||||
qNoBusinessID = queryExecute("
|
qNoBusinessID = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Items
|
SELECT COUNT(*) as cnt FROM Items
|
||||||
WHERE ItemBusinessID IS NULL OR ItemBusinessID = 0
|
WHERE BusinessID IS NULL OR BusinessID = 0
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.verification["itemsWithoutBusinessID"] = qNoBusinessID.cnt;
|
response.verification["itemsWithoutBusinessID"] = qNoBusinessID.cnt;
|
||||||
|
|
@ -46,38 +46,38 @@ try {
|
||||||
qCategoryItems = queryExecute("
|
qCategoryItems = queryExecute("
|
||||||
SELECT COUNT(DISTINCT p.ItemID) as cnt
|
SELECT COUNT(DISTINCT p.ItemID) as cnt
|
||||||
FROM Items p
|
FROM Items p
|
||||||
INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
|
INNER JOIN Items c ON c.ParentItemID = p.ItemID
|
||||||
WHERE p.ItemParentItemID = 0
|
WHERE p.ParentItemID = 0
|
||||||
AND p.ItemBusinessID > 0
|
AND p.BusinessID > 0
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
|
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ItemID
|
||||||
)
|
)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.verification["categoryItemsCreated"] = qCategoryItems.cnt;
|
response.verification["categoryItemsCreated"] = qCategoryItems.cnt;
|
||||||
|
|
||||||
// Verification Step 4: Check templates exist (in ItemTemplateLinks)
|
// Verification Step 4: Check templates exist (in lt_ItemID_TemplateItemID)
|
||||||
qTemplates = queryExecute("
|
qTemplates = queryExecute("
|
||||||
SELECT COUNT(DISTINCT tl.TemplateItemID) as cnt
|
SELECT COUNT(DISTINCT tl.TemplateItemID) as cnt
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
INNER JOIN Items t ON t.ItemID = tl.TemplateItemID
|
INNER JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.verification["templatesInLinks"] = qTemplates.cnt;
|
response.verification["templatesInLinks"] = qTemplates.cnt;
|
||||||
|
|
||||||
// Verification Step 5: Find orphans at ParentID=0
|
// Verification Step 5: Find orphans at ParentID=0
|
||||||
// Orphan = ParentID=0, no children pointing to it, not in ItemTemplateLinks
|
// Orphan = ParentID=0, no children pointing to it, not in lt_ItemID_TemplateItemID
|
||||||
qOrphans = queryExecute("
|
qOrphans = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName, i.ItemBusinessID
|
SELECT i.ID, i.Name, i.BusinessID
|
||||||
FROM Items i
|
FROM Items i
|
||||||
WHERE i.ItemParentItemID = 0
|
WHERE i.ParentItemID = 0
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM Items child WHERE child.ItemParentItemID = i.ItemID
|
SELECT 1 FROM Items child WHERE child.ParentItemID = i.ID
|
||||||
)
|
)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID
|
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = i.ID
|
||||||
)
|
)
|
||||||
ORDER BY i.ItemBusinessID, i.ItemName
|
ORDER BY i.BusinessID, i.Name
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.verification["orphanCount"] = qOrphans.recordCount;
|
response.verification["orphanCount"] = qOrphans.recordCount;
|
||||||
|
|
@ -85,8 +85,8 @@ try {
|
||||||
for (orphan in qOrphans) {
|
for (orphan in qOrphans) {
|
||||||
arrayAppend(response.orphans, {
|
arrayAppend(response.orphans, {
|
||||||
"ItemID": orphan.ItemID,
|
"ItemID": orphan.ItemID,
|
||||||
"ItemName": orphan.ItemName,
|
"Name": orphan.Name,
|
||||||
"BusinessID": orphan.ItemBusinessID
|
"BusinessID": orphan.BusinessID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ try {
|
||||||
|
|
||||||
if (!safeToCleanup) {
|
if (!safeToCleanup) {
|
||||||
arrayAppend(response.steps, "VERIFICATION FAILED - Cannot cleanup yet");
|
arrayAppend(response.steps, "VERIFICATION FAILED - Cannot cleanup yet");
|
||||||
arrayAppend(response.steps, "- " & qNoBusinessID.cnt & " items still missing ItemBusinessID");
|
arrayAppend(response.steps, "- " & qNoBusinessID.cnt & " items still missing BusinessID");
|
||||||
response["OK"] = false;
|
response["OK"] = false;
|
||||||
writeOutput(serializeJSON(response));
|
writeOutput(serializeJSON(response));
|
||||||
abort;
|
abort;
|
||||||
|
|
@ -119,31 +119,31 @@ try {
|
||||||
// Execute cleanup
|
// Execute cleanup
|
||||||
arrayAppend(response.steps, "Executing cleanup...");
|
arrayAppend(response.steps, "Executing cleanup...");
|
||||||
|
|
||||||
// Step 1: Drop ItemCategoryID column
|
// Step 1: Drop CategoryID column
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Items DROP COLUMN ItemCategoryID
|
ALTER TABLE Items DROP COLUMN CategoryID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(response.steps, "Dropped ItemCategoryID column from Items");
|
arrayAppend(response.steps, "Dropped CategoryID column from Items");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
if (findNoCase("check that column", e.message) || findNoCase("Unknown column", e.message)) {
|
if (findNoCase("check that column", e.message) || findNoCase("Unknown column", e.message)) {
|
||||||
arrayAppend(response.steps, "ItemCategoryID column already dropped");
|
arrayAppend(response.steps, "CategoryID column already dropped");
|
||||||
} else {
|
} else {
|
||||||
arrayAppend(response.steps, "Warning dropping ItemCategoryID: " & e.message);
|
arrayAppend(response.steps, "Warning dropping CategoryID: " & e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Drop ItemIsModifierTemplate column (now derived from ItemTemplateLinks)
|
// Step 2: Drop IsModifierTemplate column (now derived from lt_ItemID_TemplateItemID)
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Items DROP COLUMN ItemIsModifierTemplate
|
ALTER TABLE Items DROP COLUMN IsModifierTemplate
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(response.steps, "Dropped ItemIsModifierTemplate column from Items");
|
arrayAppend(response.steps, "Dropped IsModifierTemplate column from Items");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
if (findNoCase("check that column", e.message) || findNoCase("Unknown column", e.message)) {
|
if (findNoCase("check that column", e.message) || findNoCase("Unknown column", e.message)) {
|
||||||
arrayAppend(response.steps, "ItemIsModifierTemplate column already dropped");
|
arrayAppend(response.steps, "IsModifierTemplate column already dropped");
|
||||||
} else {
|
} else {
|
||||||
arrayAppend(response.steps, "Warning dropping ItemIsModifierTemplate: " & e.message);
|
arrayAppend(response.steps, "Warning dropping IsModifierTemplate: " & e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ if (businessId <= 0) {
|
||||||
try {
|
try {
|
||||||
// Find duplicate UserIDs for this business (keep the one with highest status or oldest)
|
// Find duplicate UserIDs for this business (keep the one with highest status or oldest)
|
||||||
qDupes = queryExecute("
|
qDupes = queryExecute("
|
||||||
SELECT UserID, COUNT(*) as cnt, MIN(EmployeeID) as keepId
|
SELECT ID, COUNT(*) as cnt, MIN(ID) as keepId
|
||||||
FROM lt_Users_Businesses_Employees
|
FROM Employees
|
||||||
WHERE BusinessID = ?
|
WHERE BusinessID = ?
|
||||||
GROUP BY UserID
|
GROUP BY UserID
|
||||||
HAVING COUNT(*) > 1
|
HAVING COUNT(*) > 1
|
||||||
|
|
@ -45,8 +45,8 @@ try {
|
||||||
for (row in qDupes) {
|
for (row in qDupes) {
|
||||||
// Delete all but the one we want to keep (the one with lowest EmployeeID)
|
// Delete all but the one we want to keep (the one with lowest EmployeeID)
|
||||||
qDel = queryExecute("
|
qDel = queryExecute("
|
||||||
DELETE FROM lt_Users_Businesses_Employees
|
DELETE FROM Employees
|
||||||
WHERE BusinessID = ? AND UserID = ? AND EmployeeID != ?
|
WHERE BusinessID = ? AND UserID = ? AND ID != ?
|
||||||
", [
|
", [
|
||||||
{ value: businessId, cfsqltype: "cf_sql_integer" },
|
{ value: businessId, cfsqltype: "cf_sql_integer" },
|
||||||
{ value: row.UserID, cfsqltype: "cf_sql_integer" },
|
{ value: row.UserID, cfsqltype: "cf_sql_integer" },
|
||||||
|
|
@ -57,19 +57,19 @@ try {
|
||||||
|
|
||||||
// Get remaining employees
|
// Get remaining employees
|
||||||
qRemaining = queryExecute("
|
qRemaining = queryExecute("
|
||||||
SELECT e.EmployeeID, e.UserID, u.UserFirstName, u.UserLastName
|
SELECT e.ID, e.UserID, u.FirstName, u.LastName
|
||||||
FROM lt_Users_Businesses_Employees e
|
FROM Employees e
|
||||||
JOIN Users u ON e.UserID = u.UserID
|
JOIN Users u ON e.UserID = u.ID
|
||||||
WHERE e.BusinessID = ?
|
WHERE e.BusinessID = ?
|
||||||
ORDER BY e.EmployeeID
|
ORDER BY e.ID
|
||||||
", [{ value: businessId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
", [{ value: businessId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
||||||
|
|
||||||
remaining = [];
|
remaining = [];
|
||||||
for (r in qRemaining) {
|
for (r in qRemaining) {
|
||||||
arrayAppend(remaining, {
|
arrayAppend(remaining, {
|
||||||
"EmployeeID": r.EmployeeID,
|
"EmployeeID": r.ID,
|
||||||
"UserID": r.UserID,
|
"UserID": r.UserID,
|
||||||
"Name": trim(r.UserFirstName & " " & r.UserLastName)
|
"Name": trim(r.FirstName & " " & r.LastName)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,106 +9,120 @@ try {
|
||||||
// Keep only Lazy Daisy (BusinessID 37)
|
// Keep only Lazy Daisy (BusinessID 37)
|
||||||
keepBusinessID = 37;
|
keepBusinessID = 37;
|
||||||
|
|
||||||
// First, reassign all beacons to Lazy Daisy
|
// Unassign all beacons from service points of other businesses
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE lt_Beacon_Businesses_ServicePoints
|
UPDATE ServicePoints
|
||||||
SET BusinessID = :keepID
|
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||||
|
WHERE BusinessID != :keepID AND BeaconID IS NOT NULL
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Reassigned all beacons to Lazy Daisy");
|
response.steps.append("Unassigned beacons from other businesses' service points");
|
||||||
|
|
||||||
// Get list of businesses to delete
|
// Get list of businesses to delete
|
||||||
qBiz = queryExecute("
|
qBiz = queryExecute("
|
||||||
SELECT BusinessID, BusinessName FROM Businesses WHERE BusinessID != :keepID
|
SELECT ID, Name FROM Businesses WHERE ID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
deletedBusinesses = [];
|
deletedBusinesses = [];
|
||||||
for (i = 1; i <= qBiz.recordCount; i++) {
|
for (i = 1; i <= qBiz.recordCount; i++) {
|
||||||
arrayAppend(deletedBusinesses, qBiz.BusinessName[i]);
|
arrayAppend(deletedBusinesses, qBiz.Name[i]);
|
||||||
}
|
}
|
||||||
response.steps.append("Found " & qBiz.recordCount & " businesses to delete");
|
response.steps.append("Found " & qBiz.recordCount & " businesses to delete");
|
||||||
|
|
||||||
// Delete related data first (foreign key constraints)
|
// Delete related data first (foreign key constraints)
|
||||||
// Delete ItemTemplateLinks for items from other businesses
|
// Delete lt_ItemID_TemplateItemID for items from other businesses
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE itl FROM ItemTemplateLinks itl
|
DELETE itl FROM lt_ItemID_TemplateItemID itl
|
||||||
JOIN Items i ON i.ItemID = itl.ItemID
|
JOIN Items i ON i.ID = itl.ItemID
|
||||||
WHERE i.ItemBusinessID != :keepID
|
WHERE i.BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted ItemTemplateLinks for other businesses");
|
response.steps.append("Deleted lt_ItemID_TemplateItemID for other businesses");
|
||||||
|
|
||||||
// Delete Items for other businesses
|
// Delete Items for other businesses
|
||||||
qItems = queryExecute("
|
qItems = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Items WHERE ItemBusinessID != :keepID
|
SELECT COUNT(*) as cnt FROM Items WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Items WHERE ItemBusinessID != :keepID
|
DELETE FROM Items WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted " & qItems.cnt & " items from other businesses");
|
response.steps.append("Deleted " & qItems.cnt & " items from other businesses");
|
||||||
|
|
||||||
// Delete Categories for other businesses
|
// Delete Categories for other businesses
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Categories WHERE CategoryBusinessID != :keepID
|
DELETE FROM Categories WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted categories from other businesses");
|
response.steps.append("Deleted categories from other businesses");
|
||||||
|
|
||||||
// Delete Hours for other businesses
|
// Delete Hours for other businesses
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Hours WHERE HoursBusinessID != :keepID
|
DELETE FROM Hours WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted hours from other businesses");
|
response.steps.append("Deleted hours from other businesses");
|
||||||
|
|
||||||
// Delete Employees for other businesses (skip if table doesn't exist)
|
// Delete Employees for other businesses
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Employees WHERE EmployeeBusinessID != :keepID
|
DELETE FROM Employees WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted employees from other businesses");
|
response.steps.append("Deleted employees from other businesses");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
response.steps.append("Skipped employees (table may not exist)");
|
response.steps.append("Skipped employees (table may not exist)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete ServicePoints for other businesses (skip if table doesn't exist)
|
// Delete ServicePoints for other businesses
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM ServicePoints WHERE ServicePointBusinessID != :keepID
|
DELETE FROM ServicePoints WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted service points from other businesses");
|
response.steps.append("Deleted service points from other businesses");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
response.steps.append("Skipped service points (table may not exist)");
|
response.steps.append("Skipped service points (table may not exist)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete Stations for other businesses (skip if table doesn't exist)
|
// Delete Stations for other businesses
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Stations WHERE StationBusinessID != :keepID
|
DELETE FROM Stations WHERE BusinessID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted stations from other businesses");
|
response.steps.append("Deleted stations from other businesses");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
response.steps.append("Skipped stations (table may not exist)");
|
response.steps.append("Skipped stations (table may not exist)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete beacon-business mappings for other businesses
|
||||||
|
try {
|
||||||
|
queryExecute("
|
||||||
|
DELETE FROM lt_BeaconsID_BusinessesID WHERE BusinessID != :keepID
|
||||||
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
|
response.steps.append("Deleted beacon mappings for other businesses");
|
||||||
|
} catch (any e) {
|
||||||
|
response.steps.append("Skipped beacon mappings (table may not exist)");
|
||||||
|
}
|
||||||
|
|
||||||
// Finally delete the businesses themselves
|
// Finally delete the businesses themselves
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Businesses WHERE BusinessID != :keepID
|
DELETE FROM Businesses WHERE ID != :keepID
|
||||||
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
", { keepID: keepBusinessID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Deleted " & arrayLen(deletedBusinesses) & " businesses");
|
response.steps.append("Deleted " & arrayLen(deletedBusinesses) & " businesses");
|
||||||
|
|
||||||
// Get beacon status
|
// Get beacon status
|
||||||
qBeacons = queryExecute("
|
qBeacons = queryExecute("
|
||||||
SELECT lt.BeaconID, b.BeaconUUID, lt.BusinessID, biz.BusinessName, lt.ServicePointID
|
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
b.UUID, biz.Name AS BusinessName, sp.Name AS ServicePointName
|
||||||
JOIN Beacons b ON b.BeaconID = lt.BeaconID
|
FROM ServicePoints sp
|
||||||
JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
|
JOIN Businesses biz ON biz.ID = sp.BusinessID
|
||||||
|
WHERE sp.BeaconID IS NOT NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
beacons = [];
|
beacons = [];
|
||||||
for (i = 1; i <= qBeacons.recordCount; i++) {
|
for (i = 1; i <= qBeacons.recordCount; i++) {
|
||||||
arrayAppend(beacons, {
|
arrayAppend(beacons, {
|
||||||
"BeaconID": qBeacons.BeaconID[i],
|
"BeaconID": qBeacons.BeaconID[i],
|
||||||
"UUID": qBeacons.BeaconUUID[i],
|
"UUID": qBeacons.UUID[i],
|
||||||
"BusinessID": qBeacons.BusinessID[i],
|
"BusinessID": qBeacons.BusinessID[i],
|
||||||
"BusinessName": qBeacons.BusinessName[i],
|
"BusinessName": qBeacons.BusinessName[i],
|
||||||
"ServicePointID": qBeacons.ServicePointID[i]
|
"ServicePointID": qBeacons.ServicePointID[i],
|
||||||
|
"ServicePointName": qBeacons.ServicePointName[i]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ param name="url.action" default="check"; // "check" or "deactivate"
|
||||||
|
|
||||||
// Check the item first
|
// Check the item first
|
||||||
qItem = queryExecute("
|
qItem = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemParentItemID, ItemIsActive, ItemIsCollapsible
|
SELECT ID, Name, ParentItemID, IsActive, IsCollapsible
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemID = :itemId
|
WHERE ID = :itemId
|
||||||
", { itemId: url.itemId });
|
", { itemId: url.itemId });
|
||||||
|
|
||||||
if (qItem.recordCount == 0) {
|
if (qItem.recordCount == 0) {
|
||||||
|
|
@ -19,25 +19,25 @@ if (qItem.recordCount == 0) {
|
||||||
|
|
||||||
// Get all children (direct only for display)
|
// Get all children (direct only for display)
|
||||||
qChildren = queryExecute("
|
qChildren = queryExecute("
|
||||||
SELECT ItemID, ItemName
|
SELECT ID, Name
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemParentItemID = :itemId
|
WHERE ParentItemID = :itemId
|
||||||
", { itemId: url.itemId });
|
", { itemId: url.itemId });
|
||||||
|
|
||||||
childList = [];
|
childList = [];
|
||||||
for (row in qChildren) {
|
for (row in qChildren) {
|
||||||
arrayAppend(childList, { "ItemID": row.ItemID, "ItemName": row.ItemName });
|
arrayAppend(childList, { "ItemID": row.ID, "Name": row.Name });
|
||||||
}
|
}
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"ACTION": url.action,
|
"ACTION": url.action,
|
||||||
"ITEM": {
|
"ITEM": {
|
||||||
"ItemID": qItem.ItemID,
|
"ItemID": qItem.ID,
|
||||||
"ItemName": qItem.ItemName,
|
"Name": qItem.Name,
|
||||||
"ItemParentItemID": qItem.ItemParentItemID,
|
"ParentItemID": qItem.ParentItemID,
|
||||||
"ItemIsActive": qItem.ItemIsActive,
|
"IsActive": qItem.IsActive,
|
||||||
"ItemIsCollapsible": qItem.ItemIsCollapsible
|
"IsCollapsible": qItem.IsCollapsible
|
||||||
},
|
},
|
||||||
"HAS_CHILDREN": qChildren.recordCount > 0,
|
"HAS_CHILDREN": qChildren.recordCount > 0,
|
||||||
"CHILD_COUNT": qChildren.recordCount,
|
"CHILD_COUNT": qChildren.recordCount,
|
||||||
|
|
@ -48,14 +48,14 @@ if (url.action == "deactivate") {
|
||||||
// Deactivate children first
|
// Deactivate children first
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemIsActive = 0
|
SET IsActive = 0
|
||||||
WHERE ItemParentItemID = :itemId
|
WHERE ParentItemID = :itemId
|
||||||
", { itemId: url.itemId });
|
", { itemId: url.itemId });
|
||||||
|
|
||||||
// Then deactivate the parent
|
// Then deactivate the parent
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemIsActive = 0
|
SET IsActive = 0
|
||||||
WHERE ItemID = :itemId
|
WHERE ItemID = :itemId
|
||||||
", { itemId: url.itemId });
|
", { itemId: url.itemId });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@
|
||||||
// Delete cart orders (status 0) to reset for testing
|
// Delete cart orders (status 0) to reset for testing
|
||||||
result = queryExecute("
|
result = queryExecute("
|
||||||
DELETE FROM OrderLineItems
|
DELETE FROM OrderLineItems
|
||||||
WHERE OrderLineItemOrderID IN (
|
WHERE OrderID IN (
|
||||||
SELECT OrderID FROM Orders WHERE OrderStatusID = 0
|
SELECT ID FROM Orders WHERE StatusID = 0
|
||||||
)
|
)
|
||||||
", {}, { datasource = "payfrit" });
|
", {}, { datasource = "payfrit" });
|
||||||
|
|
||||||
result2 = queryExecute("
|
result2 = queryExecute("
|
||||||
DELETE FROM Orders WHERE OrderStatusID = 0
|
DELETE FROM Orders WHERE StatusID = 0
|
||||||
", {}, { datasource = "payfrit" });
|
", {}, { datasource = "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -10,27 +10,27 @@ try {
|
||||||
businessIDs = [38, 39, 40, 41, 42];
|
businessIDs = [38, 39, 40, 41, 42];
|
||||||
|
|
||||||
for (bizID in businessIDs) {
|
for (bizID in businessIDs) {
|
||||||
// Delete ItemTemplateLinks for items belonging to this business
|
// Delete lt_ItemID_TemplateItemID for items belonging to this business
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE itl FROM ItemTemplateLinks itl
|
DELETE itl FROM lt_ItemID_TemplateItemID itl
|
||||||
INNER JOIN Items i ON i.ItemID = itl.ItemID
|
INNER JOIN Items i ON i.ID = itl.ItemID
|
||||||
WHERE i.ItemBusinessID = :bizID
|
WHERE i.BusinessID = :bizID
|
||||||
", { bizID: bizID }, { datasource: "payfrit" });
|
", { bizID: bizID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Delete Items
|
// Delete Items
|
||||||
queryExecute("DELETE FROM Items WHERE ItemBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
queryExecute("DELETE FROM Items WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Delete Categories
|
// Delete Categories
|
||||||
queryExecute("DELETE FROM Categories WHERE CategoryBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
queryExecute("DELETE FROM Categories WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Delete Hours
|
// Delete Hours
|
||||||
queryExecute("DELETE FROM Hours WHERE HoursBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
queryExecute("DELETE FROM Hours WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Delete Addresses linked to this business
|
// Delete Addresses linked to this business
|
||||||
queryExecute("DELETE FROM Addresses WHERE AddressBusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
queryExecute("DELETE FROM Addresses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Delete the Business itself
|
// Delete the Business itself
|
||||||
queryExecute("DELETE FROM Businesses WHERE BusinessID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
queryExecute("DELETE FROM Businesses WHERE ID = :bizID", { bizID: bizID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.steps.append("Deleted business " & bizID & " and all related data");
|
response.steps.append("Deleted business " & bizID & " and all related data");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@
|
||||||
try {
|
try {
|
||||||
result = queryExecute("
|
result = queryExecute("
|
||||||
UPDATE Tasks
|
UPDATE Tasks
|
||||||
SET TaskCompletedOn = NOW()
|
SET CompletedOn = NOW()
|
||||||
WHERE TaskTypeID = 2
|
WHERE TaskTypeID = 2
|
||||||
AND TaskCompletedOn IS NULL
|
AND CompletedOn IS NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
affected = result.recordCount ?: 0;
|
affected = result.recordCount ?: 0;
|
||||||
|
|
|
||||||
|
|
@ -15,24 +15,24 @@ try {
|
||||||
|
|
||||||
// First, check if Big Dean's has a Beverages/Drinks category
|
// First, check if Big Dean's has a Beverages/Drinks category
|
||||||
qExistingCat = queryExecute("
|
qExistingCat = queryExecute("
|
||||||
SELECT CategoryID, CategoryName FROM Categories
|
SELECT ID, Name FROM Categories
|
||||||
WHERE CategoryBusinessID = :bizId AND (CategoryName LIKE '%Drink%' OR CategoryName LIKE '%Beverage%')
|
WHERE BusinessID = :bizId AND (Name LIKE '%Drink%' OR Name LIKE '%Beverage%')
|
||||||
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qExistingCat.recordCount > 0) {
|
if (qExistingCat.recordCount > 0) {
|
||||||
drinksCategoryId = qExistingCat.CategoryID;
|
drinksCategoryId = qExistingCat.CategoryID;
|
||||||
response["CategoryNote"] = "Using existing category: " & qExistingCat.CategoryName;
|
response["CategoryNote"] = "Using existing category: " & qExistingCat.Name;
|
||||||
} else {
|
} else {
|
||||||
// Create a new Beverages category for Big Dean's
|
// Create a new Beverages category for Big Dean's
|
||||||
qMaxCat = queryExecute("SELECT COALESCE(MAX(CategoryID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" });
|
qMaxCat = queryExecute("SELECT COALESCE(MAX(CategoryID), 0) + 1 as nextId FROM Categories", {}, { datasource: "payfrit" });
|
||||||
drinksCategoryId = qMaxCat.nextId;
|
drinksCategoryId = qMaxCat.nextId;
|
||||||
|
|
||||||
qMaxSort = queryExecute("
|
qMaxSort = queryExecute("
|
||||||
SELECT COALESCE(MAX(CategorySortOrder), 0) + 1 as nextSort FROM Categories WHERE CategoryBusinessID = :bizId
|
SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort FROM Categories WHERE BusinessID = :bizId
|
||||||
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
", { bizId: bigDeansBusinessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Categories (CategoryID, CategoryBusinessID, CategoryParentCategoryID, CategoryName, CategorySortOrder, CategoryAddedOn)
|
INSERT INTO Categories (CategoryID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn)
|
||||||
VALUES (:catId, :bizId, 0, 'Beverages', :sortOrder, NOW())
|
VALUES (:catId, :bizId, 0, 'Beverages', :sortOrder, NOW())
|
||||||
", {
|
", {
|
||||||
catId: drinksCategoryId,
|
catId: drinksCategoryId,
|
||||||
|
|
@ -61,8 +61,8 @@ try {
|
||||||
for (drink in drinks) {
|
for (drink in drinks) {
|
||||||
// Check if item already exists
|
// Check if item already exists
|
||||||
qExists = queryExecute("
|
qExists = queryExecute("
|
||||||
SELECT ItemID FROM Items
|
SELECT ID FROM Items
|
||||||
WHERE ItemBusinessID = :bizId AND ItemName = :name AND ItemCategoryID = :catId
|
WHERE BusinessID = :bizId AND Name = :name AND CategoryID = :catId
|
||||||
", { bizId: bigDeansBusinessId, name: drink.name, catId: drinksCategoryId }, { datasource: "payfrit" });
|
", { bizId: bigDeansBusinessId, name: drink.name, catId: drinksCategoryId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qExists.recordCount == 0) {
|
if (qExists.recordCount == 0) {
|
||||||
|
|
@ -72,10 +72,10 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
|
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||||
ItemName, ItemDescription, ItemPrice, ItemIsActive,
|
Name, Description, Price, IsActive,
|
||||||
ItemSortOrder, ItemIsCollapsible, ItemRequiresChildSelection,
|
SortOrder, IsCollapsible, RequiresChildSelection,
|
||||||
ItemAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:itemId, :bizId, :catId, 0,
|
:itemId, :bizId, :catId, 0,
|
||||||
:name, :desc, :price, 1,
|
:name, :desc, :price, 1,
|
||||||
|
|
@ -103,10 +103,10 @@ try {
|
||||||
qMaxOpt = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
qMaxOpt = queryExecute("SELECT COALESCE(MAX(ItemID), 0) + 1 as nextId FROM Items", {}, { datasource: "payfrit" });
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemID, ItemBusinessID, ItemCategoryID, ItemParentItemID,
|
ItemID, BusinessID, CategoryID, ParentItemID,
|
||||||
ItemName, ItemDescription, ItemPrice, ItemIsActive,
|
Name, Description, Price, IsActive,
|
||||||
ItemSortOrder, ItemIsCollapsible, ItemIsCheckedByDefault,
|
SortOrder, IsCollapsible, IsCheckedByDefault,
|
||||||
ItemAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:itemId, :bizId, 0, :parentId,
|
:itemId, :bizId, 0, :parentId,
|
||||||
:name, '', 0, 1,
|
:name, '', 0, 1,
|
||||||
|
|
|
||||||
|
|
@ -20,69 +20,74 @@ try {
|
||||||
uuid = beaconUUIDs[i];
|
uuid = beaconUUIDs[i];
|
||||||
|
|
||||||
// Check if beacon exists
|
// Check if beacon exists
|
||||||
qB = queryExecute("SELECT BeaconID FROM Beacons WHERE BeaconUUID = :uuid", { uuid: uuid }, { datasource: "payfrit" });
|
qB = queryExecute("SELECT ID FROM Beacons WHERE UUID = :uuid", { uuid: uuid }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qB.recordCount == 0) {
|
if (qB.recordCount == 0) {
|
||||||
queryExecute("INSERT INTO Beacons (BeaconUUID, BeaconBusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" });
|
queryExecute("INSERT INTO Beacons (UUID, BusinessID) VALUES (:uuid, :bizID)", { uuid: uuid, bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
qNew = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
qNew = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||||
beaconID = qNew.id;
|
beaconID = qNew.id;
|
||||||
response.steps.append("Created beacon " & beaconID & " with UUID: " & uuid);
|
response.steps.append("Created beacon " & beaconID & " with UUID: " & uuid);
|
||||||
} else {
|
} else {
|
||||||
beaconID = qB.BeaconID;
|
beaconID = qB.ID;
|
||||||
response.steps.append("Beacon exists: " & beaconID & " with UUID: " & uuid);
|
response.steps.append("Beacon exists: " & beaconID & " with UUID: " & uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get service point Table 1
|
// Get service point Table 1
|
||||||
qSP = queryExecute("
|
qSP = queryExecute("
|
||||||
SELECT ServicePointID FROM ServicePoints
|
SELECT ID FROM ServicePoints
|
||||||
WHERE ServicePointBusinessID = :bizID AND ServicePointName = 'Table 1'
|
WHERE BusinessID = :bizID AND Name = 'Table 1'
|
||||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qSP.recordCount == 0) {
|
if (qSP.recordCount == 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ServicePoints (ServicePointBusinessID, ServicePointName, ServicePointTypeID)
|
INSERT INTO ServicePoints (BusinessID, Name)
|
||||||
VALUES (:bizID, 'Table 1', 1)
|
VALUES (:bizID, 'Table 1')
|
||||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||||
servicePointID = qSP.id;
|
servicePointID = qSP.id;
|
||||||
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
|
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
|
||||||
} else {
|
} else {
|
||||||
servicePointID = qSP.ServicePointID;
|
servicePointID = qSP.ID;
|
||||||
response.steps.append("Found service point 'Table 1' (ID: " & servicePointID & ")");
|
response.steps.append("Found service point 'Table 1' (ID: " & servicePointID & ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all beacons and map them
|
// Assign all beacons to the Table 1 service point
|
||||||
qBeacons = queryExecute("SELECT BeaconID, BeaconUUID FROM Beacons", {}, { datasource: "payfrit" });
|
qBeacons = queryExecute("SELECT ID, UUID FROM Beacons WHERE BusinessID = :bizID", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
for (i = 1; i <= qBeacons.recordCount; i++) {
|
for (i = 1; i <= qBeacons.recordCount; i++) {
|
||||||
beaconID = qBeacons.BeaconID[i];
|
beaconID = qBeacons.ID[i];
|
||||||
|
|
||||||
// Delete old mapping if exists
|
// Unassign this beacon from any existing service point
|
||||||
queryExecute("DELETE FROM lt_Beacon_Businesses_ServicePoints WHERE BeaconID = :beaconID", { beaconID: beaconID }, { datasource: "payfrit" });
|
|
||||||
|
|
||||||
// Create new mapping
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO lt_Beacon_Businesses_ServicePoints (BeaconID, BusinessID, ServicePointID)
|
UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL
|
||||||
VALUES (:beaconID, :bizID, :spID)
|
WHERE BeaconID = :beaconID
|
||||||
|
", { beaconID: beaconID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
// Assign beacon to Table 1 service point
|
||||||
|
queryExecute("
|
||||||
|
UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1
|
||||||
|
WHERE ID = :spID AND BusinessID = :bizID
|
||||||
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Mapped beacon " & beaconID & " to Lazy Daisy, Table 1");
|
response.steps.append("Assigned beacon " & beaconID & " to Table 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get final status
|
// Get final status
|
||||||
qFinal = queryExecute("
|
qFinal = queryExecute("
|
||||||
SELECT lt.BeaconID, b.BeaconUUID, lt.BusinessID, biz.BusinessName, lt.ServicePointID, sp.ServicePointName
|
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||||
JOIN Beacons b ON b.BeaconID = lt.BeaconID
|
biz.Name AS BusinessName
|
||||||
JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
FROM ServicePoints sp
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
|
JOIN Businesses biz ON biz.ID = sp.BusinessID
|
||||||
|
WHERE sp.BeaconID IS NOT NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
beacons = [];
|
beacons = [];
|
||||||
for (i = 1; i <= qFinal.recordCount; i++) {
|
for (i = 1; i <= qFinal.recordCount; i++) {
|
||||||
arrayAppend(beacons, {
|
arrayAppend(beacons, {
|
||||||
"BeaconID": qFinal.BeaconID[i],
|
"BeaconID": qFinal.BeaconID[i],
|
||||||
"UUID": qFinal.BeaconUUID[i],
|
"UUID": qFinal.UUID[i],
|
||||||
"BusinessID": qFinal.BusinessID[i],
|
"BusinessID": qFinal.BusinessID[i],
|
||||||
"BusinessName": qFinal.BusinessName[i],
|
"BusinessName": qFinal.BusinessName[i],
|
||||||
"ServicePointID": qFinal.ServicePointID[i],
|
"ServicePointID": qFinal.ServicePointID[i],
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ try {
|
||||||
// Create ChatMessages table
|
// Create ChatMessages table
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE TABLE IF NOT EXISTS ChatMessages (
|
CREATE TABLE IF NOT EXISTS ChatMessages (
|
||||||
MessageID INT AUTO_INCREMENT PRIMARY KEY,
|
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
TaskID INT NOT NULL,
|
TaskID INT NOT NULL,
|
||||||
SenderUserID INT NOT NULL,
|
SenderUserID INT NOT NULL,
|
||||||
SenderType ENUM('customer', 'worker') NOT NULL,
|
SenderType ENUM('customer', 'worker') NOT NULL,
|
||||||
MessageText TEXT NOT NULL,
|
MessageBody TEXT NOT NULL,
|
||||||
IsRead TINYINT(1) DEFAULT 0,
|
IsRead TINYINT(1) DEFAULT 0,
|
||||||
CreatedOn DATETIME DEFAULT NOW(),
|
CreatedOn DATETIME DEFAULT NOW(),
|
||||||
|
|
||||||
|
|
@ -21,13 +21,13 @@ try {
|
||||||
|
|
||||||
// Also add a "Chat" category if it doesn't exist for business 17
|
// Also add a "Chat" category if it doesn't exist for business 17
|
||||||
existing = queryExecute("
|
existing = queryExecute("
|
||||||
SELECT TaskCategoryID FROM TaskCategories
|
SELECT ID FROM TaskCategories
|
||||||
WHERE TaskCategoryBusinessID = 17 AND TaskCategoryName = 'Chat'
|
WHERE BusinessID = 17 AND Name = 'Chat'
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (existing.recordCount == 0) {
|
if (existing.recordCount == 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO TaskCategories (TaskCategoryBusinessID, TaskCategoryName, TaskCategoryColor)
|
INSERT INTO TaskCategories (BusinessID, Name, Color)
|
||||||
VALUES (17, 'Chat', '##2196F3')
|
VALUES (17, 'Chat', '##2196F3')
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,47 +32,47 @@ try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE TABLE Menus (
|
CREATE TABLE Menus (
|
||||||
MenuID INT AUTO_INCREMENT PRIMARY KEY,
|
MenuID INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
MenuBusinessID INT NOT NULL,
|
BusinessID INT NOT NULL,
|
||||||
MenuName VARCHAR(100) NOT NULL,
|
Name VARCHAR(100) NOT NULL,
|
||||||
MenuDescription VARCHAR(500) NULL,
|
Description VARCHAR(500) NULL,
|
||||||
MenuDaysActive INT NOT NULL DEFAULT 127,
|
DaysActive INT NOT NULL DEFAULT 127,
|
||||||
MenuStartTime TIME NULL,
|
StartTime TIME NULL,
|
||||||
MenuEndTime TIME NULL,
|
EndTime TIME NULL,
|
||||||
MenuSortOrder INT NOT NULL DEFAULT 0,
|
SortOrder INT NOT NULL DEFAULT 0,
|
||||||
MenuIsActive TINYINT NOT NULL DEFAULT 1,
|
IsActive TINYINT NOT NULL DEFAULT 1,
|
||||||
MenuAddedOn DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
AddedOn DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
INDEX idx_menus_business (MenuBusinessID),
|
INDEX idx_menus_business (BusinessID),
|
||||||
INDEX idx_menus_active (MenuBusinessID, MenuIsActive)
|
INDEX idx_menus_active (BusinessID, IsActive)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
response["MESSAGE"] = "Menus table created successfully";
|
response["MESSAGE"] = "Menus table created successfully";
|
||||||
response["SCHEMA"] = {
|
response["SCHEMA"] = {
|
||||||
"MenuDaysActive": "Bitmask: 1=Sun, 2=Mon, 4=Tue, 8=Wed, 16=Thu, 32=Fri, 64=Sat (127 = all days)"
|
"DaysActive": "Bitmask: 1=Sun, 2=Mon, 4=Tue, 8=Wed, 16=Thu, 32=Fri, 64=Sat (127 = all days)"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if CategoryMenuID column exists in Categories table
|
// Check if MenuID column exists in Categories table
|
||||||
qCatCol = queryExecute("
|
qCatCol = queryExecute("
|
||||||
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'Categories'
|
AND TABLE_NAME = 'Categories'
|
||||||
AND COLUMN_NAME = 'CategoryMenuID'
|
AND COLUMN_NAME = 'MenuID'
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qCatCol.recordCount == 0) {
|
if (qCatCol.recordCount == 0) {
|
||||||
// Add CategoryMenuID column to Categories table
|
// Add MenuID column to Categories table
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Categories
|
ALTER TABLE Categories
|
||||||
ADD COLUMN CategoryMenuID INT NULL DEFAULT NULL AFTER CategoryBusinessID,
|
ADD COLUMN MenuID INT NULL DEFAULT NULL AFTER BusinessID,
|
||||||
ADD INDEX idx_categories_menu (CategoryMenuID)
|
ADD INDEX idx_categories_menu (MenuID)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
response["CATEGORIES_UPDATED"] = true;
|
response["CATEGORIES_UPDATED"] = true;
|
||||||
response["CATEGORIES_MESSAGE"] = "Added CategoryMenuID column to Categories table";
|
response["CATEGORIES_MESSAGE"] = "Added MenuID column to Categories table";
|
||||||
} else {
|
} else {
|
||||||
response["CATEGORIES_UPDATED"] = false;
|
response["CATEGORIES_UPDATED"] = false;
|
||||||
response["CATEGORIES_MESSAGE"] = "CategoryMenuID column already exists";
|
response["CATEGORIES_MESSAGE"] = "MenuID column already exists";
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
*
|
*
|
||||||
* POST body:
|
* POST body:
|
||||||
* {
|
* {
|
||||||
* "BusinessName": "Century Casino",
|
* "Name": "Century Casino",
|
||||||
* "UserID": 1,
|
* "UserID": 1,
|
||||||
* "ChildBusinessIDs": [47, 48] // Optional: link existing businesses as children
|
* "ChildBusinessIDs": [47, 48] // Optional: link existing businesses as children
|
||||||
* }
|
* }
|
||||||
|
|
@ -36,13 +36,13 @@ response = { "OK": false };
|
||||||
try {
|
try {
|
||||||
data = readJsonBody();
|
data = readJsonBody();
|
||||||
|
|
||||||
BusinessName = structKeyExists(data, "BusinessName") ? trim(data.BusinessName) : "";
|
Name = structKeyExists(data, "Name") ? trim(data.Name) : "";
|
||||||
UserID = structKeyExists(data, "UserID") ? val(data.UserID) : 0;
|
UserID = structKeyExists(data, "UserID") ? val(data.UserID) : 0;
|
||||||
ChildBusinessIDs = structKeyExists(data, "ChildBusinessIDs") && isArray(data.ChildBusinessIDs) ? data.ChildBusinessIDs : [];
|
ChildBusinessIDs = structKeyExists(data, "ChildBusinessIDs") && isArray(data.ChildBusinessIDs) ? data.ChildBusinessIDs : [];
|
||||||
|
|
||||||
if (!len(BusinessName)) {
|
if (!len(Name)) {
|
||||||
response["ERROR"] = "missing_name";
|
response["ERROR"] = "missing_name";
|
||||||
response["MESSAGE"] = "BusinessName is required";
|
response["MESSAGE"] = "Name is required";
|
||||||
writeOutput(serializeJSON(response));
|
writeOutput(serializeJSON(response));
|
||||||
abort;
|
abort;
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ try {
|
||||||
|
|
||||||
// Create minimal address record (just a placeholder)
|
// Create minimal address record (just a placeholder)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Addresses (AddressLine1, AddressUserID, AddressTypeID, AddressAddedOn)
|
INSERT INTO Addresses (Line1, UserID, AddressTypeID, AddedOn)
|
||||||
VALUES ('Parent Business - No Physical Location', :userID, 2, NOW())
|
VALUES ('Parent Business - No Physical Location', :userID, 2, NOW())
|
||||||
", {
|
", {
|
||||||
userID: UserID
|
userID: UserID
|
||||||
|
|
@ -67,10 +67,10 @@ try {
|
||||||
|
|
||||||
// Create parent business (no menu, no hours, just a shell)
|
// Create parent business (no menu, no hours, just a shell)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Businesses (BusinessName, BusinessUserID, BusinessAddressID, BusinessParentBusinessID, BusinessDeliveryZipCodes, BusinessAddedOn)
|
INSERT INTO Businesses (Name, UserID, AddressID, ParentBusinessID, BusinessDeliveryZipCodes, AddedOn)
|
||||||
VALUES (:name, :userId, :addressId, NULL, '', NOW())
|
VALUES (:name, :userId, :addressId, NULL, '', NOW())
|
||||||
", {
|
", {
|
||||||
name: BusinessName,
|
name: Name,
|
||||||
userId: UserID,
|
userId: UserID,
|
||||||
addressId: addressId
|
addressId: addressId
|
||||||
}, { datasource = "payfrit" });
|
}, { datasource = "payfrit" });
|
||||||
|
|
@ -80,7 +80,7 @@ try {
|
||||||
|
|
||||||
// Link address back to business
|
// Link address back to business
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Addresses SET AddressBusinessID = :bizId WHERE AddressID = :addrId
|
UPDATE Addresses SET BusinessID = :bizId WHERE ID = :addrId
|
||||||
", {
|
", {
|
||||||
bizId: newBusinessID,
|
bizId: newBusinessID,
|
||||||
addrId: addressId
|
addrId: addressId
|
||||||
|
|
@ -92,7 +92,7 @@ try {
|
||||||
childID = val(childID);
|
childID = val(childID);
|
||||||
if (childID > 0) {
|
if (childID > 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Businesses SET BusinessParentBusinessID = :parentId WHERE BusinessID = :childId
|
UPDATE Businesses SET ParentBusinessID = :parentId WHERE ID = :childId
|
||||||
", {
|
", {
|
||||||
parentId: newBusinessID,
|
parentId: newBusinessID,
|
||||||
childId: childID
|
childId: childID
|
||||||
|
|
@ -103,7 +103,7 @@ try {
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
response["BusinessID"] = newBusinessID;
|
response["BusinessID"] = newBusinessID;
|
||||||
response["BusinessName"] = BusinessName;
|
response["Name"] = Name;
|
||||||
response["MESSAGE"] = "Parent business created";
|
response["MESSAGE"] = "Parent business created";
|
||||||
if (arrayLen(linkedChildren) > 0) {
|
if (arrayLen(linkedChildren) > 0) {
|
||||||
response["LinkedChildren"] = linkedChildren;
|
response["LinkedChildren"] = linkedChildren;
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,22 @@ bizId = 27;
|
||||||
deactivatedIds = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204, 11212, 11220, 11259];
|
deactivatedIds = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204, 11212, 11220, 11259];
|
||||||
|
|
||||||
qDeactivated = queryExecute("
|
qDeactivated = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName, i.ItemParentItemID, i.ItemIsActive, i.ItemIsCollapsible,
|
SELECT i.ID, i.Name, i.ParentItemID, i.IsActive, i.IsCollapsible,
|
||||||
(SELECT COUNT(*) FROM Items c WHERE c.ItemParentItemID = i.ItemID) as ChildCount,
|
(SELECT COUNT(*) FROM Items c WHERE c.ParentItemID = i.ID) as ChildCount,
|
||||||
(SELECT GROUP_CONCAT(c.ItemName) FROM Items c WHERE c.ItemParentItemID = i.ItemID) as Children
|
(SELECT GROUP_CONCAT(c.Name) FROM Items c WHERE c.ParentItemID = i.ID) as Children
|
||||||
FROM Items i
|
FROM Items i
|
||||||
WHERE i.ItemID IN (:ids)
|
WHERE i.ID IN (:ids)
|
||||||
ORDER BY i.ItemID
|
ORDER BY i.ID
|
||||||
", { ids: { value: arrayToList(deactivatedIds), list: true } }, { datasource: "payfrit" });
|
", { ids: { value: arrayToList(deactivatedIds), list: true } }, { datasource: "payfrit" });
|
||||||
|
|
||||||
items = [];
|
items = [];
|
||||||
for (row in qDeactivated) {
|
for (row in qDeactivated) {
|
||||||
arrayAppend(items, {
|
arrayAppend(items, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"ParentID": row.ItemParentItemID,
|
"ParentID": row.ParentItemID,
|
||||||
"IsActive": row.ItemIsActive,
|
"IsActive": row.IsActive,
|
||||||
"IsCollapsible": row.ItemIsCollapsible,
|
"IsCollapsible": row.IsCollapsible,
|
||||||
"ChildCount": row.ChildCount,
|
"ChildCount": row.ChildCount,
|
||||||
"Children": row.Children
|
"Children": row.Children
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,24 @@ bizId = 27;
|
||||||
qLinks = queryExecute("
|
qLinks = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
tl.ItemID as MenuItemID,
|
tl.ItemID as MenuItemID,
|
||||||
mi.ItemName as MenuItemName,
|
mi.Name as MenuName,
|
||||||
mi.ItemParentItemID,
|
mi.ParentItemID,
|
||||||
tl.TemplateItemID,
|
tl.TemplateItemID,
|
||||||
t.ItemName as TemplateName,
|
t.Name as TemplateName,
|
||||||
tl.SortOrder
|
tl.SortOrder
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
JOIN Items mi ON mi.ItemID = tl.ItemID
|
JOIN Items mi ON mi.ID = tl.ItemID
|
||||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
WHERE mi.ItemBusinessID = :bizId
|
WHERE mi.BusinessID = :bizId
|
||||||
ORDER BY mi.ItemParentItemID, mi.ItemName, tl.SortOrder
|
ORDER BY mi.ParentItemID, mi.Name, tl.SortOrder
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
links = [];
|
links = [];
|
||||||
for (row in qLinks) {
|
for (row in qLinks) {
|
||||||
arrayAppend(links, {
|
arrayAppend(links, {
|
||||||
"MenuItemID": row.MenuItemID,
|
"MenuItemID": row.MenuItemID,
|
||||||
"MenuItemName": row.MenuItemName,
|
"MenuName": row.MenuName,
|
||||||
"ParentItemID": row.ItemParentItemID,
|
"ParentItemID": row.ParentItemID,
|
||||||
"TemplateItemID": row.TemplateItemID,
|
"TemplateItemID": row.TemplateItemID,
|
||||||
"TemplateName": row.TemplateName
|
"TemplateName": row.TemplateName
|
||||||
});
|
});
|
||||||
|
|
@ -34,20 +34,20 @@ for (row in qLinks) {
|
||||||
|
|
||||||
// Get burgers specifically (parent = 11271)
|
// Get burgers specifically (parent = 11271)
|
||||||
qBurgers = queryExecute("
|
qBurgers = queryExecute("
|
||||||
SELECT ItemID, ItemName FROM Items
|
SELECT ID, Name FROM Items
|
||||||
WHERE ItemBusinessID = :bizId AND ItemParentItemID = 11271 AND ItemIsActive = 1
|
WHERE BusinessID = :bizId AND ParentItemID = 11271 AND IsActive = 1
|
||||||
ORDER BY ItemSortOrder
|
ORDER BY SortOrder
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
burgers = [];
|
burgers = [];
|
||||||
for (row in qBurgers) {
|
for (row in qBurgers) {
|
||||||
// Get templates for this burger
|
// Get templates for this burger
|
||||||
qBurgerTemplates = queryExecute("
|
qBurgerTemplates = queryExecute("
|
||||||
SELECT tl.TemplateItemID, t.ItemName as TemplateName
|
SELECT tl.TemplateItemID, t.Name as TemplateName
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
WHERE tl.ItemID = :itemId
|
WHERE tl.ItemID = :itemId
|
||||||
", { itemId: row.ItemID }, { datasource: "payfrit" });
|
", { itemId: row.ID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
templates = [];
|
templates = [];
|
||||||
for (t in qBurgerTemplates) {
|
for (t in qBurgerTemplates) {
|
||||||
|
|
@ -55,8 +55,8 @@ for (row in qBurgers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
arrayAppend(burgers, {
|
arrayAppend(burgers, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"Templates": templates
|
"Templates": templates
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,38 +9,38 @@ businessID = 27;
|
||||||
qCategories = queryExecute("
|
qCategories = queryExecute("
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
p.ItemID as CategoryID,
|
p.ItemID as CategoryID,
|
||||||
p.ItemName as CategoryName,
|
p.Name as Name,
|
||||||
p.ItemSortOrder
|
p.SortOrder
|
||||||
FROM Items p
|
FROM Items p
|
||||||
INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
|
INNER JOIN Items c ON c.ParentItemID = p.ItemID
|
||||||
WHERE p.ItemBusinessID = :businessID
|
WHERE p.BusinessID = :businessID
|
||||||
AND p.ItemParentItemID = 0
|
AND p.ParentItemID = 0
|
||||||
AND p.ItemIsActive = 1
|
AND p.IsActive = 1
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
|
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ItemID
|
||||||
)
|
)
|
||||||
ORDER BY p.ItemSortOrder, p.ItemName
|
ORDER BY p.SortOrder, p.Name
|
||||||
", { businessID: businessID });
|
", { businessID: businessID });
|
||||||
|
|
||||||
cats = [];
|
cats = [];
|
||||||
for (c in qCategories) {
|
for (c in qCategories) {
|
||||||
arrayAppend(cats, {
|
arrayAppend(cats, {
|
||||||
"CategoryID": c.CategoryID,
|
"CategoryID": c.ID,
|
||||||
"CategoryName": c.CategoryName
|
"Name": c.Name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check raw counts
|
// Also check raw counts
|
||||||
rawCount = queryExecute("
|
rawCount = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Items
|
SELECT COUNT(*) as cnt FROM Items
|
||||||
WHERE ItemBusinessID = :bizId AND ItemParentItemID = 0 AND ItemIsActive = 1
|
WHERE BusinessID = :bizId AND ParentItemID = 0 AND IsActive = 1
|
||||||
", { bizId: businessID });
|
", { bizId: businessID });
|
||||||
|
|
||||||
childrenCount = queryExecute("
|
childrenCount = queryExecute("
|
||||||
SELECT COUNT(DISTINCT c.ItemParentItemID) as cnt
|
SELECT COUNT(DISTINCT c.ParentItemID) as cnt
|
||||||
FROM Items c
|
FROM Items c
|
||||||
INNER JOIN Items p ON p.ItemID = c.ItemParentItemID
|
INNER JOIN Items p ON p.ItemID = c.ParentItemID
|
||||||
WHERE p.ItemBusinessID = :bizId AND p.ItemParentItemID = 0
|
WHERE p.BusinessID = :bizId AND p.ParentItemID = 0
|
||||||
", { bizId: businessID });
|
", { bizId: businessID });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,24 @@ bizId = 27;
|
||||||
qLinks = queryExecute("
|
qLinks = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
tl.ItemID as MenuItemID,
|
tl.ItemID as MenuItemID,
|
||||||
mi.ItemName as MenuItemName,
|
mi.Name as MenuName,
|
||||||
mi.ItemParentItemID as MenuItemParentID,
|
mi.ParentItemID as MenuItemParentID,
|
||||||
tl.TemplateItemID,
|
tl.TemplateItemID,
|
||||||
t.ItemName as TemplateName,
|
t.Name as TemplateName,
|
||||||
t.ItemIsActive as TemplateActive,
|
t.IsActive as TemplateActive,
|
||||||
tl.SortOrder
|
tl.SortOrder
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
JOIN Items mi ON mi.ItemID = tl.ItemID
|
JOIN Items mi ON mi.ID = tl.ItemID
|
||||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
WHERE mi.ItemBusinessID = :bizId
|
WHERE mi.BusinessID = :bizId
|
||||||
ORDER BY mi.ItemName, tl.SortOrder
|
ORDER BY mi.Name, tl.SortOrder
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
links = [];
|
links = [];
|
||||||
for (row in qLinks) {
|
for (row in qLinks) {
|
||||||
arrayAppend(links, {
|
arrayAppend(links, {
|
||||||
"MenuItemID": row.MenuItemID,
|
"MenuItemID": row.MenuItemID,
|
||||||
"MenuItemName": row.MenuItemName,
|
"MenuName": row.MenuName,
|
||||||
"MenuItemParentID": row.MenuItemParentID,
|
"MenuItemParentID": row.MenuItemParentID,
|
||||||
"TemplateItemID": row.TemplateItemID,
|
"TemplateItemID": row.TemplateItemID,
|
||||||
"TemplateName": row.TemplateName,
|
"TemplateName": row.TemplateName,
|
||||||
|
|
@ -37,20 +37,20 @@ for (row in qLinks) {
|
||||||
|
|
||||||
// Get all templates that exist for this business
|
// Get all templates that exist for this business
|
||||||
qTemplates = queryExecute("
|
qTemplates = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemIsActive, ItemParentItemID
|
SELECT ID, Name, IsActive, ParentItemID
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID = :bizId
|
WHERE BusinessID = :bizId
|
||||||
AND ItemIsCollapsible = 1
|
AND IsCollapsible = 1
|
||||||
ORDER BY ItemName
|
ORDER BY Name
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
templates = [];
|
templates = [];
|
||||||
for (row in qTemplates) {
|
for (row in qTemplates) {
|
||||||
arrayAppend(templates, {
|
arrayAppend(templates, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"IsActive": row.ItemIsActive,
|
"IsActive": row.IsActive,
|
||||||
"ParentID": row.ItemParentItemID
|
"ParentID": row.ParentItemID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,67 +5,67 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
bizId = 27;
|
bizId = 27;
|
||||||
|
|
||||||
// Check the template items themselves (IDs from ItemTemplateLinks)
|
// Check the template items themselves (IDs from lt_ItemID_TemplateItemID)
|
||||||
templateIds = "11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227";
|
templateIds = "11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227";
|
||||||
|
|
||||||
qTemplates = queryExecute("
|
qTemplates = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemIsCollapsible, ItemIsActive, ItemParentItemID, ItemBusinessID
|
SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemID IN (#templateIds#)
|
WHERE ID IN (#templateIds#)
|
||||||
ORDER BY ItemName
|
ORDER BY Name
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
templates = [];
|
templates = [];
|
||||||
for (row in qTemplates) {
|
for (row in qTemplates) {
|
||||||
arrayAppend(templates, {
|
arrayAppend(templates, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"IsCollapsible": row.ItemIsCollapsible,
|
"IsCollapsible": row.IsCollapsible,
|
||||||
"IsActive": row.ItemIsActive,
|
"IsActive": row.IsActive,
|
||||||
"ParentID": row.ItemParentItemID,
|
"ParentID": row.ParentItemID,
|
||||||
"BusinessID": row.ItemBusinessID
|
"BusinessID": row.BusinessID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check what other templates might exist for burgers
|
// Also check what other templates might exist for burgers
|
||||||
// Look for items that are in ItemTemplateLinks but NOT linked to burgers
|
// Look for items that are in lt_ItemID_TemplateItemID but NOT linked to burgers
|
||||||
qMissingTemplates = queryExecute("
|
qMissingTemplates = queryExecute("
|
||||||
SELECT DISTINCT t.ItemID, t.ItemName, t.ItemIsCollapsible, t.ItemIsActive
|
SELECT DISTINCT t.ItemID, t.Name, t.IsCollapsible, t.IsActive
|
||||||
FROM Items t
|
FROM Items t
|
||||||
WHERE t.ItemBusinessID = :bizId
|
WHERE t.BusinessID = :bizId
|
||||||
AND t.ItemParentItemID = 0
|
AND t.ParentItemID = 0
|
||||||
AND t.ItemID NOT IN (
|
AND t.ItemID NOT IN (
|
||||||
SELECT i.ItemID FROM Items i WHERE i.ItemBusinessID = :bizId AND i.ItemCategoryID > 0
|
SELECT i.ID FROM Items i WHERE i.BusinessID = :bizId AND i.CategoryID > 0
|
||||||
)
|
)
|
||||||
AND EXISTS (SELECT 1 FROM Items child WHERE child.ItemParentItemID = t.ItemID)
|
AND EXISTS (SELECT 1 FROM Items child WHERE child.ParentItemID = t.ItemID)
|
||||||
ORDER BY t.ItemName
|
ORDER BY t.Name
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
potentialTemplates = [];
|
potentialTemplates = [];
|
||||||
for (row in qMissingTemplates) {
|
for (row in qMissingTemplates) {
|
||||||
arrayAppend(potentialTemplates, {
|
arrayAppend(potentialTemplates, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"IsCollapsible": row.ItemIsCollapsible,
|
"IsCollapsible": row.IsCollapsible,
|
||||||
"IsActive": row.ItemIsActive
|
"IsActive": row.IsActive
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// What templates SHOULD burgers have? Let's see all templates used by ANY item
|
// What templates SHOULD burgers have? Let's see all templates used by ANY item
|
||||||
qAllTemplateUsage = queryExecute("
|
qAllTemplateUsage = queryExecute("
|
||||||
SELECT t.ItemID, t.ItemName, COUNT(tl.ItemID) as UsageCount
|
SELECT t.ItemID, t.Name, COUNT(tl.ItemID) as UsageCount
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
JOIN Items mi ON mi.ItemID = tl.ItemID AND mi.ItemBusinessID = :bizId
|
JOIN Items mi ON mi.ID = tl.ItemID AND mi.BusinessID = :bizId
|
||||||
GROUP BY t.ItemID, t.ItemName
|
GROUP BY t.ItemID, t.Name
|
||||||
ORDER BY t.ItemName
|
ORDER BY t.Name
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
allTemplates = [];
|
allTemplates = [];
|
||||||
for (row in qAllTemplateUsage) {
|
for (row in qAllTemplateUsage) {
|
||||||
arrayAppend(allTemplates, {
|
arrayAppend(allTemplates, {
|
||||||
"TemplateID": row.ItemID,
|
"TemplateID": row.ID,
|
||||||
"TemplateName": row.ItemName,
|
"TemplateName": row.Name,
|
||||||
"UsageCount": row.UsageCount
|
"UsageCount": row.UsageCount
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,41 +7,41 @@ bizId = 27;
|
||||||
|
|
||||||
// Get the template items themselves
|
// Get the template items themselves
|
||||||
qTemplates = queryExecute("
|
qTemplates = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemIsCollapsible, ItemIsActive, ItemParentItemID, ItemBusinessID
|
SELECT ID, Name, IsCollapsible, IsActive, ParentItemID, BusinessID
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemID IN (11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227)
|
WHERE ID IN (11267, 11251, 11246, 11224, 11233, 11230, 11240, 11243, 11237, 11227)
|
||||||
ORDER BY ItemName
|
ORDER BY Name
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
templates = [];
|
templates = [];
|
||||||
for (row in qTemplates) {
|
for (row in qTemplates) {
|
||||||
arrayAppend(templates, {
|
arrayAppend(templates, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"IsCollapsible": row.ItemIsCollapsible,
|
"IsCollapsible": row.IsCollapsible,
|
||||||
"IsActive": row.ItemIsActive,
|
"IsActive": row.IsActive,
|
||||||
"ParentID": row.ItemParentItemID,
|
"ParentID": row.ParentItemID,
|
||||||
"BusinessID": row.ItemBusinessID
|
"BusinessID": row.BusinessID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// What templates are used by burgers vs all items?
|
// What templates are used by burgers vs all items?
|
||||||
qBurgerLinks = queryExecute("
|
qBurgerLinks = queryExecute("
|
||||||
SELECT mi.ItemID, mi.ItemName, GROUP_CONCAT(t.ItemName ORDER BY tl.SortOrder) as Templates
|
SELECT mi.ID, mi.Name, GROUP_CONCAT(t.Name ORDER BY tl.SortOrder) as Templates
|
||||||
FROM Items mi
|
FROM Items mi
|
||||||
JOIN ItemTemplateLinks tl ON tl.ItemID = mi.ItemID
|
JOIN lt_ItemID_TemplateItemID tl ON tl.ItemID = mi.ID
|
||||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
WHERE mi.ItemBusinessID = :bizId
|
WHERE mi.BusinessID = :bizId
|
||||||
AND mi.ItemParentItemID = 11271
|
AND mi.ParentItemID = 11271
|
||||||
GROUP BY mi.ItemID, mi.ItemName
|
GROUP BY mi.ID, mi.Name
|
||||||
ORDER BY mi.ItemName
|
ORDER BY mi.Name
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
burgerLinks = [];
|
burgerLinks = [];
|
||||||
for (row in qBurgerLinks) {
|
for (row in qBurgerLinks) {
|
||||||
arrayAppend(burgerLinks, {
|
arrayAppend(burgerLinks, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"Templates": row.Templates
|
"Templates": row.Templates
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -49,20 +49,20 @@ for (row in qBurgerLinks) {
|
||||||
// Also check: are there templates that SHOULD be linked to burgers?
|
// Also check: are there templates that SHOULD be linked to burgers?
|
||||||
// (e.g., Add Cheese, etc.)
|
// (e.g., Add Cheese, etc.)
|
||||||
qCheeseTemplate = queryExecute("
|
qCheeseTemplate = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemParentItemID, ItemIsActive
|
SELECT ID, Name, ParentItemID, IsActive
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID = :bizId
|
WHERE BusinessID = :bizId
|
||||||
AND ItemName LIKE '%Cheese%'
|
AND Name LIKE '%Cheese%'
|
||||||
ORDER BY ItemName
|
ORDER BY Name
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
cheeseItems = [];
|
cheeseItems = [];
|
||||||
for (row in qCheeseTemplate) {
|
for (row in qCheeseTemplate) {
|
||||||
arrayAppend(cheeseItems, {
|
arrayAppend(cheeseItems, {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"ParentID": row.ItemParentItemID,
|
"ParentID": row.ParentItemID,
|
||||||
"IsActive": row.ItemIsActive
|
"IsActive": row.IsActive
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,36 +26,36 @@
|
||||||
<cftry>
|
<cftry>
|
||||||
<!--- Get raw employee records --- >
|
<!--- Get raw employee records --- >
|
||||||
<cfset qEmployees = queryExecute("
|
<cfset qEmployees = queryExecute("
|
||||||
SELECT e.*, b.BusinessName
|
SELECT e.*, b.Name
|
||||||
FROM lt_Users_Businesses_Employees e
|
FROM Employees e
|
||||||
INNER JOIN Businesses b ON b.BusinessID = e.BusinessID
|
INNER JOIN Businesses b ON b.ID = e.BusinessID
|
||||||
WHERE e.UserID = ?
|
WHERE e.UserID = ?
|
||||||
ORDER BY b.BusinessName ASC
|
ORDER BY b.Name ASC
|
||||||
", [ { value = UserID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
|
", [ { value = UserID, cfsqltype = "cf_sql_integer" } ], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfset employees = []>
|
<cfset employees = []>
|
||||||
<cfloop query="qEmployees">
|
<cfloop query="qEmployees">
|
||||||
<cfset arrayAppend(employees, {
|
<cfset arrayAppend(employees, {
|
||||||
"EmployeeID": qEmployees.EmployeeID,
|
"EmployeeID": qEmployees.ID,
|
||||||
"UserID": qEmployees.UserID,
|
"UserID": qEmployees.UserID,
|
||||||
"BusinessID": qEmployees.BusinessID,
|
"BusinessID": qEmployees.BusinessID,
|
||||||
"BusinessName": qEmployees.BusinessName,
|
"Name": qEmployees.Name,
|
||||||
"EmployeeIsActive": qEmployees.EmployeeIsActive
|
"IsActive": qEmployees.IsActive
|
||||||
})>
|
})>
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
||||||
<!--- Check for duplicate businesses --- >
|
<!--- Check for duplicate businesses --- >
|
||||||
<cfset qDuplicates = queryExecute("
|
<cfset qDuplicates = queryExecute("
|
||||||
SELECT BusinessName, COUNT(*) AS cnt
|
SELECT Name, COUNT(*) AS cnt
|
||||||
FROM Businesses
|
FROM Businesses
|
||||||
GROUP BY BusinessName
|
GROUP BY Name
|
||||||
HAVING COUNT(*) > 1
|
HAVING COUNT(*) > 1
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfset duplicates = []>
|
<cfset duplicates = []>
|
||||||
<cfloop query="qDuplicates">
|
<cfloop query="qDuplicates">
|
||||||
<cfset arrayAppend(duplicates, {
|
<cfset arrayAppend(duplicates, {
|
||||||
"BusinessName": qDuplicates.BusinessName,
|
"Name": qDuplicates.Name,
|
||||||
"Count": qDuplicates.cnt
|
"Count": qDuplicates.cnt
|
||||||
})>
|
})>
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ try {
|
||||||
messages = [];
|
messages = [];
|
||||||
for (row in qAll) {
|
for (row in qAll) {
|
||||||
arrayAppend(messages, {
|
arrayAppend(messages, {
|
||||||
"MessageID": row.MessageID,
|
"MessageID": row.ID,
|
||||||
"TaskID": row.TaskID,
|
"TaskID": row.TaskID,
|
||||||
"SenderUserID": row.SenderUserID,
|
"SenderUserID": row.SenderUserID,
|
||||||
"SenderType": row.SenderType,
|
"SenderType": row.SenderType,
|
||||||
"MessageText": left(row.MessageText, 100),
|
"MessageBody": left(row.MessageBody, 100),
|
||||||
"CreatedOn": row.CreatedOn
|
"CreatedOn": row.CreatedOn
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,54 +10,54 @@ response = { "OK": true };
|
||||||
try {
|
try {
|
||||||
// Get Fountain Drinks item
|
// Get Fountain Drinks item
|
||||||
qFountain = queryExecute("
|
qFountain = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemParentItemID, ItemPrice, ItemIsCollapsible, ItemRequiresChildSelection
|
SELECT ID, Name, ParentItemID, Price, IsCollapsible, RequiresChildSelection
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID = 17 AND ItemName LIKE '%Fountain%'
|
WHERE BusinessID = 17 AND Name LIKE '%Fountain%'
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response["FountainDrinks"] = [];
|
response["FountainDrinks"] = [];
|
||||||
for (row in qFountain) {
|
for (row in qFountain) {
|
||||||
fountainItem = {
|
fountainItem = {
|
||||||
"ItemID": row.ItemID,
|
"ItemID": row.ID,
|
||||||
"ItemName": row.ItemName,
|
"Name": row.Name,
|
||||||
"ItemPrice": row.ItemPrice,
|
"Price": row.Price,
|
||||||
"ItemIsCollapsible": row.ItemIsCollapsible,
|
"IsCollapsible": row.IsCollapsible,
|
||||||
"ItemRequiresChildSelection": row.ItemRequiresChildSelection,
|
"RequiresChildSelection": row.RequiresChildSelection,
|
||||||
"Children": []
|
"Children": []
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get children of this item
|
// Get children of this item
|
||||||
qChildren = queryExecute("
|
qChildren = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemParentItemID, ItemPrice, ItemIsCollapsible, ItemRequiresChildSelection, ItemIsCheckedByDefault
|
SELECT ID, Name, ParentItemID, Price, IsCollapsible, RequiresChildSelection, IsCheckedByDefault
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemParentItemID = :parentId
|
WHERE ParentItemID = :parentId
|
||||||
ORDER BY ItemSortOrder
|
ORDER BY SortOrder
|
||||||
", { parentId: row.ItemID }, { datasource: "payfrit" });
|
", { parentId: row.ID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
for (child in qChildren) {
|
for (child in qChildren) {
|
||||||
childItem = {
|
childItem = {
|
||||||
"ItemID": child.ItemID,
|
"ItemID": child.ItemID,
|
||||||
"ItemName": child.ItemName,
|
"Name": child.Name,
|
||||||
"ItemPrice": child.ItemPrice,
|
"Price": child.Price,
|
||||||
"ItemIsCollapsible": child.ItemIsCollapsible,
|
"IsCollapsible": child.IsCollapsible,
|
||||||
"ItemIsCheckedByDefault": child.ItemIsCheckedByDefault,
|
"IsCheckedByDefault": child.IsCheckedByDefault,
|
||||||
"Grandchildren": []
|
"Grandchildren": []
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get grandchildren
|
// Get grandchildren
|
||||||
qGrandchildren = queryExecute("
|
qGrandchildren = queryExecute("
|
||||||
SELECT ItemID, ItemName, ItemPrice, ItemIsCheckedByDefault
|
SELECT ID, Name, Price, IsCheckedByDefault
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemParentItemID = :parentId
|
WHERE ParentItemID = :parentId
|
||||||
ORDER BY ItemSortOrder
|
ORDER BY SortOrder
|
||||||
", { parentId: child.ItemID }, { datasource: "payfrit" });
|
", { parentId: child.ItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
for (gc in qGrandchildren) {
|
for (gc in qGrandchildren) {
|
||||||
arrayAppend(childItem.Grandchildren, {
|
arrayAppend(childItem.Grandchildren, {
|
||||||
"ItemID": gc.ItemID,
|
"ItemID": gc.ItemID,
|
||||||
"ItemName": gc.ItemName,
|
"Name": gc.Name,
|
||||||
"ItemPrice": gc.ItemPrice,
|
"Price": gc.Price,
|
||||||
"ItemIsCheckedByDefault": gc.ItemIsCheckedByDefault
|
"IsCheckedByDefault": gc.IsCheckedByDefault
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@ if (structKeyExists(data, "Phone") && len(data.Phone)) {
|
||||||
phone = reReplace(data.Phone, "[^0-9]", "", "all");
|
phone = reReplace(data.Phone, "[^0-9]", "", "all");
|
||||||
|
|
||||||
qUser = queryExecute("
|
qUser = queryExecute("
|
||||||
SELECT UserID, UserFirstName, UserLastName, UserEmailAddress, UserContactNumber
|
SELECT ID, FirstName, LastName, EmailAddress, ContactNumber
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE REPLACE(REPLACE(REPLACE(UserContactNumber, '-', ''), '(', ''), ')', '') LIKE ?
|
WHERE REPLACE(REPLACE(REPLACE(ContactNumber, '-', ''), '(', ''), ')', '') LIKE ?
|
||||||
OR UserContactNumber LIKE ?
|
OR ContactNumber LIKE ?
|
||||||
", [
|
", [
|
||||||
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" },
|
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" },
|
||||||
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" }
|
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" }
|
||||||
|
|
@ -28,35 +28,35 @@ if (structKeyExists(data, "Phone") && len(data.Phone)) {
|
||||||
abort;
|
abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
userId = qUser.UserID;
|
userId = qUser.ID;
|
||||||
|
|
||||||
qEmployees = queryExecute("
|
qEmployees = queryExecute("
|
||||||
SELECT e.EmployeeID, e.BusinessID, e.EmployeeStatusID,
|
SELECT e.ID, e.BusinessID, e.StatusID,
|
||||||
CAST(e.EmployeeIsActive AS UNSIGNED) AS EmployeeIsActive,
|
CAST(e.IsActive AS UNSIGNED) AS IsActive,
|
||||||
b.BusinessName
|
b.Name
|
||||||
FROM lt_Users_Businesses_Employees e
|
FROM Employees e
|
||||||
JOIN Businesses b ON e.BusinessID = b.BusinessID
|
JOIN Businesses b ON e.BusinessID = b.ID
|
||||||
WHERE e.UserID = ?
|
WHERE e.UserID = ?
|
||||||
", [{ value: userId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
", [{ value: userId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
||||||
|
|
||||||
employees = [];
|
employees = [];
|
||||||
for (row in qEmployees) {
|
for (row in qEmployees) {
|
||||||
arrayAppend(employees, {
|
arrayAppend(employees, {
|
||||||
"EmployeeID": row.EmployeeID,
|
"EmployeeID": row.ID,
|
||||||
"BusinessID": row.BusinessID,
|
"BusinessID": row.BusinessID,
|
||||||
"BusinessName": row.BusinessName,
|
"Name": row.Name,
|
||||||
"StatusID": row.EmployeeStatusID,
|
"StatusID": row.StatusID,
|
||||||
"IsActive": row.EmployeeIsActive
|
"IsActive": row.IsActive
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"USER": {
|
"USER": {
|
||||||
"UserID": qUser.UserID,
|
"UserID": qUser.ID,
|
||||||
"Name": trim(qUser.UserFirstName & " " & qUser.UserLastName),
|
"Name": trim(qUser.FirstName & " " & qUser.LastName),
|
||||||
"Email": qUser.UserEmailAddress,
|
"Email": qUser.EmailAddress,
|
||||||
"Phone": qUser.UserContactNumber
|
"Phone": qUser.ContactNumber
|
||||||
},
|
},
|
||||||
"EMPLOYEES": employees
|
"EMPLOYEES": employees
|
||||||
}));
|
}));
|
||||||
|
|
@ -67,23 +67,23 @@ if (structKeyExists(data, "Phone") && len(data.Phone)) {
|
||||||
businessId = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 17;
|
businessId = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 17;
|
||||||
|
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT EmployeeID, UserID, EmployeeStatusID, EmployeeIsActive,
|
SELECT ID, UserID, StatusID, IsActive,
|
||||||
CAST(EmployeeIsActive AS UNSIGNED) AS IsActiveInt
|
CAST(IsActive AS UNSIGNED) AS IsActiveInt
|
||||||
FROM lt_Users_Businesses_Employees
|
FROM Employees
|
||||||
WHERE BusinessID = ?
|
WHERE BusinessID = ?
|
||||||
", [{ value: businessId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
", [{ value: businessId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
for (r in q) {
|
for (r in q) {
|
||||||
arrayAppend(rows, {
|
arrayAppend(rows, {
|
||||||
"EmployeeID": r.EmployeeID,
|
"EmployeeID": r.ID,
|
||||||
"UserID": r.UserID,
|
"UserID": r.UserID,
|
||||||
"StatusID": r.EmployeeStatusID,
|
"StatusID": r.StatusID,
|
||||||
"RawIsActive": r.EmployeeIsActive,
|
"RawIsActive": r.IsActive,
|
||||||
"CastIsActive": r.IsActiveInt,
|
"CastIsActive": r.IsActiveInt,
|
||||||
"ValRaw": val(r.EmployeeIsActive),
|
"ValRaw": val(r.IsActive),
|
||||||
"ValCast": val(r.IsActiveInt),
|
"ValCast": val(r.IsActiveInt),
|
||||||
"EqRaw1": r.EmployeeIsActive == 1,
|
"EqRaw1": r.IsActive == 1,
|
||||||
"EqCast1": r.IsActiveInt == 1
|
"EqCast1": r.IsActiveInt == 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ try {
|
||||||
// Close all open chats action
|
// Close all open chats action
|
||||||
if (structKeyExists(data, "action") && data.action == "closeAllChats") {
|
if (structKeyExists(data, "action") && data.action == "closeAllChats") {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Tasks SET TaskCompletedOn = NOW()
|
UPDATE Tasks SET CompletedOn = NOW()
|
||||||
WHERE TaskTypeID = 2 AND TaskCompletedOn IS NULL
|
WHERE TaskTypeID = 2 AND CompletedOn IS NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
writeOutput(serializeJSON({ "OK": true, "MESSAGE": "All open chats closed" }));
|
writeOutput(serializeJSON({ "OK": true, "MESSAGE": "All open chats closed" }));
|
||||||
abort;
|
abort;
|
||||||
|
|
@ -24,38 +24,38 @@ if (structKeyExists(data, "action") && data.action == "closeAllChats") {
|
||||||
<cftry>
|
<cftry>
|
||||||
<cfset qTasks = queryExecute("
|
<cfset qTasks = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
t.TaskID,
|
t.ID,
|
||||||
t.TaskBusinessID,
|
t.BusinessID,
|
||||||
t.TaskOrderID,
|
t.OrderID,
|
||||||
t.TaskClaimedByUserID,
|
t.ClaimedByUserID,
|
||||||
t.TaskClaimedOn,
|
t.ClaimedOn,
|
||||||
t.TaskCompletedOn,
|
t.CompletedOn,
|
||||||
o.OrderStatusID
|
o.StatusID
|
||||||
FROM Tasks t
|
FROM Tasks t
|
||||||
LEFT JOIN Orders o ON o.OrderID = t.TaskOrderID
|
LEFT JOIN Orders o ON o.ID = t.OrderID
|
||||||
ORDER BY t.TaskID DESC
|
ORDER BY t.ID DESC
|
||||||
LIMIT 20
|
LIMIT 20
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfset tasks = []>
|
<cfset tasks = []>
|
||||||
<cfloop query="qTasks">
|
<cfloop query="qTasks">
|
||||||
<cfset arrayAppend(tasks, {
|
<cfset arrayAppend(tasks, {
|
||||||
"TaskID": qTasks.TaskID,
|
"TaskID": qTasks.ID,
|
||||||
"TaskBusinessID": qTasks.TaskBusinessID,
|
"BusinessID": qTasks.BusinessID,
|
||||||
"TaskOrderID": qTasks.TaskOrderID,
|
"OrderID": qTasks.OrderID,
|
||||||
"TaskClaimedByUserID": qTasks.TaskClaimedByUserID,
|
"ClaimedByUserID": qTasks.ClaimedByUserID,
|
||||||
"TaskClaimedOn": isNull(qTasks.TaskClaimedOn) ? "NULL" : dateTimeFormat(qTasks.TaskClaimedOn, "yyyy-mm-dd HH:nn:ss"),
|
"ClaimedOn": isNull(qTasks.ClaimedOn) ? "NULL" : dateTimeFormat(qTasks.ClaimedOn, "yyyy-mm-dd HH:nn:ss"),
|
||||||
"TaskCompletedOn": isNull(qTasks.TaskCompletedOn) ? "NULL" : dateTimeFormat(qTasks.TaskCompletedOn, "yyyy-mm-dd HH:nn:ss"),
|
"CompletedOn": isNull(qTasks.CompletedOn) ? "NULL" : dateTimeFormat(qTasks.CompletedOn, "yyyy-mm-dd HH:nn:ss"),
|
||||||
"OrderStatusID": isNull(qTasks.OrderStatusID) ? "NULL" : qTasks.OrderStatusID
|
"StatusID": isNull(qTasks.StatusID) ? "NULL" : qTasks.StatusID
|
||||||
})>
|
})>
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
||||||
<cfset qStats = queryExecute("
|
<cfset qStats = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
COUNT(*) as Total,
|
COUNT(*) as Total,
|
||||||
SUM(CASE WHEN TaskClaimedByUserID > 0 AND TaskCompletedOn IS NULL THEN 1 ELSE 0 END) as ClaimedNotCompleted,
|
SUM(CASE WHEN ClaimedByUserID > 0 AND CompletedOn IS NULL THEN 1 ELSE 0 END) as ClaimedNotCompleted,
|
||||||
SUM(CASE WHEN TaskClaimedByUserID = 0 OR TaskClaimedByUserID IS NULL THEN 1 ELSE 0 END) as Unclaimed,
|
SUM(CASE WHEN ClaimedByUserID = 0 OR ClaimedByUserID IS NULL THEN 1 ELSE 0 END) as Unclaimed,
|
||||||
SUM(CASE WHEN TaskCompletedOn IS NOT NULL THEN 1 ELSE 0 END) as Completed
|
SUM(CASE WHEN CompletedOn IS NOT NULL THEN 1 ELSE 0 END) as Completed
|
||||||
FROM Tasks
|
FROM Tasks
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,19 @@
|
||||||
|
|
||||||
<cftry>
|
<cftry>
|
||||||
<cfset qAll = queryExecute("
|
<cfset qAll = queryExecute("
|
||||||
SELECT TaskID, TaskClaimedByUserID, TaskCompletedOn, TaskOrderID,
|
SELECT ID, ClaimedByUserID, CompletedOn, OrderID,
|
||||||
CASE WHEN TaskCompletedOn IS NULL THEN 'YES_NULL' ELSE 'NOT_NULL' END AS IsNull
|
CASE WHEN CompletedOn IS NULL THEN 'YES_NULL' ELSE 'NOT_NULL' END AS IsNull
|
||||||
FROM Tasks
|
FROM Tasks
|
||||||
ORDER BY TaskID DESC
|
ORDER BY ID DESC
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfset tasks = []>
|
<cfset tasks = []>
|
||||||
<cfloop query="qAll">
|
<cfloop query="qAll">
|
||||||
<cfset arrayAppend(tasks, {
|
<cfset arrayAppend(tasks, {
|
||||||
"TaskID": qAll.TaskID,
|
"TaskID": qAll.ID,
|
||||||
"TaskClaimedByUserID": qAll.TaskClaimedByUserID,
|
"ClaimedByUserID": qAll.ClaimedByUserID,
|
||||||
"TaskOrderID": qAll.TaskOrderID,
|
"OrderID": qAll.OrderID,
|
||||||
"TaskCompletedOn": len(trim(qAll.TaskCompletedOn)) ? toString(qAll.TaskCompletedOn) : "",
|
"CompletedOn": len(trim(qAll.CompletedOn)) ? toString(qAll.CompletedOn) : "",
|
||||||
"IsNull": qAll.IsNull
|
"IsNull": qAll.IsNull
|
||||||
})>
|
})>
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
|
||||||
|
|
@ -3,39 +3,39 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Check ItemTemplateLinks for Big Dean's (BusinessID 27)
|
// Check lt_ItemID_TemplateItemID for Big Dean's (BusinessID 27)
|
||||||
bizId = 27;
|
bizId = 27;
|
||||||
|
|
||||||
// Count total links
|
// Count total links
|
||||||
qCount = queryExecute("SELECT COUNT(*) as cnt FROM ItemTemplateLinks", {}, { datasource: "payfrit" });
|
qCount = queryExecute("SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Get template item IDs for this business
|
// Get template item IDs for this business
|
||||||
qTemplates = queryExecute("
|
qTemplates = queryExecute("
|
||||||
SELECT DISTINCT tl.TemplateItemID, i.ItemName
|
SELECT DISTINCT tl.TemplateItemID, i.Name
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
JOIN Items i ON i.ItemID = tl.TemplateItemID
|
JOIN Items i ON i.ID = tl.TemplateItemID
|
||||||
WHERE i.ItemBusinessID = :bizId
|
WHERE i.BusinessID = :bizId
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
templates = [];
|
templates = [];
|
||||||
for (row in qTemplates) {
|
for (row in qTemplates) {
|
||||||
arrayAppend(templates, { "TemplateItemID": row.TemplateItemID, "ItemName": row.ItemName });
|
arrayAppend(templates, { "TemplateItemID": row.TemplateItemID, "Name": row.Name });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get items that should be categories (ParentItemID=0, not templates)
|
// Get items that should be categories (ParentItemID=0, not templates)
|
||||||
qCategories = queryExecute("
|
qCategories = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName, i.ItemParentItemID, i.ItemIsCollapsible
|
SELECT i.ID, i.Name, i.ParentItemID, i.IsCollapsible
|
||||||
FROM Items i
|
FROM Items i
|
||||||
WHERE i.ItemBusinessID = :bizId
|
WHERE i.BusinessID = :bizId
|
||||||
AND i.ItemParentItemID = 0
|
AND i.ParentItemID = 0
|
||||||
AND i.ItemIsCollapsible = 0
|
AND i.IsCollapsible = 0
|
||||||
AND NOT EXISTS (SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID)
|
AND NOT EXISTS (SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = i.ID)
|
||||||
ORDER BY i.ItemSortOrder
|
ORDER BY i.SortOrder
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
categories = [];
|
categories = [];
|
||||||
for (row in qCategories) {
|
for (row in qCategories) {
|
||||||
arrayAppend(categories, { "ItemID": row.ItemID, "ItemName": row.ItemName });
|
arrayAppend(categories, { "ItemID": row.ID, "Name": row.Name });
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ if (len(phone) == 0) {
|
||||||
|
|
||||||
// Find user by phone
|
// Find user by phone
|
||||||
qUser = queryExecute("
|
qUser = queryExecute("
|
||||||
SELECT UserID, UserFirstName, UserLastName, UserEmailAddress, UserContactNumber
|
SELECT ID, FirstName, LastName, EmailAddress, ContactNumber
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE REPLACE(REPLACE(REPLACE(UserContactNumber, '-', ''), '(', ''), ')', '') LIKE ?
|
WHERE REPLACE(REPLACE(REPLACE(ContactNumber, '-', ''), '(', ''), ')', '') LIKE ?
|
||||||
OR UserContactNumber LIKE ?
|
OR ContactNumber LIKE ?
|
||||||
", [
|
", [
|
||||||
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" },
|
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" },
|
||||||
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" }
|
{ value: "%" & phone & "%", cfsqltype: "cf_sql_varchar" }
|
||||||
|
|
@ -34,36 +34,36 @@ if (qUser.recordCount == 0) {
|
||||||
abort;
|
abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
userId = qUser.UserID;
|
userId = qUser.ID;
|
||||||
|
|
||||||
// Get all employee records for this user
|
// Get all employee records for this user
|
||||||
qEmployees = queryExecute("
|
qEmployees = queryExecute("
|
||||||
SELECT e.EmployeeID, e.BusinessID, e.EmployeeStatusID,
|
SELECT e.ID, e.BusinessID, e.StatusID,
|
||||||
CAST(e.EmployeeIsActive AS UNSIGNED) AS EmployeeIsActive,
|
CAST(e.IsActive AS UNSIGNED) AS IsActive,
|
||||||
b.BusinessName
|
b.Name
|
||||||
FROM lt_Users_Businesses_Employees e
|
FROM Employees e
|
||||||
JOIN Businesses b ON e.BusinessID = b.BusinessID
|
JOIN Businesses b ON e.BusinessID = b.ID
|
||||||
WHERE e.UserID = ?
|
WHERE e.UserID = ?
|
||||||
", [{ value: userId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
", [{ value: userId, cfsqltype: "cf_sql_integer" }], { datasource: "payfrit" });
|
||||||
|
|
||||||
employees = [];
|
employees = [];
|
||||||
for (row in qEmployees) {
|
for (row in qEmployees) {
|
||||||
arrayAppend(employees, {
|
arrayAppend(employees, {
|
||||||
"EmployeeID": row.EmployeeID,
|
"EmployeeID": row.ID,
|
||||||
"BusinessID": row.BusinessID,
|
"BusinessID": row.BusinessID,
|
||||||
"BusinessName": row.BusinessName,
|
"Name": row.Name,
|
||||||
"StatusID": row.EmployeeStatusID,
|
"StatusID": row.StatusID,
|
||||||
"IsActive": row.EmployeeIsActive
|
"IsActive": row.IsActive
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"USER": {
|
"USER": {
|
||||||
"UserID": qUser.UserID,
|
"UserID": qUser.ID,
|
||||||
"Name": trim(qUser.UserFirstName & " " & qUser.UserLastName),
|
"Name": trim(qUser.FirstName & " " & qUser.LastName),
|
||||||
"Email": qUser.UserEmailAddress,
|
"Email": qUser.EmailAddress,
|
||||||
"Phone": qUser.UserContactNumber
|
"Phone": qUser.ContactNumber
|
||||||
},
|
},
|
||||||
"EMPLOYEES": employees
|
"EMPLOYEES": employees
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -28,19 +28,19 @@ try {
|
||||||
response["ERROR"] = "BusinessID required";
|
response["ERROR"] = "BusinessID required";
|
||||||
} else {
|
} else {
|
||||||
// Get address ID first
|
// Get address ID first
|
||||||
qBiz = queryExecute("SELECT BusinessAddressID FROM Businesses WHERE BusinessID = :id", { id: bizID }, { datasource = "payfrit" });
|
qBiz = queryExecute("SELECT AddressID FROM Businesses WHERE ID = :id", { id: bizID }, { datasource = "payfrit" });
|
||||||
|
|
||||||
if (qBiz.recordCount == 0) {
|
if (qBiz.recordCount == 0) {
|
||||||
response["ERROR"] = "Business not found";
|
response["ERROR"] = "Business not found";
|
||||||
} else {
|
} else {
|
||||||
addrID = qBiz.BusinessAddressID;
|
addrID = qBiz.AddressID;
|
||||||
|
|
||||||
// Delete business
|
// Delete business
|
||||||
queryExecute("DELETE FROM Businesses WHERE BusinessID = :id", { id: bizID }, { datasource = "payfrit" });
|
queryExecute("DELETE FROM Businesses WHERE ID = :id", { id: bizID }, { datasource = "payfrit" });
|
||||||
|
|
||||||
// Delete address if exists
|
// Delete address if exists
|
||||||
if (val(addrID) > 0) {
|
if (val(addrID) > 0) {
|
||||||
queryExecute("DELETE FROM Addresses WHERE AddressID = :id", { id: addrID }, { datasource = "payfrit" });
|
queryExecute("DELETE FROM Addresses WHERE ID = :id", { id: addrID }, { datasource = "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
* Delete Orphan Modifiers for In and Out Burger (BusinessID=17)
|
* Delete Orphan Modifiers for In and Out Burger (BusinessID=17)
|
||||||
*
|
*
|
||||||
* This script deletes duplicate modifier items that are no longer needed
|
* This script deletes duplicate modifier items that are no longer needed
|
||||||
* because we now use ItemTemplateLinks.
|
* because we now use lt_ItemID_TemplateItemID.
|
||||||
*
|
*
|
||||||
* The orphan items are level-1 modifiers (direct children of parent items)
|
* The orphan items are level-1 modifiers (direct children of parent items)
|
||||||
* that have been replaced by template links.
|
* that have been replaced by template links.
|
||||||
|
|
@ -29,18 +29,18 @@ try {
|
||||||
qOrphans = queryExecute("
|
qOrphans = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
m.ItemID,
|
m.ItemID,
|
||||||
m.ItemName,
|
m.Name,
|
||||||
m.ItemParentItemID,
|
m.ParentItemID,
|
||||||
p.ItemName as ParentName
|
p.Name as ParentName
|
||||||
FROM Items m
|
FROM Items m
|
||||||
INNER JOIN Items p ON p.ItemID = m.ItemParentItemID
|
INNER JOIN Items p ON p.ItemID = m.ParentItemID
|
||||||
INNER JOIN Categories c ON c.CategoryID = p.ItemCategoryID
|
INNER JOIN Categories c ON c.ID = p.CategoryID
|
||||||
WHERE c.CategoryBusinessID = :businessID
|
WHERE c.BusinessID = :businessID
|
||||||
AND m.ItemParentItemID > 0
|
AND m.ParentItemID > 0
|
||||||
AND p.ItemParentItemID = 0
|
AND p.ParentItemID = 0
|
||||||
AND (m.ItemIsModifierTemplate IS NULL OR m.ItemIsModifierTemplate = 0)
|
AND (m.IsModifierTemplate IS NULL OR m.IsModifierTemplate = 0)
|
||||||
AND m.ItemIsActive = 1
|
AND m.IsActive = 1
|
||||||
ORDER BY m.ItemName
|
ORDER BY m.Name
|
||||||
", { businessID: businessID }, { datasource: "payfrit" });
|
", { businessID: businessID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.deleted, "Found " & qOrphans.recordCount & " orphan modifiers to delete");
|
arrayAppend(response.deleted, "Found " & qOrphans.recordCount & " orphan modifiers to delete");
|
||||||
|
|
@ -50,23 +50,23 @@ try {
|
||||||
try {
|
try {
|
||||||
// Delete children of this orphan (options within the modifier group)
|
// Delete children of this orphan (options within the modifier group)
|
||||||
qDeleteChildren = queryExecute("
|
qDeleteChildren = queryExecute("
|
||||||
DELETE FROM Items WHERE ItemParentItemID = :orphanID
|
DELETE FROM Items WHERE ParentItemID = :orphanID
|
||||||
", { orphanID: orphan.ItemID }, { datasource: "payfrit" });
|
", { orphanID: orphan.ItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Delete the orphan itself
|
// Delete the orphan itself
|
||||||
qDeleteOrphan = queryExecute("
|
qDeleteOrphan = queryExecute("
|
||||||
DELETE FROM Items WHERE ItemID = :orphanID
|
DELETE FROM Items WHERE ID = :orphanID
|
||||||
", { orphanID: orphan.ItemID }, { datasource: "payfrit" });
|
", { orphanID: orphan.ItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.deleted, {
|
arrayAppend(response.deleted, {
|
||||||
"ItemID": orphan.ItemID,
|
"ItemID": orphan.ItemID,
|
||||||
"ItemName": orphan.ItemName,
|
"Name": orphan.Name,
|
||||||
"WasUnder": orphan.ParentName
|
"WasUnder": orphan.ParentName
|
||||||
});
|
});
|
||||||
} catch (any deleteErr) {
|
} catch (any deleteErr) {
|
||||||
arrayAppend(response.errors, {
|
arrayAppend(response.errors, {
|
||||||
"ItemID": orphan.ItemID,
|
"ItemID": orphan.ItemID,
|
||||||
"ItemName": orphan.ItemName,
|
"Name": orphan.Name,
|
||||||
"Error": deleteErr.message
|
"Error": deleteErr.message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
/**
|
/**
|
||||||
* Delete orphan Items at ParentID=0
|
* Delete orphan Items at ParentID=0
|
||||||
* Orphan = ParentID=0, no children, not in ItemTemplateLinks
|
* Orphan = ParentID=0, no children, not in lt_ItemID_TemplateItemID
|
||||||
*/
|
*/
|
||||||
|
|
||||||
response = { "OK": false, "deleted": 0, "orphans": [] };
|
response = { "OK": false, "deleted": 0, "orphans": [] };
|
||||||
|
|
@ -19,24 +19,24 @@ response = { "OK": false, "deleted": 0, "orphans": [] };
|
||||||
try {
|
try {
|
||||||
// Find orphans
|
// Find orphans
|
||||||
qOrphans = queryExecute("
|
qOrphans = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName, i.ItemBusinessID
|
SELECT i.ID, i.Name, i.BusinessID
|
||||||
FROM Items i
|
FROM Items i
|
||||||
WHERE i.ItemParentItemID = 0
|
WHERE i.ParentItemID = 0
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM Items child WHERE child.ItemParentItemID = i.ItemID
|
SELECT 1 FROM Items child WHERE child.ParentItemID = i.ID
|
||||||
)
|
)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID
|
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = i.ID
|
||||||
)
|
)
|
||||||
ORDER BY i.ItemBusinessID, i.ItemName
|
ORDER BY i.BusinessID, i.Name
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
orphanIDs = [];
|
orphanIDs = [];
|
||||||
for (orphan in qOrphans) {
|
for (orphan in qOrphans) {
|
||||||
arrayAppend(response.orphans, {
|
arrayAppend(response.orphans, {
|
||||||
"ItemID": orphan.ItemID,
|
"ItemID": orphan.ItemID,
|
||||||
"ItemName": orphan.ItemName,
|
"Name": orphan.Name,
|
||||||
"BusinessID": orphan.ItemBusinessID
|
"BusinessID": orphan.BusinessID
|
||||||
});
|
});
|
||||||
arrayAppend(orphanIDs, orphan.ItemID);
|
arrayAppend(orphanIDs, orphan.ItemID);
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ try {
|
||||||
// Delete them by ID list
|
// Delete them by ID list
|
||||||
if (arrayLen(orphanIDs) > 0) {
|
if (arrayLen(orphanIDs) > 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM Items WHERE ItemID IN (#arrayToList(orphanIDs)#)
|
DELETE FROM Items WHERE ID IN (#arrayToList(orphanIDs)#)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,16 @@
|
||||||
* Eliminate Categories Table - Schema Migration
|
* Eliminate Categories Table - Schema Migration
|
||||||
*
|
*
|
||||||
* Final unified schema:
|
* Final unified schema:
|
||||||
* - Everything is an Item with ItemBusinessID
|
* - Everything is an Item with BusinessID
|
||||||
* - ParentID=0 items are either categories or templates (derived from usage)
|
* - ParentID=0 items are either categories or templates (derived from usage)
|
||||||
* - Categories = items at ParentID=0 that have menu items as children
|
* - Categories = items at ParentID=0 that have menu items as children
|
||||||
* - Templates = items at ParentID=0 that appear in ItemTemplateLinks
|
* - Templates = items at ParentID=0 that appear in lt_ItemID_TemplateItemID
|
||||||
* - Orphans = ParentID=0 items that are neither (cleanup candidates)
|
* - Orphans = ParentID=0 items that are neither (cleanup candidates)
|
||||||
*
|
*
|
||||||
* Steps:
|
* Steps:
|
||||||
* 1. Add ItemBusinessID column to Items
|
* 1. Add BusinessID column to Items
|
||||||
* 2. For each Category: create Item, re-parent menu items, set BusinessID
|
* 2. For each Category: create Item, re-parent menu items, set BusinessID
|
||||||
* 3. Set ItemBusinessID on templates based on linked items
|
* 3. Set BusinessID on templates based on linked items
|
||||||
*
|
*
|
||||||
* Query param: ?dryRun=1 to preview without making changes
|
* Query param: ?dryRun=1 to preview without making changes
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,30 +34,30 @@ try {
|
||||||
dryRun = structKeyExists(url, "dryRun") && url.dryRun == 1;
|
dryRun = structKeyExists(url, "dryRun") && url.dryRun == 1;
|
||||||
response["dryRun"] = dryRun;
|
response["dryRun"] = dryRun;
|
||||||
|
|
||||||
// Step 1: Add ItemBusinessID column if it doesn't exist
|
// Step 1: Add BusinessID column if it doesn't exist
|
||||||
try {
|
try {
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Items ADD COLUMN ItemBusinessID INT DEFAULT 0 AFTER ItemID
|
ALTER TABLE Items ADD COLUMN BusinessID INT DEFAULT 0 AFTER ItemID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
arrayAppend(response.steps, "Added ItemBusinessID column to Items table");
|
arrayAppend(response.steps, "Added BusinessID column to Items table");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
if (findNoCase("Duplicate column", e.message)) {
|
if (findNoCase("Duplicate column", e.message)) {
|
||||||
arrayAppend(response.steps, "ItemBusinessID column already exists");
|
arrayAppend(response.steps, "BusinessID column already exists");
|
||||||
} else {
|
} else {
|
||||||
throw(e);
|
throw(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Add index on ItemBusinessID
|
// Step 2: Add index on BusinessID
|
||||||
try {
|
try {
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE INDEX idx_item_business ON Items (ItemBusinessID)
|
CREATE INDEX idx_item_business ON Items (BusinessID)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
arrayAppend(response.steps, "Added index on ItemBusinessID");
|
arrayAppend(response.steps, "Added index on BusinessID");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
if (findNoCase("Duplicate key name", e.message)) {
|
if (findNoCase("Duplicate key name", e.message)) {
|
||||||
arrayAppend(response.steps, "Index idx_item_business already exists");
|
arrayAppend(response.steps, "Index idx_item_business already exists");
|
||||||
|
|
@ -66,7 +66,7 @@ try {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Drop foreign key constraint on ItemCategoryID if it exists
|
// Step 3: Drop foreign key constraint on CategoryID if it exists
|
||||||
try {
|
try {
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
|
|
@ -84,9 +84,9 @@ try {
|
||||||
|
|
||||||
// Step 4: Get all Categories
|
// Step 4: Get all Categories
|
||||||
qCategories = queryExecute("
|
qCategories = queryExecute("
|
||||||
SELECT CategoryID, CategoryBusinessID, CategoryName
|
SELECT ID, BusinessID, Name
|
||||||
FROM Categories
|
FROM Categories
|
||||||
ORDER BY CategoryBusinessID, CategoryName
|
ORDER BY BusinessID, Name
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Found " & qCategories.recordCount & " categories to migrate");
|
arrayAppend(response.steps, "Found " & qCategories.recordCount & " categories to migrate");
|
||||||
|
|
@ -94,29 +94,29 @@ try {
|
||||||
// Step 4: Migrate each category
|
// Step 4: Migrate each category
|
||||||
for (cat in qCategories) {
|
for (cat in qCategories) {
|
||||||
migration = {
|
migration = {
|
||||||
"oldCategoryID": cat.CategoryID,
|
"oldCategoryID": cat.ID,
|
||||||
"categoryName": cat.CategoryName,
|
"categoryName": cat.Name,
|
||||||
"businessID": cat.CategoryBusinessID,
|
"businessID": cat.BusinessID,
|
||||||
"newItemID": 0,
|
"newItemID": 0,
|
||||||
"itemsUpdated": 0
|
"itemsUpdated": 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
// Create new Item for this category (ParentID=0, no template flag needed)
|
// Create new Item for this category (ParentID=0, no template flag needed)
|
||||||
// Note: ItemCategoryID set to 0 temporarily until we drop that column
|
// Note: CategoryID set to 0 temporarily until we drop that column
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemBusinessID,
|
BusinessID,
|
||||||
ItemCategoryID,
|
CategoryID,
|
||||||
ItemName,
|
Name,
|
||||||
ItemDescription,
|
Description,
|
||||||
ItemParentItemID,
|
ParentItemID,
|
||||||
ItemPrice,
|
Price,
|
||||||
ItemIsActive,
|
IsActive,
|
||||||
ItemIsCheckedByDefault,
|
IsCheckedByDefault,
|
||||||
ItemRequiresChildSelection,
|
RequiresChildSelection,
|
||||||
ItemSortOrder,
|
SortOrder,
|
||||||
ItemAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID,
|
:businessID,
|
||||||
0,
|
0,
|
||||||
|
|
@ -131,56 +131,56 @@ try {
|
||||||
NOW()
|
NOW()
|
||||||
)
|
)
|
||||||
", {
|
", {
|
||||||
businessID: cat.CategoryBusinessID,
|
businessID: cat.BusinessID,
|
||||||
categoryName: cat.CategoryName
|
categoryName: cat.Name
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Get the new Item ID
|
// Get the new Item ID
|
||||||
qNewItem = queryExecute("
|
qNewItem = queryExecute("
|
||||||
SELECT ItemID FROM Items
|
SELECT ID FROM Items
|
||||||
WHERE ItemBusinessID = :businessID
|
WHERE BusinessID = :businessID
|
||||||
AND ItemName = :categoryName
|
AND Name = :categoryName
|
||||||
AND ItemParentItemID = 0
|
AND ParentItemID = 0
|
||||||
ORDER BY ItemID DESC
|
ORDER BY ID DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
", {
|
", {
|
||||||
businessID: cat.CategoryBusinessID,
|
businessID: cat.BusinessID,
|
||||||
categoryName: cat.CategoryName
|
categoryName: cat.Name
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
newItemID = qNewItem.ItemID;
|
newItemID = qNewItem.ID;
|
||||||
migration["newItemID"] = newItemID;
|
migration["newItemID"] = newItemID;
|
||||||
|
|
||||||
// Update menu items in this category:
|
// Update menu items in this category:
|
||||||
// - Set ItemParentItemID = newItemID (for top-level items only)
|
// - Set ParentItemID = newItemID (for top-level items only)
|
||||||
// - Set ItemBusinessID = businessID (for all items)
|
// - Set BusinessID = businessID (for all items)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemBusinessID = :businessID,
|
SET BusinessID = :businessID,
|
||||||
ItemParentItemID = :newItemID
|
ParentItemID = :newItemID
|
||||||
WHERE ItemCategoryID = :categoryID
|
WHERE CategoryID = :categoryID
|
||||||
AND ItemParentItemID = 0
|
AND ParentItemID = 0
|
||||||
", {
|
", {
|
||||||
businessID: cat.CategoryBusinessID,
|
businessID: cat.BusinessID,
|
||||||
newItemID: newItemID,
|
newItemID: newItemID,
|
||||||
categoryID: cat.CategoryID
|
categoryID: cat.ID
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Set ItemBusinessID on ALL items in this category (including nested)
|
// Set BusinessID on ALL items in this category (including nested)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemBusinessID = :businessID
|
SET BusinessID = :businessID
|
||||||
WHERE ItemCategoryID = :categoryID
|
WHERE CategoryID = :categoryID
|
||||||
AND (ItemBusinessID IS NULL OR ItemBusinessID = 0)
|
AND (BusinessID IS NULL OR BusinessID = 0)
|
||||||
", {
|
", {
|
||||||
businessID: cat.CategoryBusinessID,
|
businessID: cat.BusinessID,
|
||||||
categoryID: cat.CategoryID
|
categoryID: cat.ID
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Count how many were updated
|
// Count how many were updated
|
||||||
qCount = queryExecute("
|
qCount = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Items
|
SELECT COUNT(*) as cnt FROM Items
|
||||||
WHERE ItemParentItemID = :newItemID
|
WHERE ParentItemID = :newItemID
|
||||||
", { newItemID: newItemID }, { datasource: "payfrit" });
|
", { newItemID: newItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
migration["itemsUpdated"] = qCount.cnt;
|
migration["itemsUpdated"] = qCount.cnt;
|
||||||
|
|
@ -188,9 +188,9 @@ try {
|
||||||
// Dry run - count what would be updated
|
// Dry run - count what would be updated
|
||||||
qCount = queryExecute("
|
qCount = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Items
|
SELECT COUNT(*) as cnt FROM Items
|
||||||
WHERE ItemCategoryID = :categoryID
|
WHERE CategoryID = :categoryID
|
||||||
AND ItemParentItemID = 0
|
AND ParentItemID = 0
|
||||||
", { categoryID: cat.CategoryID }, { datasource: "payfrit" });
|
", { categoryID: cat.ID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
migration["itemsToUpdate"] = qCount.cnt;
|
migration["itemsToUpdate"] = qCount.cnt;
|
||||||
}
|
}
|
||||||
|
|
@ -198,37 +198,37 @@ try {
|
||||||
arrayAppend(response.migrations, migration);
|
arrayAppend(response.migrations, migration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Set ItemBusinessID for templates (items in ItemTemplateLinks)
|
// Step 5: Set BusinessID for templates (items in lt_ItemID_TemplateItemID)
|
||||||
// Templates get their BusinessID from the items they're linked to
|
// Templates get their BusinessID from the items they're linked to
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items t
|
UPDATE Items t
|
||||||
INNER JOIN ItemTemplateLinks tl ON tl.TemplateItemID = t.ItemID
|
INNER JOIN lt_ItemID_TemplateItemID tl ON tl.TemplateItemID = t.ItemID
|
||||||
INNER JOIN Items i ON i.ItemID = tl.ItemID
|
INNER JOIN Items i ON i.ID = tl.ItemID
|
||||||
SET t.ItemBusinessID = i.ItemBusinessID
|
SET t.BusinessID = i.BusinessID
|
||||||
WHERE (t.ItemBusinessID IS NULL OR t.ItemBusinessID = 0)
|
WHERE (t.BusinessID IS NULL OR t.BusinessID = 0)
|
||||||
AND i.ItemBusinessID > 0
|
AND i.BusinessID > 0
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Set ItemBusinessID on templates from linked items");
|
arrayAppend(response.steps, "Set BusinessID on templates from linked items");
|
||||||
|
|
||||||
// Set ItemBusinessID on template children (options)
|
// Set BusinessID on template children (options)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items c
|
UPDATE Items c
|
||||||
INNER JOIN Items t ON t.ItemID = c.ItemParentItemID
|
INNER JOIN Items t ON t.ItemID = c.ParentItemID
|
||||||
SET c.ItemBusinessID = t.ItemBusinessID
|
SET c.BusinessID = t.BusinessID
|
||||||
WHERE t.ItemBusinessID > 0
|
WHERE t.BusinessID > 0
|
||||||
AND (c.ItemBusinessID IS NULL OR c.ItemBusinessID = 0)
|
AND (c.BusinessID IS NULL OR c.BusinessID = 0)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Set ItemBusinessID on template children");
|
arrayAppend(response.steps, "Set BusinessID on template children");
|
||||||
|
|
||||||
// Make sure templates have ParentID=0 (they live at top level)
|
// Make sure templates have ParentID=0 (they live at top level)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items t
|
UPDATE Items t
|
||||||
INNER JOIN ItemTemplateLinks tl ON tl.TemplateItemID = t.ItemID
|
INNER JOIN lt_ItemID_TemplateItemID tl ON tl.TemplateItemID = t.ItemID
|
||||||
SET t.ItemParentItemID = 0
|
SET t.ParentItemID = 0
|
||||||
WHERE t.ItemParentItemID != 0
|
WHERE t.ParentItemID != 0
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Ensured templates have ParentItemID=0");
|
arrayAppend(response.steps, "Ensured templates have ParentItemID=0");
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,32 @@ fakeCategories = [11177, 11180, 11183, 11186, 11190, 11193, 11196, 11199, 11204,
|
||||||
// Deactivate these items (or we could delete them, but deactivate is safer)
|
// Deactivate these items (or we could delete them, but deactivate is safer)
|
||||||
for (itemId in fakeCategories) {
|
for (itemId in fakeCategories) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items SET ItemIsActive = 0 WHERE ItemID = :itemId AND ItemBusinessID = :bizId
|
UPDATE Items SET IsActive = 0 WHERE ItemID = :itemId AND BusinessID = :bizId
|
||||||
", { itemId: itemId, bizId: bizId }, { datasource: "payfrit" });
|
", { itemId: itemId, bizId: bizId }, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also deactivate their children (modifier options that belong to these fake parents)
|
// Also deactivate their children (modifier options that belong to these fake parents)
|
||||||
for (itemId in fakeCategories) {
|
for (itemId in fakeCategories) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items SET ItemIsActive = 0 WHERE ItemParentItemID = :itemId AND ItemBusinessID = :bizId
|
UPDATE Items SET IsActive = 0 WHERE ParentItemID = :itemId AND BusinessID = :bizId
|
||||||
", { itemId: itemId, bizId: bizId }, { datasource: "payfrit" });
|
", { itemId: itemId, bizId: bizId }, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now verify what categories remain
|
// Now verify what categories remain
|
||||||
qCategories = queryExecute("
|
qCategories = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName
|
SELECT i.ID, i.Name
|
||||||
FROM Items i
|
FROM Items i
|
||||||
WHERE i.ItemBusinessID = :bizId
|
WHERE i.BusinessID = :bizId
|
||||||
AND i.ItemParentItemID = 0
|
AND i.ParentItemID = 0
|
||||||
AND i.ItemIsActive = 1
|
AND i.IsActive = 1
|
||||||
AND i.ItemIsCollapsible = 0
|
AND i.IsCollapsible = 0
|
||||||
AND NOT EXISTS (SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID)
|
AND NOT EXISTS (SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = i.ID)
|
||||||
ORDER BY i.ItemSortOrder
|
ORDER BY i.SortOrder
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
categories = [];
|
categories = [];
|
||||||
for (row in qCategories) {
|
for (row in qCategories) {
|
||||||
arrayAppend(categories, { "ItemID": row.ItemID, "ItemName": row.ItemName });
|
arrayAppend(categories, { "ItemID": row.ID, "Name": row.Name });
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ actions = [];
|
||||||
|
|
||||||
// First, let's see what templates already exist and are active for burgers
|
// First, let's see what templates already exist and are active for burgers
|
||||||
qExistingLinks = queryExecute("
|
qExistingLinks = queryExecute("
|
||||||
SELECT tl.ItemID as MenuItemID, tl.TemplateItemID, t.ItemName as TemplateName
|
SELECT tl.ItemID as MenuItemID, tl.TemplateItemID, t.Name as TemplateName
|
||||||
FROM ItemTemplateLinks tl
|
FROM lt_ItemID_TemplateItemID tl
|
||||||
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
WHERE tl.ItemID IN (:burgerIds)
|
WHERE tl.ItemID IN (:burgerIds)
|
||||||
", { burgerIds: { value: arrayToList(burgerIds), list: true } }, { datasource: "payfrit" });
|
", { burgerIds: { value: arrayToList(burgerIds), list: true } }, { datasource: "payfrit" });
|
||||||
|
|
@ -33,8 +33,8 @@ for (row in qExistingLinks) {
|
||||||
|
|
||||||
// Reactivate template 11196 (Extras with Add Cheese)
|
// Reactivate template 11196 (Extras with Add Cheese)
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
queryExecute("UPDATE Items SET ItemIsActive = 1 WHERE ItemID = 11196", {}, { datasource: "payfrit" });
|
queryExecute("UPDATE Items SET IsActive = 1 WHERE ItemID = 11196", {}, { datasource: "payfrit" });
|
||||||
queryExecute("UPDATE Items SET ItemIsActive = 1 WHERE ItemParentItemID = 11196", {}, { datasource: "payfrit" });
|
queryExecute("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)" });
|
arrayAppend(actions, { action: dryRun ? "WOULD_REACTIVATE" : "REACTIVATED", itemID: 11196, name: "Extras (Add Cheese, Add Onions)" });
|
||||||
|
|
||||||
|
|
@ -42,13 +42,13 @@ arrayAppend(actions, { action: dryRun ? "WOULD_REACTIVATE" : "REACTIVATED", item
|
||||||
for (burgerId in burgerIds) {
|
for (burgerId in burgerIds) {
|
||||||
// Check if link already exists
|
// Check if link already exists
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM ItemTemplateLinks WHERE ItemID = :burgerId AND TemplateItemID = 11196
|
SELECT COUNT(*) as cnt FROM lt_ItemID_TemplateItemID WHERE ItemID = :burgerId AND TemplateItemID = 11196
|
||||||
", { burgerId: burgerId }, { datasource: "payfrit" });
|
", { burgerId: burgerId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qCheck.cnt EQ 0) {
|
if (qCheck.cnt EQ 0) {
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
|
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||||
VALUES (:burgerId, 11196, 2)
|
VALUES (:burgerId, 11196, 2)
|
||||||
", { burgerId: burgerId }, { datasource: "payfrit" });
|
", { burgerId: burgerId }, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
@ -59,17 +59,17 @@ for (burgerId in burgerIds) {
|
||||||
// Verify the result
|
// Verify the result
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
qVerify = queryExecute("
|
qVerify = queryExecute("
|
||||||
SELECT mi.ItemID, mi.ItemName, GROUP_CONCAT(t.ItemName ORDER BY tl.SortOrder) as Templates
|
SELECT mi.ID, mi.Name, GROUP_CONCAT(t.Name ORDER BY tl.SortOrder) as Templates
|
||||||
FROM Items mi
|
FROM Items mi
|
||||||
LEFT JOIN ItemTemplateLinks tl ON tl.ItemID = mi.ItemID
|
LEFT JOIN lt_ItemID_TemplateItemID tl ON tl.ItemID = mi.ID
|
||||||
LEFT JOIN Items t ON t.ItemID = tl.TemplateItemID
|
LEFT JOIN Items t ON t.ItemID = tl.TemplateItemID
|
||||||
WHERE mi.ItemID IN (:burgerIds)
|
WHERE mi.ID IN (:burgerIds)
|
||||||
GROUP BY mi.ItemID, mi.ItemName
|
GROUP BY mi.ID, mi.Name
|
||||||
", { burgerIds: { value: arrayToList(burgerIds), list: true } }, { datasource: "payfrit" });
|
", { burgerIds: { value: arrayToList(burgerIds), list: true } }, { datasource: "payfrit" });
|
||||||
|
|
||||||
result = [];
|
result = [];
|
||||||
for (row in qVerify) {
|
for (row in qVerify) {
|
||||||
arrayAppend(result, { itemID: row.ItemID, name: row.ItemName, templates: row.Templates });
|
arrayAppend(result, { itemID: row.ID, name: row.Name, templates: row.Templates });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = "Dry run - no changes made";
|
result = "Dry run - no changes made";
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,32 @@
|
||||||
<cfsetting showdebugoutput="false">
|
<cfsetting showdebugoutput="false">
|
||||||
<cfcontent type="application/json" reset="true">
|
<cfcontent type="application/json" reset="true">
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// One-time fix: remove # prefix from BusinessBrandColor
|
// One-time fix: remove # prefix from BrandColor
|
||||||
qBefore = queryExecute("
|
qBefore = queryExecute("
|
||||||
SELECT BusinessID, BusinessBrandColor
|
SELECT ID, BrandColor
|
||||||
FROM Businesses
|
FROM Businesses
|
||||||
WHERE BusinessBrandColor LIKE :pattern
|
WHERE BrandColor LIKE :pattern
|
||||||
", { pattern: { value: "##%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
", { pattern: { value: "##%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qBefore.recordCount > 0) {
|
if (qBefore.recordCount > 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Businesses
|
UPDATE Businesses
|
||||||
SET BusinessBrandColor = SUBSTRING(BusinessBrandColor, 2)
|
SET BrandColor = SUBSTRING(BrandColor, 2)
|
||||||
WHERE BusinessBrandColor LIKE :pattern
|
WHERE BrandColor LIKE :pattern
|
||||||
", { pattern: { value: "##%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
", { pattern: { value: "##%", cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
qAfter = queryExecute("
|
qAfter = queryExecute("
|
||||||
SELECT BusinessID, BusinessBrandColor
|
SELECT ID, BrandColor
|
||||||
FROM Businesses
|
FROM Businesses
|
||||||
WHERE BusinessBrandColor IS NOT NULL AND LENGTH(BusinessBrandColor) > 0
|
WHERE BrandColor IS NOT NULL AND LENGTH(BrandColor) > 0
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
for (i = 1; i <= qAfter.recordCount; i++) {
|
for (i = 1; i <= qAfter.recordCount; i++) {
|
||||||
arrayAppend(rows, {
|
arrayAppend(rows, {
|
||||||
"BusinessID": qAfter.BusinessID[i],
|
"BusinessID": qAfter.BusinessID[i],
|
||||||
"BusinessBrandColor": qAfter.BusinessBrandColor[i]
|
"BrandColor": qAfter.BrandColor[i]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
* 2. Re-parent the three flavors under the new group
|
* 2. Re-parent the three flavors under the new group
|
||||||
* 3. Remove template flag from flavors
|
* 3. Remove template flag from flavors
|
||||||
* 4. Mark "Choose Flavor" as the template
|
* 4. Mark "Choose Flavor" as the template
|
||||||
* 5. Create ItemTemplateLinks entry for Shake -> Choose Flavor
|
* 5. Create lt_ItemID_TemplateItemID entry for Shake -> Choose Flavor
|
||||||
* 6. Set ItemRequiresChildSelection=1 on the shake item
|
* 6. Set RequiresChildSelection=1 on the shake item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
response = { "OK": false, "steps": [] };
|
response = { "OK": false, "steps": [] };
|
||||||
|
|
@ -46,19 +46,19 @@ try {
|
||||||
// Step 1: Create "Choose Flavor" modifier group under Shake
|
// Step 1: Create "Choose Flavor" modifier group under Shake
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Items (
|
INSERT INTO Items (
|
||||||
ItemCategoryID,
|
CategoryID,
|
||||||
ItemName,
|
Name,
|
||||||
ItemDescription,
|
Description,
|
||||||
ItemParentItemID,
|
ParentItemID,
|
||||||
ItemPrice,
|
Price,
|
||||||
ItemIsActive,
|
IsActive,
|
||||||
ItemIsCheckedByDefault,
|
IsCheckedByDefault,
|
||||||
ItemRequiresChildSelection,
|
RequiresChildSelection,
|
||||||
ItemMaxNumSelectionReq,
|
MaxNumSelectionReq,
|
||||||
ItemIsCollapsible,
|
IsCollapsible,
|
||||||
ItemSortOrder,
|
SortOrder,
|
||||||
ItemIsModifierTemplate,
|
IsModifierTemplate,
|
||||||
ItemAddedOn
|
AddedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:categoryID,
|
:categoryID,
|
||||||
'Choose Flavor',
|
'Choose Flavor',
|
||||||
|
|
@ -81,22 +81,22 @@ try {
|
||||||
|
|
||||||
// Get the new Choose Flavor ID
|
// Get the new Choose Flavor ID
|
||||||
qNewGroup = queryExecute("
|
qNewGroup = queryExecute("
|
||||||
SELECT ItemID FROM Items
|
SELECT ID FROM Items
|
||||||
WHERE ItemName = 'Choose Flavor'
|
WHERE Name = 'Choose Flavor'
|
||||||
AND ItemParentItemID = :shakeItemID
|
AND ParentItemID = :shakeItemID
|
||||||
ORDER BY ItemID DESC
|
ORDER BY ID DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
", { shakeItemID: shakeItemID }, { datasource: "payfrit" });
|
", { shakeItemID: shakeItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
chooseFlavorID = qNewGroup.ItemID;
|
chooseFlavorID = qNewGroup.ID;
|
||||||
arrayAppend(response.steps, "Created 'Choose Flavor' group with ID: " & chooseFlavorID);
|
arrayAppend(response.steps, "Created 'Choose Flavor' group with ID: " & chooseFlavorID);
|
||||||
|
|
||||||
// Step 2: Re-parent the three flavors under Choose Flavor
|
// Step 2: Re-parent the three flavors under Choose Flavor
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemParentItemID = :chooseFlavorID,
|
SET ParentItemID = :chooseFlavorID,
|
||||||
ItemIsModifierTemplate = 0,
|
IsModifierTemplate = 0,
|
||||||
ItemIsCheckedByDefault = 0
|
IsCheckedByDefault = 0
|
||||||
WHERE ItemID IN (:chocolateID, :strawberryID, :vanillaID)
|
WHERE ItemID IN (:chocolateID, :strawberryID, :vanillaID)
|
||||||
", {
|
", {
|
||||||
chooseFlavorID: chooseFlavorID,
|
chooseFlavorID: chooseFlavorID,
|
||||||
|
|
@ -109,14 +109,14 @@ try {
|
||||||
|
|
||||||
// Step 3: Set Vanilla as default (common choice)
|
// Step 3: Set Vanilla as default (common choice)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items SET ItemIsCheckedByDefault = 1 WHERE ItemID = :vanillaID
|
UPDATE Items SET IsCheckedByDefault = 1 WHERE ItemID = :vanillaID
|
||||||
", { vanillaID: vanillaID }, { datasource: "payfrit" });
|
", { vanillaID: vanillaID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Set Vanilla as default flavor");
|
arrayAppend(response.steps, "Set Vanilla as default flavor");
|
||||||
|
|
||||||
// Step 4: Remove old template links for the flavors
|
// Step 4: Remove old template links for the flavors
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM ItemTemplateLinks
|
DELETE FROM lt_ItemID_TemplateItemID
|
||||||
WHERE TemplateItemID IN (:chocolateID, :strawberryID, :vanillaID)
|
WHERE TemplateItemID IN (:chocolateID, :strawberryID, :vanillaID)
|
||||||
", {
|
", {
|
||||||
chocolateID: chocolateID,
|
chocolateID: chocolateID,
|
||||||
|
|
@ -126,9 +126,9 @@ try {
|
||||||
|
|
||||||
arrayAppend(response.steps, "Removed old template links for flavor items");
|
arrayAppend(response.steps, "Removed old template links for flavor items");
|
||||||
|
|
||||||
// Step 5: Create ItemTemplateLinks for Shake -> Choose Flavor
|
// Step 5: Create lt_ItemID_TemplateItemID for Shake -> Choose Flavor
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
|
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||||
VALUES (:shakeItemID, :chooseFlavorID, 0)
|
VALUES (:shakeItemID, :chooseFlavorID, 0)
|
||||||
ON DUPLICATE KEY UPDATE SortOrder = 0
|
ON DUPLICATE KEY UPDATE SortOrder = 0
|
||||||
", {
|
", {
|
||||||
|
|
@ -138,14 +138,14 @@ try {
|
||||||
|
|
||||||
arrayAppend(response.steps, "Created template link: Shake -> Choose Flavor");
|
arrayAppend(response.steps, "Created template link: Shake -> Choose Flavor");
|
||||||
|
|
||||||
// Step 6: Set ItemRequiresChildSelection on shake
|
// Step 6: Set RequiresChildSelection on shake
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemRequiresChildSelection = 1
|
SET RequiresChildSelection = 1
|
||||||
WHERE ItemID = :shakeItemID
|
WHERE ItemID = :shakeItemID
|
||||||
", { shakeItemID: shakeItemID }, { datasource: "payfrit" });
|
", { shakeItemID: shakeItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Set ItemRequiresChildSelection=1 on Shake item");
|
arrayAppend(response.steps, "Set RequiresChildSelection=1 on Shake item");
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
response["chooseFlavorID"] = chooseFlavorID;
|
response["chooseFlavorID"] = chooseFlavorID;
|
||||||
|
|
|
||||||
|
|
@ -75,17 +75,17 @@ function buildAddressString(line1, line2, city, zipCode) {
|
||||||
<cfif structKeyExists(url, "geocode") AND structKeyExists(url, "addressId")>
|
<cfif structKeyExists(url, "geocode") AND structKeyExists(url, "addressId")>
|
||||||
<cfset addressId = val(url.addressId)>
|
<cfset addressId = val(url.addressId)>
|
||||||
<cfquery name="addr" datasource="payfrit">
|
<cfquery name="addr" datasource="payfrit">
|
||||||
SELECT AddressLine1, AddressLine2, AddressCity, AddressZIPCode
|
SELECT Line1, Line2, City, ZIPCode
|
||||||
FROM Addresses WHERE AddressID = <cfqueryparam value="#addressId#" cfsqltype="cf_sql_integer">
|
FROM Addresses WHERE ID = <cfqueryparam value="#addressId#" cfsqltype="cf_sql_integer">
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfif addr.recordCount GT 0>
|
<cfif addr.recordCount GT 0>
|
||||||
<cfset fullAddress = buildAddressString(addr.AddressLine1, addr.AddressLine2, addr.AddressCity, addr.AddressZIPCode)>
|
<cfset fullAddress = buildAddressString(addr.Line1, addr.Line2, addr.City, addr.ZIPCode)>
|
||||||
<cfset geo = geocodeAddress(fullAddress)>
|
<cfset geo = geocodeAddress(fullAddress)>
|
||||||
<cfif geo.success>
|
<cfif geo.success>
|
||||||
<cfquery datasource="payfrit">
|
<cfquery datasource="payfrit">
|
||||||
UPDATE Addresses SET AddressLat = <cfqueryparam value="#geo.lat#" cfsqltype="cf_sql_decimal">,
|
UPDATE Addresses SET Latitude = <cfqueryparam value="#geo.lat#" cfsqltype="cf_sql_decimal">,
|
||||||
AddressLng = <cfqueryparam value="#geo.lng#" cfsqltype="cf_sql_decimal">
|
Longitude = <cfqueryparam value="#geo.lng#" cfsqltype="cf_sql_decimal">
|
||||||
WHERE AddressID = <cfqueryparam value="#addressId#" cfsqltype="cf_sql_integer">
|
WHERE ID = <cfqueryparam value="#addressId#" cfsqltype="cf_sql_integer">
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfoutput><div class="success">Geocoded Address ID #addressId#: #geo.lat#, #geo.lng#</div></cfoutput>
|
<cfoutput><div class="success">Geocoded Address ID #addressId#: #geo.lat#, #geo.lng#</div></cfoutput>
|
||||||
<cfelse>
|
<cfelse>
|
||||||
|
|
@ -96,21 +96,21 @@ function buildAddressString(line1, line2, city, zipCode) {
|
||||||
|
|
||||||
<cfif structKeyExists(url, "geocodeAll")>
|
<cfif structKeyExists(url, "geocodeAll")>
|
||||||
<cfquery name="missing" datasource="payfrit">
|
<cfquery name="missing" datasource="payfrit">
|
||||||
SELECT AddressID, AddressLine1, AddressLine2, AddressCity, AddressZIPCode
|
SELECT ID, Line1, Line2, City, ZIPCode
|
||||||
FROM Addresses
|
FROM Addresses
|
||||||
WHERE (AddressLat IS NULL OR AddressLat = 0)
|
WHERE (Latitude IS NULL OR Latitude = 0)
|
||||||
AND AddressLine1 IS NOT NULL AND AddressLine1 != ''
|
AND Line1 IS NOT NULL AND Line1 != ''
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfset successCount = 0>
|
<cfset successCount = 0>
|
||||||
<cfset failCount = 0>
|
<cfset failCount = 0>
|
||||||
<cfloop query="missing">
|
<cfloop query="missing">
|
||||||
<cfset fullAddress = buildAddressString(missing.AddressLine1, missing.AddressLine2, missing.AddressCity, missing.AddressZIPCode)>
|
<cfset fullAddress = buildAddressString(missing.Line1, missing.Line2, missing.City, missing.ZIPCode)>
|
||||||
<cfset geo = geocodeAddress(fullAddress)>
|
<cfset geo = geocodeAddress(fullAddress)>
|
||||||
<cfif geo.success>
|
<cfif geo.success>
|
||||||
<cfquery datasource="payfrit">
|
<cfquery datasource="payfrit">
|
||||||
UPDATE Addresses SET AddressLat = <cfqueryparam value="#geo.lat#" cfsqltype="cf_sql_decimal">,
|
UPDATE Addresses SET Latitude = <cfqueryparam value="#geo.lat#" cfsqltype="cf_sql_decimal">,
|
||||||
AddressLng = <cfqueryparam value="#geo.lng#" cfsqltype="cf_sql_decimal">
|
Longitude = <cfqueryparam value="#geo.lng#" cfsqltype="cf_sql_decimal">
|
||||||
WHERE AddressID = <cfqueryparam value="#missing.AddressID#" cfsqltype="cf_sql_integer">
|
WHERE ID = <cfqueryparam value="#missing.ID#" cfsqltype="cf_sql_integer">
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfset successCount = successCount + 1>
|
<cfset successCount = successCount + 1>
|
||||||
<cfelse>
|
<cfelse>
|
||||||
|
|
@ -123,23 +123,23 @@ function buildAddressString(line1, line2, city, zipCode) {
|
||||||
|
|
||||||
<cfquery name="addresses" datasource="payfrit">
|
<cfquery name="addresses" datasource="payfrit">
|
||||||
SELECT
|
SELECT
|
||||||
b.BusinessID,
|
b.ID,
|
||||||
b.BusinessName,
|
b.Name,
|
||||||
a.AddressID,
|
a.ID,
|
||||||
a.AddressLine1,
|
a.Line1,
|
||||||
a.AddressLine2,
|
a.Line2,
|
||||||
a.AddressCity,
|
a.City,
|
||||||
a.AddressZIPCode,
|
a.ZIPCode,
|
||||||
a.AddressLat,
|
a.Latitude,
|
||||||
a.AddressLng
|
a.Longitude
|
||||||
FROM Businesses b
|
FROM Businesses b
|
||||||
LEFT JOIN Addresses a ON b.BusinessAddressID = a.AddressID
|
LEFT JOIN Addresses a ON b.AddressID = a.ID
|
||||||
ORDER BY b.BusinessName
|
ORDER BY b.Name
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfset missingCount = 0>
|
<cfset missingCount = 0>
|
||||||
<cfloop query="addresses">
|
<cfloop query="addresses">
|
||||||
<cfif (NOT len(addresses.AddressLat) OR val(addresses.AddressLat) EQ 0) AND len(addresses.AddressLine1)>
|
<cfif (NOT len(addresses.Latitude) OR val(addresses.Latitude) EQ 0) AND len(addresses.Line1)>
|
||||||
<cfset missingCount = missingCount + 1>
|
<cfset missingCount = missingCount + 1>
|
||||||
</cfif>
|
</cfif>
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
@ -166,31 +166,31 @@ function buildAddressString(line1, line2, city, zipCode) {
|
||||||
<cfloop query="addresses">
|
<cfloop query="addresses">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
#addresses.BusinessName#
|
#addresses.Name#
|
||||||
<cfif len(addresses.AddressLat) AND val(addresses.AddressLat) NEQ 0>
|
<cfif len(addresses.Latitude) AND val(addresses.Latitude) NEQ 0>
|
||||||
<span class="has-coords">#chr(10003)#</span>
|
<span class="has-coords">#chr(10003)#</span>
|
||||||
<cfelseif len(addresses.AddressLine1)>
|
<cfelseif len(addresses.Line1)>
|
||||||
<span class="no-coords">#chr(9679)#</span>
|
<span class="no-coords">#chr(9679)#</span>
|
||||||
</cfif>
|
</cfif>
|
||||||
</td>
|
</td>
|
||||||
<td class="address">
|
<td class="address">
|
||||||
<cfif len(addresses.AddressLine1)>
|
<cfif len(addresses.Line1)>
|
||||||
#addresses.AddressLine1#<cfif len(addresses.AddressLine2)>, #addresses.AddressLine2#</cfif><br>
|
#addresses.Line1#<cfif len(addresses.Line2)>, #addresses.Line2#</cfif><br>
|
||||||
#addresses.AddressCity# #addresses.AddressZIPCode#
|
#addresses.City# #addresses.ZIPCode#
|
||||||
<cfelse>
|
<cfelse>
|
||||||
<em style="color:##666;">No address</em>
|
<em style="color:##666;">No address</em>
|
||||||
</cfif>
|
</cfif>
|
||||||
</td>
|
</td>
|
||||||
<td class="coords">
|
<td class="coords">
|
||||||
<cfif len(addresses.AddressLat) AND val(addresses.AddressLat) NEQ 0>
|
<cfif len(addresses.Latitude) AND val(addresses.Latitude) NEQ 0>
|
||||||
#numberFormat(addresses.AddressLat, "_.______")#<br>
|
#numberFormat(addresses.Latitude, "_.______")#<br>
|
||||||
#numberFormat(addresses.AddressLng, "_.______")#
|
#numberFormat(addresses.Longitude, "_.______")#
|
||||||
<cfelse>
|
<cfelse>
|
||||||
-
|
-
|
||||||
</cfif>
|
</cfif>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<cfif len(addresses.AddressLine1) AND len(addresses.AddressID)>
|
<cfif len(addresses.Line1) AND len(addresses.AddressID)>
|
||||||
<a href="?geocode=1&addressId=#addresses.AddressID#"><button class="btn-lookup">Lookup</button></a>
|
<a href="?geocode=1&addressId=#addresses.AddressID#"><button class="btn-lookup">Lookup</button></a>
|
||||||
</cfif>
|
</cfif>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ try {
|
||||||
response["ERROR"] = "ChildBusinessID required";
|
response["ERROR"] = "ChildBusinessID required";
|
||||||
} else {
|
} else {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Businesses SET BusinessParentBusinessID = :parentId WHERE BusinessID = :childId
|
UPDATE Businesses SET ParentBusinessID = :parentId WHERE ID = :childId
|
||||||
", {
|
", {
|
||||||
parentId: { value = parentID > 0 ? parentID : javaCast("null", ""), cfsqltype = "cf_sql_integer", null = parentID == 0 },
|
parentId: { value = parentID > 0 ? parentID : javaCast("null", ""), cfsqltype = "cf_sql_integer", null = parentID == 0 },
|
||||||
childId: childID
|
childId: childID
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,13 @@ try {
|
||||||
|
|
||||||
// Step 1: Get all parent items (burgers, combos, etc.)
|
// Step 1: Get all parent items (burgers, combos, etc.)
|
||||||
qParentItems = queryExecute("
|
qParentItems = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName
|
SELECT i.ID, i.Name
|
||||||
FROM Items i
|
FROM Items i
|
||||||
INNER JOIN Categories c ON c.CategoryID = i.ItemCategoryID
|
INNER JOIN Categories c ON c.ID = i.CategoryID
|
||||||
WHERE c.CategoryBusinessID = :businessID
|
WHERE c.BusinessID = :businessID
|
||||||
AND i.ItemParentItemID = 0
|
AND i.ParentItemID = 0
|
||||||
AND i.ItemIsActive = 1
|
AND i.IsActive = 1
|
||||||
ORDER BY i.ItemName
|
ORDER BY i.Name
|
||||||
", { businessID: businessID }, { datasource: "payfrit" });
|
", { businessID: businessID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Found " & qParentItems.recordCount & " parent items");
|
arrayAppend(response.steps, "Found " & qParentItems.recordCount & " parent items");
|
||||||
|
|
@ -41,20 +41,20 @@ try {
|
||||||
qModifiers = queryExecute("
|
qModifiers = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
m.ItemID,
|
m.ItemID,
|
||||||
m.ItemName,
|
m.Name,
|
||||||
m.ItemParentItemID,
|
m.ParentItemID,
|
||||||
m.ItemPrice,
|
m.Price,
|
||||||
m.ItemIsCheckedByDefault,
|
m.IsCheckedByDefault,
|
||||||
m.ItemSortOrder,
|
m.SortOrder,
|
||||||
p.ItemName as ParentName
|
p.Name as ParentName
|
||||||
FROM Items m
|
FROM Items m
|
||||||
INNER JOIN Items p ON p.ItemID = m.ItemParentItemID
|
INNER JOIN Items p ON p.ItemID = m.ParentItemID
|
||||||
INNER JOIN Categories c ON c.CategoryID = p.ItemCategoryID
|
INNER JOIN Categories c ON c.ID = p.CategoryID
|
||||||
WHERE c.CategoryBusinessID = :businessID
|
WHERE c.BusinessID = :businessID
|
||||||
AND m.ItemParentItemID > 0
|
AND m.ParentItemID > 0
|
||||||
AND m.ItemIsActive = 1
|
AND m.IsActive = 1
|
||||||
AND p.ItemParentItemID = 0
|
AND p.ParentItemID = 0
|
||||||
ORDER BY m.ItemName, m.ItemID
|
ORDER BY m.Name, m.ItemID
|
||||||
", { businessID: businessID }, { datasource: "payfrit" });
|
", { businessID: businessID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(response.steps, "Found " & qModifiers.recordCount & " level-1 modifiers");
|
arrayAppend(response.steps, "Found " & qModifiers.recordCount & " level-1 modifiers");
|
||||||
|
|
@ -62,17 +62,17 @@ try {
|
||||||
// Step 3: Group modifiers by name to find duplicates
|
// Step 3: Group modifiers by name to find duplicates
|
||||||
modifiersByName = {};
|
modifiersByName = {};
|
||||||
for (mod in qModifiers) {
|
for (mod in qModifiers) {
|
||||||
modName = mod.ItemName;
|
modName = mod.Name;
|
||||||
if (!structKeyExists(modifiersByName, modName)) {
|
if (!structKeyExists(modifiersByName, modName)) {
|
||||||
modifiersByName[modName] = [];
|
modifiersByName[modName] = [];
|
||||||
}
|
}
|
||||||
arrayAppend(modifiersByName[modName], {
|
arrayAppend(modifiersByName[modName], {
|
||||||
"ItemID": mod.ItemID,
|
"ItemID": mod.ItemID,
|
||||||
"ParentItemID": mod.ItemParentItemID,
|
"ParentItemID": mod.ParentItemID,
|
||||||
"ParentName": mod.ParentName,
|
"ParentName": mod.ParentName,
|
||||||
"Price": mod.ItemPrice,
|
"Price": mod.Price,
|
||||||
"IsDefault": mod.ItemIsCheckedByDefault,
|
"IsDefault": mod.IsCheckedByDefault,
|
||||||
"SortOrder": mod.ItemSortOrder
|
"SortOrder": mod.SortOrder
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +91,7 @@ try {
|
||||||
|
|
||||||
// Mark as template
|
// Mark as template
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items SET ItemIsModifierTemplate = 1 WHERE ItemID = :itemID
|
UPDATE Items SET IsModifierTemplate = 1 WHERE ItemID = :itemID
|
||||||
", { itemID: templateItemID }, { datasource: "payfrit" });
|
", { itemID: templateItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
templateMap[modName] = templateItemID;
|
templateMap[modName] = templateItemID;
|
||||||
|
|
@ -111,7 +111,7 @@ try {
|
||||||
// Insert link (ignore duplicates)
|
// Insert link (ignore duplicates)
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
|
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||||
VALUES (:itemID, :templateID, :sortOrder)
|
VALUES (:itemID, :templateID, :sortOrder)
|
||||||
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
|
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
|
||||||
", {
|
", {
|
||||||
|
|
@ -134,7 +134,7 @@ try {
|
||||||
if (i > 1) {
|
if (i > 1) {
|
||||||
arrayAppend(orphanItems, {
|
arrayAppend(orphanItems, {
|
||||||
"ItemID": inst.ItemID,
|
"ItemID": inst.ItemID,
|
||||||
"ItemName": modName,
|
"Name": modName,
|
||||||
"WasUnder": inst.ParentName
|
"WasUnder": inst.ParentName
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -143,12 +143,12 @@ try {
|
||||||
// Single instance - still mark as template for consistency
|
// Single instance - still mark as template for consistency
|
||||||
singleItem = instances[1];
|
singleItem = instances[1];
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items SET ItemIsModifierTemplate = 1 WHERE ItemID = :itemID
|
UPDATE Items SET IsModifierTemplate = 1 WHERE ItemID = :itemID
|
||||||
", { itemID: singleItem.ItemID }, { datasource: "payfrit" });
|
", { itemID: singleItem.ItemID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Create link
|
// Create link
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ItemTemplateLinks (ItemID, TemplateItemID, SortOrder)
|
INSERT INTO lt_ItemID_TemplateItemID (ItemID, TemplateItemID, SortOrder)
|
||||||
VALUES (:itemID, :templateID, :sortOrder)
|
VALUES (:itemID, :templateID, :sortOrder)
|
||||||
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
|
ON DUPLICATE KEY UPDATE SortOrder = :sortOrder
|
||||||
", {
|
", {
|
||||||
|
|
|
||||||
|
|
@ -27,20 +27,20 @@ try {
|
||||||
// Find all businesses with items in unified schema
|
// Find all businesses with items in unified schema
|
||||||
if (len(businessFilter)) {
|
if (len(businessFilter)) {
|
||||||
qBusinesses = queryExecute("
|
qBusinesses = queryExecute("
|
||||||
SELECT DISTINCT ItemBusinessID as BusinessID
|
SELECT DISTINCT BusinessID as BusinessID
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID = :bid AND ItemBusinessID > 0
|
WHERE BusinessID = :bid AND BusinessID > 0
|
||||||
", { bid: businessFilter }, { datasource: "payfrit" });
|
", { bid: businessFilter }, { datasource: "payfrit" });
|
||||||
} else {
|
} else {
|
||||||
qBusinesses = queryExecute("
|
qBusinesses = queryExecute("
|
||||||
SELECT DISTINCT ItemBusinessID as BusinessID
|
SELECT DISTINCT BusinessID as BusinessID
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID > 0
|
WHERE BusinessID > 0
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (biz in qBusinesses) {
|
for (biz in qBusinesses) {
|
||||||
bizId = biz.BusinessID;
|
bizId = biz.ID;
|
||||||
bizResult = { "BusinessID": bizId, "CategoriesCreated": 0, "ItemsUpdated": 0 };
|
bizResult = { "BusinessID": bizId, "CategoriesCreated": 0, "ItemsUpdated": 0 };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -48,26 +48,26 @@ try {
|
||||||
qCategoryItems = queryExecute("
|
qCategoryItems = queryExecute("
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
p.ItemID,
|
p.ItemID,
|
||||||
p.ItemName,
|
p.Name,
|
||||||
p.ItemSortOrder
|
p.SortOrder
|
||||||
FROM Items p
|
FROM Items p
|
||||||
INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
|
INNER JOIN Items c ON c.ParentItemID = p.ItemID
|
||||||
WHERE p.ItemBusinessID = :bizId
|
WHERE p.BusinessID = :bizId
|
||||||
AND p.ItemParentItemID = 0
|
AND p.ParentItemID = 0
|
||||||
AND (p.ItemIsCollapsible = 0 OR p.ItemIsCollapsible IS NULL)
|
AND (p.IsCollapsible = 0 OR p.IsCollapsible IS NULL)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
|
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = p.ItemID
|
||||||
)
|
)
|
||||||
ORDER BY p.ItemSortOrder, p.ItemName
|
ORDER BY p.SortOrder, p.Name
|
||||||
", { bizId: bizId }, { datasource: "payfrit" });
|
", { bizId: bizId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
sortOrder = 0;
|
sortOrder = 0;
|
||||||
for (catItem in qCategoryItems) {
|
for (catItem in qCategoryItems) {
|
||||||
// Check if category already exists for this business with same name
|
// Check if category already exists for this business with same name
|
||||||
qExisting = queryExecute("
|
qExisting = queryExecute("
|
||||||
SELECT CategoryID FROM Categories
|
SELECT ID FROM Categories
|
||||||
WHERE CategoryBusinessID = :bizId AND CategoryName = :name
|
WHERE BusinessID = :bizId AND Name = :name
|
||||||
", { bizId: bizId, name: left(catItem.ItemName, 30) }, { datasource: "payfrit" });
|
", { bizId: bizId, name: left(catItem.Name, 30) }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qExisting.recordCount == 0) {
|
if (qExisting.recordCount == 0) {
|
||||||
// Get next CategoryID
|
// Get next CategoryID
|
||||||
|
|
@ -79,12 +79,12 @@ try {
|
||||||
// Create new category with explicit ID
|
// Create new category with explicit ID
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Categories
|
INSERT INTO Categories
|
||||||
(CategoryID, CategoryBusinessID, CategoryParentCategoryID, CategoryName, CategorySortOrder, CategoryAddedOn)
|
(CategoryID, BusinessID, ParentCategoryID, Name, SortOrder, AddedOn)
|
||||||
VALUES (:catId, :bizId, 0, :name, :sortOrder, NOW())
|
VALUES (:catId, :bizId, 0, :name, :sortOrder, NOW())
|
||||||
", {
|
", {
|
||||||
catId: newCatId,
|
catId: newCatId,
|
||||||
bizId: bizId,
|
bizId: bizId,
|
||||||
name: left(catItem.ItemName, 30),
|
name: left(catItem.Name, 30),
|
||||||
sortOrder: sortOrder
|
sortOrder: sortOrder
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
@ -96,9 +96,9 @@ try {
|
||||||
// Update all children of this category Item to have the new CategoryID
|
// Update all children of this category Item to have the new CategoryID
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemCategoryID = :catId
|
SET CategoryID = :catId
|
||||||
WHERE ItemParentItemID = :parentId
|
WHERE ParentItemID = :parentId
|
||||||
AND ItemBusinessID = :bizId
|
AND BusinessID = :bizId
|
||||||
", {
|
", {
|
||||||
catId: newCatId,
|
catId: newCatId,
|
||||||
parentId: catItem.ItemID,
|
parentId: catItem.ItemID,
|
||||||
|
|
|
||||||
299
api/admin/perf-dashboard.cfm
Normal file
299
api/admin/perf-dashboard.cfm
Normal file
|
|
@ -0,0 +1,299 @@
|
||||||
|
<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; }
|
||||||
|
|
||||||
|
.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 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') +
|
||||||
|
card('Data Since', s.FirstLog || 'none', '');
|
||||||
|
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 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>
|
||||||
|
|
@ -40,7 +40,7 @@ try {
|
||||||
MAX(TotalMs) as MaxMs,
|
MAX(TotalMs) as MaxMs,
|
||||||
ROUND(AVG(QueryCount), 1) as AvgQueries,
|
ROUND(AVG(QueryCount), 1) as AvgQueries,
|
||||||
ROUND(AVG(ResponseBytes)) as AvgBytes
|
ROUND(AVG(ResponseBytes)) as AvgBytes
|
||||||
FROM api_perf_log
|
FROM ApiPerfLogs
|
||||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||||
GROUP BY Endpoint
|
GROUP BY Endpoint
|
||||||
ORDER BY Calls DESC
|
ORDER BY Calls DESC
|
||||||
|
|
@ -76,7 +76,7 @@ try {
|
||||||
ROUND(AVG(AppMs)) as AvgAppMs,
|
ROUND(AVG(AppMs)) as AvgAppMs,
|
||||||
MAX(TotalMs) as MaxMs,
|
MAX(TotalMs) as MaxMs,
|
||||||
ROUND(AVG(QueryCount), 1) as AvgQueries
|
ROUND(AVG(QueryCount), 1) as AvgQueries
|
||||||
FROM api_perf_log
|
FROM ApiPerfLogs
|
||||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||||
GROUP BY Endpoint
|
GROUP BY Endpoint
|
||||||
HAVING Calls >= 3
|
HAVING Calls >= 3
|
||||||
|
|
@ -106,7 +106,7 @@ try {
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT Endpoint, TotalMs, DbMs, AppMs, QueryCount, ResponseBytes,
|
SELECT Endpoint, TotalMs, DbMs, AppMs, QueryCount, ResponseBytes,
|
||||||
BusinessID, UserID, LoggedAt
|
BusinessID, UserID, LoggedAt
|
||||||
FROM api_perf_log
|
FROM ApiPerfLogs
|
||||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||||
ORDER BY TotalMs DESC
|
ORDER BY TotalMs DESC
|
||||||
LIMIT :lim
|
LIMIT :lim
|
||||||
|
|
@ -144,7 +144,7 @@ try {
|
||||||
ROUND(AVG(QueryCount), 1) as OverallAvgQueries,
|
ROUND(AVG(QueryCount), 1) as OverallAvgQueries,
|
||||||
MIN(LoggedAt) as FirstLog,
|
MIN(LoggedAt) as FirstLog,
|
||||||
MAX(LoggedAt) as LastLog
|
MAX(LoggedAt) as LastLog
|
||||||
FROM api_perf_log
|
FROM ApiPerfLogs
|
||||||
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
WHERE LoggedAt > DATE_SUB(NOW(), INTERVAL :hours HOUR)
|
||||||
", {
|
", {
|
||||||
hours: { value: hours, cfsqltype: "cf_sql_integer" }
|
hours: { value: hours, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,25 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Add QuickTaskTemplateTypeID column to QuickTaskTemplates table if it doesn't exist
|
// Add TaskTypeID column to QuickTaskTemplates table if it doesn't exist
|
||||||
try {
|
try {
|
||||||
// Check if column exists
|
// Check if column exists
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
WHERE TABLE_SCHEMA = 'payfrit'
|
WHERE TABLE_SCHEMA = 'payfrit'
|
||||||
AND TABLE_NAME = 'QuickTaskTemplates'
|
AND TABLE_NAME = 'QuickTaskTemplates'
|
||||||
AND COLUMN_NAME = 'QuickTaskTemplateTypeID'
|
AND COLUMN_NAME = 'TaskTypeID'
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qCheck.recordCount == 0) {
|
if (qCheck.recordCount == 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE QuickTaskTemplates
|
ALTER TABLE QuickTaskTemplates
|
||||||
ADD COLUMN QuickTaskTemplateTypeID INT NULL AFTER QuickTaskTemplateCategoryID
|
ADD COLUMN TaskTypeID INT NULL AFTER TaskCategoryID
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Column QuickTaskTemplateTypeID added to QuickTaskTemplates"
|
"MESSAGE": "Column TaskTypeID added to QuickTaskTemplates"
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// One-time cleanup: delete test tasks and reset
|
// One-time cleanup: delete test tasks and reset
|
||||||
try {
|
try {
|
||||||
// Delete tasks 30, 31, 32 (test tasks with bad data)
|
// Delete tasks 30, 31, 32 (test tasks with bad data)
|
||||||
queryExecute("DELETE FROM Tasks WHERE TaskID IN (30, 31, 32)", [], { datasource: "payfrit" });
|
queryExecute("DELETE FROM Tasks WHERE ID IN (30, 31, 32)", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,13 @@ try {
|
||||||
// Get template details
|
// Get template details
|
||||||
qTemplate = queryExecute("
|
qTemplate = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
QuickTaskTemplateTitle as Title,
|
Title as Title,
|
||||||
QuickTaskTemplateDetails as Details,
|
Details as Details,
|
||||||
QuickTaskTemplateCategoryID as CategoryID
|
TaskCategoryID as CategoryID
|
||||||
FROM QuickTaskTemplates
|
FROM QuickTaskTemplates
|
||||||
WHERE QuickTaskTemplateID = :id
|
WHERE ID = :id
|
||||||
AND QuickTaskTemplateBusinessID = :businessID
|
AND BusinessID = :businessID
|
||||||
AND QuickTaskTemplateIsActive = 1
|
AND IsActive = 1
|
||||||
", {
|
", {
|
||||||
id: { value: templateID, cfsqltype: "cf_sql_integer" },
|
id: { value: templateID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -66,11 +66,11 @@ try {
|
||||||
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Template not found" });
|
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Template not found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the task (TaskClaimedByUserID=0 means unclaimed/pending)
|
// Create the task (ClaimedByUserID=0 means unclaimed/pending)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Tasks (
|
INSERT INTO Tasks (
|
||||||
TaskBusinessID, TaskCategoryID, TaskTypeID,
|
BusinessID, CategoryID, TaskTypeID,
|
||||||
TaskTitle, TaskDetails, TaskAddedOn, TaskClaimedByUserID
|
Title, Details, CreatedOn, ClaimedByUserID
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID, :categoryID, :typeID,
|
:businessID, :categoryID, :typeID,
|
||||||
:title, :details, NOW(), 0
|
:title, :details, NOW(), 0
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,23 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
try {
|
try {
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT TaskID, TaskTitle, TaskDetails, TaskCategoryID, TaskClaimedByUserID, TaskCompletedOn, TaskAddedOn
|
SELECT ID, Title, Details, TaskCategoryID, ClaimedByUserID, CompletedOn, CreatedOn
|
||||||
FROM Tasks
|
FROM Tasks
|
||||||
WHERE TaskBusinessID = 47
|
WHERE BusinessID = 47
|
||||||
ORDER BY TaskID DESC
|
ORDER BY ID DESC
|
||||||
LIMIT 20
|
LIMIT 20
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
tasks = [];
|
tasks = [];
|
||||||
for (row in q) {
|
for (row in q) {
|
||||||
arrayAppend(tasks, {
|
arrayAppend(tasks, {
|
||||||
"TaskID": row.TaskID,
|
"TaskID": row.ID,
|
||||||
"Title": row.TaskTitle,
|
"Title": row.Title,
|
||||||
"Details": isNull(row.TaskDetails) ? "" : row.TaskDetails,
|
"Details": isNull(row.Details) ? "" : row.Details,
|
||||||
"CategoryID": row.TaskCategoryID,
|
"CategoryID": row.ID,
|
||||||
"ClaimedByUserID": row.TaskClaimedByUserID,
|
"ClaimedByUserID": row.ClaimedByUserID,
|
||||||
"CompletedOn": isNull(row.TaskCompletedOn) ? "" : dateTimeFormat(row.TaskCompletedOn, "yyyy-mm-dd HH:nn:ss"),
|
"CompletedOn": isNull(row.CompletedOn) ? "" : dateTimeFormat(row.CompletedOn, "yyyy-mm-dd HH:nn:ss"),
|
||||||
"AddedOn": isNull(row.TaskAddedOn) ? "" : dateTimeFormat(row.TaskAddedOn, "yyyy-mm-dd HH:nn:ss")
|
"AddedOn": isNull(row.CreatedOn) ? "" : dateTimeFormat(row.CreatedOn, "yyyy-mm-dd HH:nn:ss")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ try {
|
||||||
// Verify template exists and belongs to this business
|
// Verify template exists and belongs to this business
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT QuickTaskTemplateID FROM QuickTaskTemplates
|
SELECT QuickTaskTemplateID FROM QuickTaskTemplates
|
||||||
WHERE QuickTaskTemplateID = :id AND QuickTaskTemplateBusinessID = :businessID
|
WHERE ID = :id AND BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
id: { value: templateID, cfsqltype: "cf_sql_integer" },
|
id: { value: templateID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -62,8 +62,8 @@ try {
|
||||||
|
|
||||||
// Soft delete by setting IsActive to 0
|
// Soft delete by setting IsActive to 0
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE QuickTaskTemplates SET QuickTaskTemplateIsActive = 0
|
UPDATE QuickTaskTemplates SET IsActive = 0
|
||||||
WHERE QuickTaskTemplateID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
id: { value: templateID, cfsqltype: "cf_sql_integer" }
|
id: { value: templateID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
|
||||||
|
|
@ -45,22 +45,22 @@ try {
|
||||||
// Get quick task templates for this business
|
// Get quick task templates for this business
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
qt.QuickTaskTemplateID,
|
qt.ID,
|
||||||
qt.QuickTaskTemplateName as Name,
|
qt.Name as Name,
|
||||||
qt.QuickTaskTemplateCategoryID as CategoryID,
|
qt.TaskCategoryID as CategoryID,
|
||||||
qt.QuickTaskTemplateTitle as Title,
|
qt.Title as Title,
|
||||||
qt.QuickTaskTemplateDetails as Details,
|
qt.Details as Details,
|
||||||
qt.QuickTaskTemplateIcon as Icon,
|
qt.Icon as Icon,
|
||||||
qt.QuickTaskTemplateColor as Color,
|
qt.Color as Color,
|
||||||
qt.QuickTaskTemplateSortOrder as SortOrder,
|
qt.SortOrder as SortOrder,
|
||||||
qt.QuickTaskTemplateIsActive as IsActive,
|
qt.IsActive as IsActive,
|
||||||
tc.TaskCategoryName as CategoryName,
|
tc.Name as Name,
|
||||||
tc.TaskCategoryColor as CategoryColor
|
tc.Color as CategoryColor
|
||||||
FROM QuickTaskTemplates qt
|
FROM QuickTaskTemplates qt
|
||||||
LEFT JOIN TaskCategories tc ON qt.QuickTaskTemplateCategoryID = tc.TaskCategoryID
|
LEFT JOIN TaskCategories tc ON qt.TaskCategoryID = tc.ID
|
||||||
WHERE qt.QuickTaskTemplateBusinessID = :businessID
|
WHERE qt.BusinessID = :businessID
|
||||||
AND qt.QuickTaskTemplateIsActive = 1
|
AND qt.IsActive = 1
|
||||||
ORDER BY qt.QuickTaskTemplateSortOrder, qt.QuickTaskTemplateID
|
ORDER BY qt.SortOrder, qt.ID
|
||||||
", {
|
", {
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
@ -68,7 +68,7 @@ try {
|
||||||
templates = [];
|
templates = [];
|
||||||
for (row in q) {
|
for (row in q) {
|
||||||
arrayAppend(templates, {
|
arrayAppend(templates, {
|
||||||
"QuickTaskTemplateID": row.QuickTaskTemplateID,
|
"QuickTaskTemplateID": row.ID,
|
||||||
"Name": row.Name,
|
"Name": row.Name,
|
||||||
"CategoryID": isNull(row.CategoryID) ? "" : row.CategoryID,
|
"CategoryID": isNull(row.CategoryID) ? "" : row.CategoryID,
|
||||||
"Title": row.Title,
|
"Title": row.Title,
|
||||||
|
|
@ -77,7 +77,7 @@ try {
|
||||||
"Color": isNull(row.Color) ? "##6366f1" : row.Color,
|
"Color": isNull(row.Color) ? "##6366f1" : row.Color,
|
||||||
"SortOrder": row.SortOrder,
|
"SortOrder": row.SortOrder,
|
||||||
"IsActive": row.IsActive,
|
"IsActive": row.IsActive,
|
||||||
"CategoryName": isNull(row.CategoryName) ? "" : row.CategoryName,
|
"Name": isNull(row.Name) ? "" : row.Name,
|
||||||
"CategoryColor": isNull(row.CategoryColor) ? "" : row.CategoryColor
|
"CategoryColor": isNull(row.CategoryColor) ? "" : row.CategoryColor
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
try {
|
try {
|
||||||
// Delete all Quick Task templates for business 1
|
// Delete all Quick Task templates for business 1
|
||||||
queryExecute("DELETE FROM QuickTaskTemplates WHERE QuickTaskTemplateBusinessID = 1", [], { datasource: "payfrit" });
|
queryExecute("DELETE FROM QuickTaskTemplates WHERE BusinessID = 1", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ try {
|
||||||
// UPDATE existing template
|
// UPDATE existing template
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT QuickTaskTemplateID FROM QuickTaskTemplates
|
SELECT QuickTaskTemplateID FROM QuickTaskTemplates
|
||||||
WHERE QuickTaskTemplateID = :id AND QuickTaskTemplateBusinessID = :businessID
|
WHERE ID = :id AND BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
id: { value: templateID, cfsqltype: "cf_sql_integer" },
|
id: { value: templateID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -82,13 +82,13 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE QuickTaskTemplates SET
|
UPDATE QuickTaskTemplates SET
|
||||||
QuickTaskTemplateName = :name,
|
Name = :name,
|
||||||
QuickTaskTemplateTitle = :title,
|
Title = :title,
|
||||||
QuickTaskTemplateDetails = :details,
|
Details = :details,
|
||||||
QuickTaskTemplateCategoryID = :categoryID,
|
TaskCategoryID = :categoryID,
|
||||||
QuickTaskTemplateIcon = :icon,
|
Icon = :icon,
|
||||||
QuickTaskTemplateColor = :color
|
Color = :color
|
||||||
WHERE QuickTaskTemplateID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
name: { value: templateName, cfsqltype: "cf_sql_varchar" },
|
name: { value: templateName, cfsqltype: "cf_sql_varchar" },
|
||||||
title: { value: templateTitle, cfsqltype: "cf_sql_varchar" },
|
title: { value: templateTitle, cfsqltype: "cf_sql_varchar" },
|
||||||
|
|
@ -109,8 +109,8 @@ try {
|
||||||
// INSERT new template
|
// INSERT new template
|
||||||
// Get next sort order
|
// Get next sort order
|
||||||
qSort = queryExecute("
|
qSort = queryExecute("
|
||||||
SELECT COALESCE(MAX(QuickTaskTemplateSortOrder), 0) + 1 as nextSort
|
SELECT COALESCE(MAX(SortOrder), 0) + 1 as nextSort
|
||||||
FROM QuickTaskTemplates WHERE QuickTaskTemplateBusinessID = :businessID
|
FROM QuickTaskTemplates WHERE BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
@ -119,9 +119,9 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO QuickTaskTemplates (
|
INSERT INTO QuickTaskTemplates (
|
||||||
QuickTaskTemplateBusinessID, QuickTaskTemplateName, QuickTaskTemplateTitle,
|
BusinessID, Name, Title,
|
||||||
QuickTaskTemplateDetails, QuickTaskTemplateCategoryID,
|
Details, TaskCategoryID,
|
||||||
QuickTaskTemplateIcon, QuickTaskTemplateColor, QuickTaskTemplateSortOrder
|
Icon, Color, SortOrder
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID, :name, :title, :details, :categoryID, :icon, :color, :sortOrder
|
:businessID, :name, :title, :details, :categoryID, :icon, :color, :sortOrder
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -15,20 +15,20 @@ try {
|
||||||
// Create QuickTaskTemplates table
|
// Create QuickTaskTemplates table
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE TABLE IF NOT EXISTS QuickTaskTemplates (
|
CREATE TABLE IF NOT EXISTS QuickTaskTemplates (
|
||||||
QuickTaskTemplateID INT AUTO_INCREMENT PRIMARY KEY,
|
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
QuickTaskTemplateBusinessID INT NOT NULL,
|
BusinessID INT NOT NULL,
|
||||||
QuickTaskTemplateName VARCHAR(100) NOT NULL,
|
Name VARCHAR(100) NOT NULL,
|
||||||
QuickTaskTemplateCategoryID INT NULL,
|
TaskCategoryID INT NULL,
|
||||||
QuickTaskTemplateTypeID INT NULL,
|
TaskTypeID INT NULL,
|
||||||
QuickTaskTemplateTitle VARCHAR(255) NOT NULL,
|
Title VARCHAR(255) NOT NULL,
|
||||||
QuickTaskTemplateDetails TEXT NULL,
|
Details TEXT NULL,
|
||||||
QuickTaskTemplateIcon VARCHAR(30) DEFAULT 'add_box',
|
Icon VARCHAR(30) DEFAULT 'add_box',
|
||||||
QuickTaskTemplateColor VARCHAR(20) DEFAULT '##6366f1',
|
Color VARCHAR(20) DEFAULT '##6366f1',
|
||||||
QuickTaskTemplateSortOrder INT DEFAULT 0,
|
SortOrder INT DEFAULT 0,
|
||||||
QuickTaskTemplateIsActive BIT(1) DEFAULT b'1',
|
IsActive BIT(1) DEFAULT b'1',
|
||||||
QuickTaskTemplateCreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP,
|
CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
INDEX idx_business_active (QuickTaskTemplateBusinessID, QuickTaskTemplateIsActive),
|
INDEX idx_business_active (BusinessID, IsActive),
|
||||||
INDEX idx_sort (QuickTaskTemplateBusinessID, QuickTaskTemplateSortOrder)
|
INDEX idx_sort (BusinessID, SortOrder)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,42 +5,42 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
businessId = 27; // Big Dean's
|
businessId = 27; // Big Dean's
|
||||||
|
|
||||||
// Categories are items with ItemParentItemID=0 AND ItemIsCollapsible=0
|
// Categories are items with ParentItemID=0 AND IsCollapsible=0
|
||||||
// Modifier templates are items with ItemParentItemID=0 AND ItemIsCollapsible=1
|
// Modifier templates are items with ParentItemID=0 AND IsCollapsible=1
|
||||||
// Menu items are children of categories
|
// Menu items are children of categories
|
||||||
// Modifiers are children of menu items or modifier templates
|
// Modifiers are children of menu items or modifier templates
|
||||||
|
|
||||||
// Get category IDs (NOT modifier templates)
|
// Get category IDs (NOT modifier templates)
|
||||||
categoryIds = queryExecute("
|
categoryIds = queryExecute("
|
||||||
SELECT ItemID
|
SELECT ID
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID = :bizId
|
WHERE BusinessID = :bizId
|
||||||
AND ItemParentItemID = 0
|
AND ParentItemID = 0
|
||||||
AND ItemIsCollapsible = 0
|
AND IsCollapsible = 0
|
||||||
", { bizId: businessId }, { datasource: "payfrit" });
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
catIdList = "";
|
catIdList = "";
|
||||||
for (cat in categoryIds) {
|
for (cat in categoryIds) {
|
||||||
catIdList = listAppend(catIdList, cat.ItemID);
|
catIdList = listAppend(catIdList, cat.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now get actual menu items (direct children of categories)
|
// Now get actual menu items (direct children of categories)
|
||||||
// Exclude items that are template options (their parent is a collapsible modifier group)
|
// Exclude items that are template options (their parent is a collapsible modifier group)
|
||||||
items = queryExecute("
|
items = queryExecute("
|
||||||
SELECT i.ItemID, i.ItemName
|
SELECT i.ID, i.Name
|
||||||
FROM Items i
|
FROM Items i
|
||||||
WHERE i.ItemBusinessID = :bizId
|
WHERE i.BusinessID = :bizId
|
||||||
AND i.ItemParentItemID IN (#catIdList#)
|
AND i.ParentItemID IN (#catIdList#)
|
||||||
AND i.ItemIsCollapsible = 0
|
AND i.IsCollapsible = 0
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID
|
SELECT 1 FROM lt_ItemID_TemplateItemID tl WHERE tl.TemplateItemID = i.ID
|
||||||
)
|
)
|
||||||
", { bizId: businessId }, { datasource: "payfrit" });
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
updated = [];
|
updated = [];
|
||||||
|
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
itemName = lcase(item.ItemName);
|
itemName = lcase(item.Name);
|
||||||
newPrice = 0;
|
newPrice = 0;
|
||||||
|
|
||||||
// Drinks - $3-6
|
// Drinks - $3-6
|
||||||
|
|
@ -99,13 +99,13 @@ for (item in items) {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemPrice = :price
|
SET Price = :price
|
||||||
WHERE ItemID = :itemId
|
WHERE ItemID = :itemId
|
||||||
", { price: newPrice, itemId: item.ItemID }, { datasource: "payfrit" });
|
", { price: newPrice, itemId: item.ID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(updated, {
|
arrayAppend(updated, {
|
||||||
"ItemID": item.ItemID,
|
"ItemID": item.ID,
|
||||||
"ItemName": item.ItemName,
|
"Name": item.Name,
|
||||||
"NewPrice": newPrice
|
"NewPrice": newPrice
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -113,15 +113,15 @@ for (item in items) {
|
||||||
// Update modifier prices (children of menu items, NOT direct children of categories)
|
// 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 are items whose parent is NOT a category (i.e., parent is a menu item or modifier group)
|
||||||
modifiers = queryExecute("
|
modifiers = queryExecute("
|
||||||
SELECT ItemID, ItemName
|
SELECT ID, Name
|
||||||
FROM Items
|
FROM Items
|
||||||
WHERE ItemBusinessID = :bizId
|
WHERE BusinessID = :bizId
|
||||||
AND ItemParentItemID > 0
|
AND ParentItemID > 0
|
||||||
AND ItemParentItemID NOT IN (#catIdList#)
|
AND ParentItemID NOT IN (#catIdList#)
|
||||||
", { bizId: businessId }, { datasource: "payfrit" });
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
for (mod in modifiers) {
|
for (mod in modifiers) {
|
||||||
modName = lcase(mod.ItemName);
|
modName = lcase(mod.Name);
|
||||||
modPrice = 0;
|
modPrice = 0;
|
||||||
|
|
||||||
// Proteins are expensive add-ons
|
// Proteins are expensive add-ons
|
||||||
|
|
@ -150,7 +150,7 @@ for (mod in modifiers) {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemPrice = :price
|
SET Price = :price
|
||||||
WHERE ItemID = :itemId
|
WHERE ItemID = :itemId
|
||||||
", { price: modPrice, itemId: mod.ItemID }, { datasource: "payfrit" });
|
", { price: modPrice, itemId: mod.ItemID }, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
@ -158,17 +158,17 @@ for (mod in modifiers) {
|
||||||
// Reset category prices to $0 (shouldn't have prices for reporting)
|
// Reset category prices to $0 (shouldn't have prices for reporting)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemPrice = 0
|
SET Price = 0
|
||||||
WHERE ItemBusinessID = :bizId
|
WHERE BusinessID = :bizId
|
||||||
AND ItemParentItemID = 0
|
AND ParentItemID = 0
|
||||||
", { bizId: businessId }, { datasource: "payfrit" });
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Reset modifier group prices to $0 (only options have prices)
|
// Reset modifier group prices to $0 (only options have prices)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Items
|
UPDATE Items
|
||||||
SET ItemPrice = 0
|
SET Price = 0
|
||||||
WHERE ItemBusinessID = :bizId
|
WHERE BusinessID = :bizId
|
||||||
AND ItemIsCollapsible = 1
|
AND IsCollapsible = 1
|
||||||
", { bizId: businessId }, { datasource: "payfrit" });
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ try {
|
||||||
// Verify exists and belongs to business
|
// Verify exists and belongs to business
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT ScheduledTaskID FROM ScheduledTaskDefinitions
|
SELECT ScheduledTaskID FROM ScheduledTaskDefinitions
|
||||||
WHERE ScheduledTaskID = :id AND ScheduledTaskBusinessID = :businessID
|
WHERE ID = :id AND BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
id: { value: taskID, cfsqltype: "cf_sql_integer" },
|
id: { value: taskID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -62,7 +62,7 @@ try {
|
||||||
|
|
||||||
// Hard delete the definition
|
// Hard delete the definition
|
||||||
queryExecute("
|
queryExecute("
|
||||||
DELETE FROM ScheduledTaskDefinitions WHERE ScheduledTaskID = :id
|
DELETE FROM ScheduledTaskDefinitions WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
id: { value: taskID, cfsqltype: "cf_sql_integer" }
|
id: { value: taskID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
|
||||||
|
|
@ -45,24 +45,24 @@ try {
|
||||||
// Get scheduled task definitions for this business
|
// Get scheduled task definitions for this business
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
st.ScheduledTaskID,
|
st.ID,
|
||||||
st.ScheduledTaskName as Name,
|
st.Name as Name,
|
||||||
st.ScheduledTaskCategoryID as CategoryID,
|
st.TaskCategoryID as CategoryID,
|
||||||
st.ScheduledTaskTitle as Title,
|
st.Title as Title,
|
||||||
st.ScheduledTaskDetails as Details,
|
st.Details as Details,
|
||||||
st.ScheduledTaskCronExpression as CronExpression,
|
st.CronExpression as CronExpression,
|
||||||
COALESCE(st.ScheduledTaskScheduleType, 'cron') as ScheduleType,
|
COALESCE(st.ScheduleType, 'cron') as ScheduleType,
|
||||||
st.ScheduledTaskIntervalMinutes as IntervalMinutes,
|
st.IntervalMinutes as IntervalMinutes,
|
||||||
st.ScheduledTaskIsActive as IsActive,
|
st.IsActive as IsActive,
|
||||||
st.ScheduledTaskLastRunOn as LastRunOn,
|
st.LastRunOn as LastRunOn,
|
||||||
st.ScheduledTaskNextRunOn as NextRunOn,
|
st.NextRunOn as NextRunOn,
|
||||||
st.ScheduledTaskCreatedOn as CreatedOn,
|
st.CreatedOn as CreatedOn,
|
||||||
tc.TaskCategoryName as CategoryName,
|
tc.Name as Name,
|
||||||
tc.TaskCategoryColor as CategoryColor
|
tc.Color as CategoryColor
|
||||||
FROM ScheduledTaskDefinitions st
|
FROM ScheduledTaskDefinitions st
|
||||||
LEFT JOIN TaskCategories tc ON st.ScheduledTaskCategoryID = tc.TaskCategoryID
|
LEFT JOIN TaskCategories tc ON st.TaskCategoryID = tc.ID
|
||||||
WHERE st.ScheduledTaskBusinessID = :businessID
|
WHERE st.BusinessID = :businessID
|
||||||
ORDER BY st.ScheduledTaskIsActive DESC, st.ScheduledTaskName
|
ORDER BY st.IsActive DESC, st.Name
|
||||||
", {
|
", {
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
@ -70,7 +70,7 @@ try {
|
||||||
scheduledTasks = [];
|
scheduledTasks = [];
|
||||||
for (row in q) {
|
for (row in q) {
|
||||||
arrayAppend(scheduledTasks, {
|
arrayAppend(scheduledTasks, {
|
||||||
"ScheduledTaskID": row.ScheduledTaskID,
|
"ScheduledTaskID": row.ID,
|
||||||
"Name": row.Name,
|
"Name": row.Name,
|
||||||
"CategoryID": isNull(row.CategoryID) ? "" : row.CategoryID,
|
"CategoryID": isNull(row.CategoryID) ? "" : row.CategoryID,
|
||||||
"Title": row.Title,
|
"Title": row.Title,
|
||||||
|
|
@ -82,7 +82,7 @@ try {
|
||||||
"LastRunOn": isNull(row.LastRunOn) ? "" : dateTimeFormat(row.LastRunOn, "yyyy-mm-dd HH:nn:ss"),
|
"LastRunOn": isNull(row.LastRunOn) ? "" : dateTimeFormat(row.LastRunOn, "yyyy-mm-dd HH:nn:ss"),
|
||||||
"NextRunOn": isNull(row.NextRunOn) ? "" : dateTimeFormat(row.NextRunOn, "yyyy-mm-dd HH:nn:ss"),
|
"NextRunOn": isNull(row.NextRunOn) ? "" : dateTimeFormat(row.NextRunOn, "yyyy-mm-dd HH:nn:ss"),
|
||||||
"CreatedOn": dateTimeFormat(row.CreatedOn, "yyyy-mm-dd HH:nn:ss"),
|
"CreatedOn": dateTimeFormat(row.CreatedOn, "yyyy-mm-dd HH:nn:ss"),
|
||||||
"CategoryName": isNull(row.CategoryName) ? "" : row.CategoryName,
|
"Name": isNull(row.Name) ? "" : row.Name,
|
||||||
"CategoryColor": isNull(row.CategoryColor) ? "" : row.CategoryColor
|
"CategoryColor": isNull(row.CategoryColor) ? "" : row.CategoryColor
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,11 @@ try {
|
||||||
// Get scheduled task definition
|
// Get scheduled task definition
|
||||||
qDef = queryExecute("
|
qDef = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
ScheduledTaskTitle as Title,
|
Title as Title,
|
||||||
ScheduledTaskDetails as Details,
|
Details as Details,
|
||||||
ScheduledTaskCategoryID as CategoryID
|
TaskCategoryID as CategoryID
|
||||||
FROM ScheduledTaskDefinitions
|
FROM ScheduledTaskDefinitions
|
||||||
WHERE ScheduledTaskID = :id AND ScheduledTaskBusinessID = :businessID
|
WHERE ID = :id AND BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
id: { value: scheduledTaskID, cfsqltype: "cf_sql_integer" },
|
id: { value: scheduledTaskID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -65,11 +65,11 @@ try {
|
||||||
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Scheduled task not found" });
|
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Scheduled task not found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the task (TaskClaimedByUserID=0 means unclaimed/pending)
|
// Create the task (ClaimedByUserID=0 means unclaimed/pending)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Tasks (
|
INSERT INTO Tasks (
|
||||||
TaskBusinessID, TaskCategoryID, TaskTypeID,
|
BusinessID, CategoryID, TaskTypeID,
|
||||||
TaskTitle, TaskDetails, TaskAddedOn, TaskClaimedByUserID
|
Title, Details, CreatedOn, ClaimedByUserID
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID, :categoryID, :typeID,
|
:businessID, :categoryID, :typeID,
|
||||||
:title, :details, NOW(), 0
|
:title, :details, NOW(), 0
|
||||||
|
|
|
||||||
|
|
@ -68,26 +68,26 @@ try {
|
||||||
dueTasks = queryExecute("
|
dueTasks = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
ScheduledTaskID,
|
ScheduledTaskID,
|
||||||
ScheduledTaskBusinessID as BusinessID,
|
BusinessID as BusinessID,
|
||||||
ScheduledTaskCategoryID as CategoryID,
|
TaskCategoryID as CategoryID,
|
||||||
ScheduledTaskTitle as Title,
|
Title as Title,
|
||||||
ScheduledTaskDetails as Details,
|
Details as Details,
|
||||||
ScheduledTaskCronExpression as CronExpression,
|
CronExpression as CronExpression,
|
||||||
COALESCE(ScheduledTaskScheduleType, 'cron') as ScheduleType,
|
COALESCE(ScheduleType, 'cron') as ScheduleType,
|
||||||
ScheduledTaskIntervalMinutes as IntervalMinutes
|
IntervalMinutes as IntervalMinutes
|
||||||
FROM ScheduledTaskDefinitions
|
FROM ScheduledTaskDefinitions
|
||||||
WHERE ScheduledTaskIsActive = 1
|
WHERE IsActive = 1
|
||||||
AND ScheduledTaskNextRunOn <= NOW()
|
AND NextRunOn <= NOW()
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
createdTasks = [];
|
createdTasks = [];
|
||||||
|
|
||||||
for (task in dueTasks) {
|
for (task in dueTasks) {
|
||||||
// Create the actual task (TaskClaimedByUserID=0 means unclaimed/pending)
|
// Create the actual task (ClaimedByUserID=0 means unclaimed/pending)
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Tasks (
|
INSERT INTO Tasks (
|
||||||
TaskBusinessID, TaskCategoryID, TaskTypeID,
|
BusinessID, CategoryID, TaskTypeID,
|
||||||
TaskTitle, TaskDetails, TaskAddedOn, TaskClaimedByUserID
|
Title, Details, CreatedOn, ClaimedByUserID
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID, :categoryID, :typeID,
|
:businessID, :categoryID, :typeID,
|
||||||
:title, :details, NOW(), 0
|
:title, :details, NOW(), 0
|
||||||
|
|
@ -117,16 +117,16 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE ScheduledTaskDefinitions SET
|
UPDATE ScheduledTaskDefinitions SET
|
||||||
ScheduledTaskLastRunOn = NOW(),
|
LastRunOn = NOW(),
|
||||||
ScheduledTaskNextRunOn = :nextRun
|
NextRunOn = :nextRun
|
||||||
WHERE ScheduledTaskID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
nextRun: { value: nextRun, cfsqltype: "cf_sql_timestamp", null: isNull(nextRun) },
|
nextRun: { value: nextRun, cfsqltype: "cf_sql_timestamp", null: isNull(nextRun) },
|
||||||
id: { value: task.ScheduledTaskID, cfsqltype: "cf_sql_integer" }
|
id: { value: task.ID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
arrayAppend(createdTasks, {
|
arrayAppend(createdTasks, {
|
||||||
"ScheduledTaskID": task.ScheduledTaskID,
|
"ScheduledTaskID": task.ID,
|
||||||
"TaskID": qNew.newID,
|
"TaskID": qNew.newID,
|
||||||
"BusinessID": task.BusinessID,
|
"BusinessID": task.BusinessID,
|
||||||
"Title": task.Title
|
"Title": task.Title
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ try {
|
||||||
// UPDATE existing
|
// UPDATE existing
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT ScheduledTaskID FROM ScheduledTaskDefinitions
|
SELECT ScheduledTaskID FROM ScheduledTaskDefinitions
|
||||||
WHERE ScheduledTaskID = :id AND ScheduledTaskBusinessID = :businessID
|
WHERE ID = :id AND BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
id: { value: taskID, cfsqltype: "cf_sql_integer" },
|
id: { value: taskID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -170,16 +170,16 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE ScheduledTaskDefinitions SET
|
UPDATE ScheduledTaskDefinitions SET
|
||||||
ScheduledTaskName = :name,
|
Name = :name,
|
||||||
ScheduledTaskTitle = :title,
|
Title = :title,
|
||||||
ScheduledTaskDetails = :details,
|
Details = :details,
|
||||||
ScheduledTaskCategoryID = :categoryID,
|
TaskCategoryID = :categoryID,
|
||||||
ScheduledTaskCronExpression = :cron,
|
CronExpression = :cron,
|
||||||
ScheduledTaskScheduleType = :scheduleType,
|
ScheduleType = :scheduleType,
|
||||||
ScheduledTaskIntervalMinutes = :intervalMinutes,
|
IntervalMinutes = :intervalMinutes,
|
||||||
ScheduledTaskIsActive = :isActive,
|
IsActive = :isActive,
|
||||||
ScheduledTaskNextRunOn = :nextRun
|
NextRunOn = :nextRun
|
||||||
WHERE ScheduledTaskID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
name: { value: taskName, cfsqltype: "cf_sql_varchar" },
|
name: { value: taskName, cfsqltype: "cf_sql_varchar" },
|
||||||
title: { value: taskTitle, cfsqltype: "cf_sql_varchar" },
|
title: { value: taskTitle, cfsqltype: "cf_sql_varchar" },
|
||||||
|
|
@ -204,10 +204,10 @@ try {
|
||||||
// INSERT new
|
// INSERT new
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ScheduledTaskDefinitions (
|
INSERT INTO ScheduledTaskDefinitions (
|
||||||
ScheduledTaskBusinessID, ScheduledTaskName, ScheduledTaskTitle,
|
BusinessID, Name, Title,
|
||||||
ScheduledTaskDetails, ScheduledTaskCategoryID,
|
Details, TaskCategoryID,
|
||||||
ScheduledTaskCronExpression, ScheduledTaskScheduleType, ScheduledTaskIntervalMinutes,
|
CronExpression, ScheduleType, IntervalMinutes,
|
||||||
ScheduledTaskIsActive, ScheduledTaskNextRunOn
|
IsActive, NextRunOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID, :name, :title, :details, :categoryID, :cron, :scheduleType, :intervalMinutes, :isActive, :nextRun
|
:businessID, :name, :title, :details, :categoryID, :cron, :scheduleType, :intervalMinutes, :isActive, :nextRun
|
||||||
)
|
)
|
||||||
|
|
@ -230,8 +230,8 @@ try {
|
||||||
// Create the first task immediately
|
// Create the first task immediately
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Tasks (
|
INSERT INTO Tasks (
|
||||||
TaskBusinessID, TaskCategoryID, TaskTypeID,
|
BusinessID, CategoryID, TaskTypeID,
|
||||||
TaskTitle, TaskDetails, TaskAddedOn, TaskClaimedByUserID
|
Title, Details, CreatedOn, ClaimedByUserID
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:businessID, :categoryID, :typeID,
|
:businessID, :categoryID, :typeID,
|
||||||
:title, :details, NOW(), 0
|
:title, :details, NOW(), 0
|
||||||
|
|
@ -262,9 +262,9 @@ try {
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE ScheduledTaskDefinitions
|
UPDATE ScheduledTaskDefinitions
|
||||||
SET ScheduledTaskLastRunOn = NOW(),
|
SET LastRunOn = NOW(),
|
||||||
ScheduledTaskNextRunOn = :nextRun
|
NextRunOn = :nextRun
|
||||||
WHERE ScheduledTaskID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
nextRun: { value: actualNextRun, cfsqltype: "cf_sql_timestamp", null: isNull(actualNextRun) },
|
nextRun: { value: actualNextRun, cfsqltype: "cf_sql_timestamp", null: isNull(actualNextRun) },
|
||||||
id: { value: newScheduledTaskID, cfsqltype: "cf_sql_integer" }
|
id: { value: newScheduledTaskID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,23 @@ try {
|
||||||
// Create ScheduledTaskDefinitions table
|
// Create ScheduledTaskDefinitions table
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE TABLE IF NOT EXISTS ScheduledTaskDefinitions (
|
CREATE TABLE IF NOT EXISTS ScheduledTaskDefinitions (
|
||||||
ScheduledTaskID INT AUTO_INCREMENT PRIMARY KEY,
|
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
ScheduledTaskBusinessID INT NOT NULL,
|
BusinessID INT NOT NULL,
|
||||||
ScheduledTaskName VARCHAR(100) NOT NULL,
|
Name VARCHAR(100) NOT NULL,
|
||||||
ScheduledTaskCategoryID INT NULL,
|
TaskCategoryID INT NULL,
|
||||||
ScheduledTaskTypeID INT NULL,
|
TaskTypeID INT NULL,
|
||||||
ScheduledTaskTitle VARCHAR(255) NOT NULL,
|
Title VARCHAR(255) NOT NULL,
|
||||||
ScheduledTaskDetails TEXT NULL,
|
Details TEXT NULL,
|
||||||
ScheduledTaskCronExpression VARCHAR(100) NOT NULL,
|
CronExpression VARCHAR(100) NOT NULL,
|
||||||
ScheduledTaskScheduleType VARCHAR(20) DEFAULT 'cron',
|
ScheduleType VARCHAR(20) DEFAULT 'cron',
|
||||||
ScheduledTaskIntervalMinutes INT NULL,
|
IntervalMinutes INT NULL,
|
||||||
ScheduledTaskIsActive BIT(1) DEFAULT b'1',
|
IsActive BIT(1) DEFAULT b'1',
|
||||||
ScheduledTaskLastRunOn DATETIME NULL,
|
LastRunOn DATETIME NULL,
|
||||||
ScheduledTaskNextRunOn DATETIME NULL,
|
NextRunOn DATETIME NULL,
|
||||||
ScheduledTaskCreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP,
|
CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
ScheduledTaskCreatedByUserID INT NULL,
|
CreatedByUserID INT NULL,
|
||||||
INDEX idx_business (ScheduledTaskBusinessID),
|
INDEX idx_business (BusinessID),
|
||||||
INDEX idx_active_next (ScheduledTaskIsActive, ScheduledTaskNextRunOn)
|
INDEX idx_active_next (IsActive, NextRunOn)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ try {
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE ScheduledTaskDefinitions
|
ALTER TABLE ScheduledTaskDefinitions
|
||||||
ADD COLUMN ScheduledTaskScheduleType VARCHAR(20) DEFAULT 'cron' AFTER ScheduledTaskCronExpression
|
ADD COLUMN ScheduleType VARCHAR(20) DEFAULT 'cron' AFTER CronExpression
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
// Column likely already exists
|
// Column likely already exists
|
||||||
|
|
@ -48,7 +48,7 @@ try {
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE ScheduledTaskDefinitions
|
ALTER TABLE ScheduledTaskDefinitions
|
||||||
ADD COLUMN ScheduledTaskIntervalMinutes INT NULL AFTER ScheduledTaskScheduleType
|
ADD COLUMN IntervalMinutes INT NULL AFTER ScheduleType
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
// Column likely already exists
|
// Column likely already exists
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,11 @@ try {
|
||||||
|
|
||||||
// Verify exists and get cron expression and schedule type
|
// Verify exists and get cron expression and schedule type
|
||||||
qCheck = queryExecute("
|
qCheck = queryExecute("
|
||||||
SELECT ScheduledTaskID, ScheduledTaskCronExpression as CronExpression,
|
SELECT ScheduledTaskID, CronExpression as CronExpression,
|
||||||
COALESCE(ScheduledTaskScheduleType, 'cron') as ScheduleType,
|
COALESCE(ScheduleType, 'cron') as ScheduleType,
|
||||||
ScheduledTaskIntervalMinutes as IntervalMinutes
|
IntervalMinutes as IntervalMinutes
|
||||||
FROM ScheduledTaskDefinitions
|
FROM ScheduledTaskDefinitions
|
||||||
WHERE ScheduledTaskID = :id AND ScheduledTaskBusinessID = :businessID
|
WHERE ID = :id AND BusinessID = :businessID
|
||||||
", {
|
", {
|
||||||
id: { value: taskID, cfsqltype: "cf_sql_integer" },
|
id: { value: taskID, cfsqltype: "cf_sql_integer" },
|
||||||
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
businessID: { value: businessID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
@ -123,16 +123,16 @@ try {
|
||||||
// Cron-based: use cron parser
|
// Cron-based: use cron parser
|
||||||
nextRunOn = calculateNextRun(qCheck.CronExpression);
|
nextRunOn = calculateNextRun(qCheck.CronExpression);
|
||||||
}
|
}
|
||||||
nextRunUpdate = ", ScheduledTaskNextRunOn = :nextRun";
|
nextRunUpdate = ", NextRunOn = :nextRun";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update status
|
// Update status
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE ScheduledTaskDefinitions SET
|
UPDATE ScheduledTaskDefinitions SET
|
||||||
ScheduledTaskIsActive = :isActive,
|
IsActive = :isActive,
|
||||||
ScheduledTaskNextRunOn = :nextRun
|
NextRunOn = :nextRun
|
||||||
WHERE ScheduledTaskID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
isActive: { value: isActive, cfsqltype: "cf_sql_bit" },
|
isActive: { value: isActive, cfsqltype: "cf_sql_bit" },
|
||||||
nextRun: { value: nextRunOn, cfsqltype: "cf_sql_timestamp" },
|
nextRun: { value: nextRunOn, cfsqltype: "cf_sql_timestamp" },
|
||||||
|
|
@ -140,8 +140,8 @@ try {
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
} else {
|
} else {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE ScheduledTaskDefinitions SET ScheduledTaskIsActive = :isActive
|
UPDATE ScheduledTaskDefinitions SET IsActive = :isActive
|
||||||
WHERE ScheduledTaskID = :id
|
WHERE ID = :id
|
||||||
", {
|
", {
|
||||||
isActive: { value: isActive, cfsqltype: "cf_sql_bit" },
|
isActive: { value: isActive, cfsqltype: "cf_sql_bit" },
|
||||||
id: { value: taskID, cfsqltype: "cf_sql_integer" }
|
id: { value: taskID, cfsqltype: "cf_sql_integer" }
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ if (businessId <= 0 || userId <= 0) {
|
||||||
try {
|
try {
|
||||||
// Update employee record
|
// Update employee record
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE lt_Users_Businesses_Employees
|
UPDATE Employees
|
||||||
SET EmployeeIsActive = ?
|
SET IsActive = ?
|
||||||
WHERE BusinessID = ? AND UserID = ?
|
WHERE BusinessID = ? AND UserID = ?
|
||||||
", [
|
", [
|
||||||
{ value: isActive, cfsqltype: "cf_sql_bit" },
|
{ value: isActive, cfsqltype: "cf_sql_bit" },
|
||||||
|
|
@ -32,12 +32,12 @@ try {
|
||||||
|
|
||||||
// Get updated record
|
// Get updated record
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT e.EmployeeID, e.BusinessID, e.UserID, e.EmployeeStatusID,
|
SELECT e.ID, e.BusinessID, e.UserID, e.StatusID,
|
||||||
CAST(e.EmployeeIsActive AS UNSIGNED) AS EmployeeIsActive,
|
CAST(e.IsActive AS UNSIGNED) AS IsActive,
|
||||||
b.BusinessName, u.UserFirstName, u.UserLastName
|
b.Name, u.FirstName, u.LastName
|
||||||
FROM lt_Users_Businesses_Employees e
|
FROM Employees e
|
||||||
JOIN Businesses b ON e.BusinessID = b.BusinessID
|
JOIN Businesses b ON e.BusinessID = b.ID
|
||||||
JOIN Users u ON e.UserID = u.UserID
|
JOIN Users u ON e.UserID = u.ID
|
||||||
WHERE e.BusinessID = ? AND e.UserID = ?
|
WHERE e.BusinessID = ? AND e.UserID = ?
|
||||||
", [
|
", [
|
||||||
{ value: businessId, cfsqltype: "cf_sql_integer" },
|
{ value: businessId, cfsqltype: "cf_sql_integer" },
|
||||||
|
|
@ -49,13 +49,13 @@ try {
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Employee updated",
|
"MESSAGE": "Employee updated",
|
||||||
"EMPLOYEE": {
|
"EMPLOYEE": {
|
||||||
"EmployeeID": q.EmployeeID,
|
"EmployeeID": q.ID,
|
||||||
"BusinessID": q.BusinessID,
|
"BusinessID": q.BusinessID,
|
||||||
"BusinessName": q.BusinessName,
|
"Name": q.Name,
|
||||||
"UserID": q.UserID,
|
"UserID": q.UserID,
|
||||||
"UserName": trim(q.UserFirstName & " " & q.UserLastName),
|
"UserName": trim(q.FirstName & " " & q.LastName),
|
||||||
"StatusID": q.EmployeeStatusID,
|
"StatusID": q.StatusID,
|
||||||
"IsActive": q.EmployeeIsActive
|
"IsActive": q.IsActive
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ response = { "OK": false };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Businesses SET BusinessHeaderImageExtension = 'jpg' WHERE BusinessID = 37
|
UPDATE Businesses SET HeaderImageExtension = 'jpg' WHERE ID = 37
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.OK = true;
|
response.OK = true;
|
||||||
response.message = "Set BusinessHeaderImageExtension to 'jpg' for business 37";
|
response.message = "Set HeaderImageExtension to 'jpg' for business 37";
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
response.error = e.message;
|
response.error = e.message;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
/**
|
/**
|
||||||
* Setup Lazy Daisy Beacons
|
* Setup Lazy Daisy Beacons
|
||||||
* Creates a beacon for each service point and links them
|
* Creates a beacon for each service point and assigns them
|
||||||
*/
|
*/
|
||||||
response = { "OK": false, "steps": [] };
|
response = { "OK": false, "steps": [] };
|
||||||
|
|
||||||
|
|
@ -14,10 +14,10 @@ try {
|
||||||
|
|
||||||
// Get all service points for Lazy Daisy
|
// Get all service points for Lazy Daisy
|
||||||
qServicePoints = queryExecute("
|
qServicePoints = queryExecute("
|
||||||
SELECT ServicePointID, ServicePointName
|
SELECT ID, Name
|
||||||
FROM ServicePoints
|
FROM ServicePoints
|
||||||
WHERE ServicePointBusinessID = :bizID AND ServicePointIsActive = 1
|
WHERE BusinessID = :bizID AND IsActive = 1
|
||||||
ORDER BY ServicePointID
|
ORDER BY SortOrder, ID
|
||||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.steps.append("Found " & qServicePoints.recordCount & " service points for Lazy Daisy");
|
response.steps.append("Found " & qServicePoints.recordCount & " service points for Lazy Daisy");
|
||||||
|
|
@ -25,20 +25,20 @@ try {
|
||||||
// Create a beacon for each service point
|
// Create a beacon for each service point
|
||||||
beaconsCreated = 0;
|
beaconsCreated = 0;
|
||||||
for (sp in qServicePoints) {
|
for (sp in qServicePoints) {
|
||||||
beaconName = "Beacon - " & sp.ServicePointName;
|
beaconName = "Beacon - " & sp.Name;
|
||||||
|
|
||||||
// Check if beacon already exists for this business with this name
|
// Check if beacon already exists for this business with this name
|
||||||
qExisting = queryExecute("
|
qExisting = queryExecute("
|
||||||
SELECT BeaconID FROM Beacons
|
SELECT ID FROM Beacons
|
||||||
WHERE BeaconBusinessID = :bizId AND BeaconName = :name
|
WHERE BusinessID = :bizId AND Name = :name
|
||||||
", { bizId: lazyDaisyID, name: beaconName }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID, name: beaconName }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qExisting.recordCount == 0) {
|
if (qExisting.recordCount == 0) {
|
||||||
// Generate a unique UUID for this beacon (32 hex chars, no dashes)
|
// Generate a unique UUID for this beacon (32 hex chars, no dashes)
|
||||||
beaconUUID = "PAYFRIT00037" & numberFormat(sp.ServicePointID, "0000000000000000000");
|
beaconUUID = "PAYFRIT00037" & numberFormat(sp.ID, "0000000000000000000");
|
||||||
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Beacons (BeaconBusinessID, BeaconName, BeaconUUID, BeaconIsActive)
|
INSERT INTO Beacons (BusinessID, Name, UUID, IsActive)
|
||||||
VALUES (:bizId, :name, :uuid, 1)
|
VALUES (:bizId, :name, :uuid, 1)
|
||||||
", {
|
", {
|
||||||
bizId: lazyDaisyID,
|
bizId: lazyDaisyID,
|
||||||
|
|
@ -49,18 +49,18 @@ try {
|
||||||
qNewBeacon = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
qNewBeacon = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||||
newBeaconId = qNewBeacon.id;
|
newBeaconId = qNewBeacon.id;
|
||||||
|
|
||||||
// Create assignment to service point
|
// Assign beacon directly to service point
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO lt_Beacon_Businesses_ServicePoints
|
UPDATE ServicePoints
|
||||||
(BeaconID, BusinessID, ServicePointID, lt_Beacon_Businesses_ServicePointAssignedByUserID)
|
SET BeaconID = :beaconId, AssignedByUserID = 1
|
||||||
VALUES (:beaconId, :bizId, :spId, 1)
|
WHERE ID = :spId AND BusinessID = :bizId
|
||||||
", {
|
", {
|
||||||
beaconId: newBeaconId,
|
beaconId: newBeaconId,
|
||||||
bizId: lazyDaisyID,
|
bizId: lazyDaisyID,
|
||||||
spId: sp.ServicePointID
|
spId: sp.ID
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
response.steps.append("Created beacon '" & beaconName & "' (ID: " & newBeaconId & ") -> " & sp.ServicePointName);
|
response.steps.append("Created beacon '" & beaconName & "' (ID: " & newBeaconId & ") -> " & sp.Name);
|
||||||
beaconsCreated++;
|
beaconsCreated++;
|
||||||
} else {
|
} else {
|
||||||
response.steps.append("Beacon '" & beaconName & "' already exists, skipping");
|
response.steps.append("Beacon '" & beaconName & "' already exists, skipping");
|
||||||
|
|
@ -69,13 +69,14 @@ try {
|
||||||
|
|
||||||
// Get final status
|
// Get final status
|
||||||
qFinal = queryExecute("
|
qFinal = queryExecute("
|
||||||
SELECT lt.BeaconID, b.BeaconUUID, b.BeaconName, lt.BusinessID, biz.BusinessName, lt.ServicePointID, sp.ServicePointName
|
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||||
JOIN Beacons b ON b.BeaconID = lt.BeaconID
|
biz.Name AS BusinessName
|
||||||
JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
FROM ServicePoints sp
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
WHERE lt.BusinessID = :bizId
|
JOIN Businesses biz ON biz.ID = sp.BusinessID
|
||||||
ORDER BY sp.ServicePointName
|
WHERE sp.BusinessID = :bizId AND sp.BeaconID IS NOT NULL
|
||||||
|
ORDER BY sp.Name
|
||||||
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizId: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
beacons = [];
|
beacons = [];
|
||||||
|
|
@ -83,8 +84,9 @@ try {
|
||||||
arrayAppend(beacons, {
|
arrayAppend(beacons, {
|
||||||
"BeaconID": qFinal.BeaconID[i],
|
"BeaconID": qFinal.BeaconID[i],
|
||||||
"BeaconName": qFinal.BeaconName[i],
|
"BeaconName": qFinal.BeaconName[i],
|
||||||
"UUID": qFinal.BeaconUUID[i],
|
"UUID": qFinal.UUID[i],
|
||||||
"BusinessName": qFinal.BusinessName[i],
|
"BusinessName": qFinal.BusinessName[i],
|
||||||
|
"ServicePointID": qFinal.ServicePointID[i],
|
||||||
"ServicePointName": qFinal.ServicePointName[i]
|
"ServicePointName": qFinal.ServicePointName[i]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ try {
|
||||||
// Hours: Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm
|
// Hours: Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm
|
||||||
|
|
||||||
// Get California StateID
|
// Get California StateID
|
||||||
qState = queryExecute("SELECT tt_StateID FROM tt_States WHERE tt_StateAbbreviation = 'CA' LIMIT 1");
|
qState = queryExecute("SELECT tt_StateID FROM tt_States WHERE Abbreviation = 'CA' LIMIT 1");
|
||||||
stateId = qState.recordCount > 0 ? qState.tt_StateID : 5; // Default to 5 if not found
|
stateId = qState.recordCount > 0 ? qState.tt_StateID : 5; // Default to 5 if not found
|
||||||
|
|
||||||
// Check if Big Dean's already has an address
|
// Check if Big Dean's already has an address
|
||||||
existingAddr = queryExecute("
|
existingAddr = queryExecute("
|
||||||
SELECT AddressID FROM Addresses
|
SELECT ID FROM Addresses
|
||||||
WHERE AddressBusinessID = :bizId AND AddressUserID = 0
|
WHERE BusinessID = :bizId AND UserID = 0
|
||||||
", { bizId: businessId });
|
", { bizId: businessId });
|
||||||
|
|
||||||
if (existingAddr.recordCount == 0) {
|
if (existingAddr.recordCount == 0) {
|
||||||
// Insert new address
|
// Insert new address
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Addresses (AddressUserID, AddressBusinessID, AddressTypeID, AddressLine1, AddressCity, AddressStateID, AddressZIPCode, AddressIsDeleted, AddressAddedOn)
|
INSERT INTO Addresses (UserID, BusinessID, AddressTypeID, Line1, City, StateID, ZIPCode, IsDeleted, AddedOn)
|
||||||
VALUES (0, :bizId, '2', :line1, :city, :stateId, :zip, 0, NOW())
|
VALUES (0, :bizId, '2', :line1, :city, :stateId, :zip, 0, NOW())
|
||||||
", {
|
", {
|
||||||
bizId: businessId,
|
bizId: businessId,
|
||||||
|
|
@ -39,8 +39,8 @@ try {
|
||||||
// Update existing address
|
// Update existing address
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Addresses
|
UPDATE Addresses
|
||||||
SET AddressLine1 = :line1, AddressCity = :city, AddressStateID = :stateId, AddressZIPCode = :zip
|
SET Line1 = :line1, City = :city, StateID = :stateId, ZIPCode = :zip
|
||||||
WHERE AddressBusinessID = :bizId AND AddressUserID = 0
|
WHERE BusinessID = :bizId AND UserID = 0
|
||||||
", {
|
", {
|
||||||
bizId: businessId,
|
bizId: businessId,
|
||||||
line1: "1615 Ocean Front Walk",
|
line1: "1615 Ocean Front Walk",
|
||||||
|
|
@ -53,7 +53,7 @@ try {
|
||||||
|
|
||||||
// Check existing hours for this business
|
// Check existing hours for this business
|
||||||
existingHours = queryExecute("
|
existingHours = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Hours WHERE HoursBusinessID = :bizId
|
SELECT COUNT(*) as cnt FROM Hours WHERE BusinessID = :bizId
|
||||||
", { bizId: businessId });
|
", { bizId: businessId });
|
||||||
|
|
||||||
if (existingHours.cnt == 0) {
|
if (existingHours.cnt == 0) {
|
||||||
|
|
@ -64,39 +64,39 @@ try {
|
||||||
// Sun: 11am-10pm (day 1)
|
// Sun: 11am-10pm (day 1)
|
||||||
|
|
||||||
// Sunday (1): 11am-10pm
|
// Sunday (1): 11am-10pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 1, '11:00:00', '22:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 1, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
// Monday (2): 11am-10pm
|
// Monday (2): 11am-10pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 2, '11:00:00', '22:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 2, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
// Tuesday (3): 11am-10pm
|
// Tuesday (3): 11am-10pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 3, '11:00:00', '22:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 3, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
// Wednesday (4): 11am-10pm
|
// Wednesday (4): 11am-10pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 4, '11:00:00', '22:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 4, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
// Thursday (5): 11am-10pm
|
// Thursday (5): 11am-10pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 5, '11:00:00', '22:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 5, '11:00:00', '22:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
// Friday (6): 11am-11pm
|
// Friday (6): 11am-11pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 6, '11:00:00', '23:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 6, '11:00:00', '23:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
// Saturday (7): 11am-11pm
|
// Saturday (7): 11am-11pm
|
||||||
queryExecute("INSERT INTO Hours (HoursBusinessID, HoursDayID, HoursOpenTime, HoursClosingTime) VALUES (:bizId, 7, '11:00:00', '23:00:00')", { bizId: businessId });
|
queryExecute("INSERT INTO Hours (BusinessID, DayID, OpenTime, ClosingTime) VALUES (:bizId, 7, '11:00:00', '23:00:00')", { bizId: businessId });
|
||||||
|
|
||||||
response["HOURS_ACTION"] = "inserted 7 days";
|
response["HOURS_ACTION"] = "inserted 7 days";
|
||||||
} else {
|
} else {
|
||||||
// Update existing hours
|
// Update existing hours
|
||||||
// Mon-Thu: 11am-10pm
|
// Mon-Thu: 11am-10pm
|
||||||
queryExecute("UPDATE Hours SET HoursOpenTime = '11:00:00', HoursClosingTime = '22:00:00' WHERE HoursBusinessID = :bizId AND HoursDayID IN (1, 2, 3, 4, 5)", { bizId: businessId });
|
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 });
|
||||||
// Fri-Sat: 11am-11pm
|
// Fri-Sat: 11am-11pm
|
||||||
queryExecute("UPDATE Hours SET HoursOpenTime = '11:00:00', HoursClosingTime = '23:00:00' WHERE HoursBusinessID = :bizId AND HoursDayID IN (6, 7)", { bizId: businessId });
|
queryExecute("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";
|
response["HOURS_ACTION"] = "updated";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update phone on Businesses table (if column exists)
|
// Update phone on Businesses table (if column exists)
|
||||||
try {
|
try {
|
||||||
queryExecute("UPDATE Businesses SET BusinessPhone = :phone WHERE BusinessID = :bizId", {
|
queryExecute("UPDATE Businesses SET Phone = :phone WHERE ID = :bizId", {
|
||||||
phone: "(310) 393-2666",
|
phone: "(310) 393-2666",
|
||||||
bizId: businessId
|
bizId: businessId
|
||||||
});
|
});
|
||||||
|
|
@ -107,35 +107,35 @@ try {
|
||||||
|
|
||||||
// Verify the data
|
// Verify the data
|
||||||
address = queryExecute("
|
address = queryExecute("
|
||||||
SELECT a.*, s.tt_StateAbbreviation
|
SELECT a.*, s.Abbreviation
|
||||||
FROM Addresses a
|
FROM Addresses a
|
||||||
LEFT JOIN tt_States s ON s.tt_StateID = a.AddressStateID
|
LEFT JOIN tt_States s ON s.ID = a.StateID
|
||||||
WHERE a.AddressBusinessID = :bizId AND a.AddressUserID = 0
|
WHERE a.BusinessID = :bizId AND a.UserID = 0
|
||||||
", { bizId: businessId });
|
", { bizId: businessId });
|
||||||
|
|
||||||
hours = queryExecute("
|
hours = queryExecute("
|
||||||
SELECT h.*, d.tt_DayName
|
SELECT h.*, d.tt_DayName
|
||||||
FROM Hours h
|
FROM Hours h
|
||||||
JOIN tt_Days d ON d.tt_DayID = h.HoursDayID
|
JOIN tt_Days d ON d.ID = h.DayID
|
||||||
WHERE h.HoursBusinessID = :bizId
|
WHERE h.BusinessID = :bizId
|
||||||
ORDER BY h.HoursDayID
|
ORDER BY h.DayID
|
||||||
", { bizId: businessId });
|
", { bizId: businessId });
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
response["BUSINESS_ID"] = businessId;
|
response["BUSINESS_ID"] = businessId;
|
||||||
response["ADDRESS"] = address.recordCount > 0 ? {
|
response["ADDRESS"] = address.recordCount > 0 ? {
|
||||||
"line1": address.AddressLine1,
|
"line1": address.Line1,
|
||||||
"city": address.AddressCity,
|
"city": address.City,
|
||||||
"state": address.tt_StateAbbreviation,
|
"state": address.Abbreviation,
|
||||||
"zip": address.AddressZIPCode
|
"zip": address.ZIPCode
|
||||||
} : "not found";
|
} : "not found";
|
||||||
|
|
||||||
hoursArr = [];
|
hoursArr = [];
|
||||||
for (h in hours) {
|
for (h in hours) {
|
||||||
arrayAppend(hoursArr, {
|
arrayAppend(hoursArr, {
|
||||||
"day": h.tt_DayName,
|
"day": h.tt_DayName,
|
||||||
"open": timeFormat(h.HoursOpenTime, "h:mm tt"),
|
"open": timeFormat(h.OpenTime, "h:mm tt"),
|
||||||
"close": timeFormat(h.HoursClosingTime, "h:mm tt")
|
"close": timeFormat(h.ClosingTime, "h:mm tt")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
response["HOURS"] = hoursArr;
|
response["HOURS"] = hoursArr;
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,19 @@ response = { "OK": false };
|
||||||
try {
|
try {
|
||||||
// Check if Big Dean's already has stations
|
// Check if Big Dean's already has stations
|
||||||
existing = queryExecute("
|
existing = queryExecute("
|
||||||
SELECT COUNT(*) as cnt FROM Stations WHERE StationBusinessID = :bizId
|
SELECT COUNT(*) as cnt FROM Stations WHERE BusinessID = :bizId
|
||||||
", { bizId: businessId });
|
", { bizId: businessId });
|
||||||
|
|
||||||
if (existing.cnt == 0) {
|
if (existing.cnt == 0) {
|
||||||
// Insert Kitchen station
|
// Insert Kitchen station
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Stations (StationBusinessID, StationName, StationColor, StationSortOrder, StationIsActive)
|
INSERT INTO Stations (BusinessID, Name, Color, SortOrder, IsActive)
|
||||||
VALUES (:bizId, 'Kitchen', :color1, 1, 1)
|
VALUES (:bizId, 'Kitchen', :color1, 1, 1)
|
||||||
", { bizId: businessId, color1: "##FF5722" });
|
", { bizId: businessId, color1: "##FF5722" });
|
||||||
|
|
||||||
// Insert Bar station
|
// Insert Bar station
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO Stations (StationBusinessID, StationName, StationColor, StationSortOrder, StationIsActive)
|
INSERT INTO Stations (BusinessID, Name, Color, SortOrder, IsActive)
|
||||||
VALUES (:bizId, 'Bar', :color2, 2, 1)
|
VALUES (:bizId, 'Bar', :color2, 2, 1)
|
||||||
", { bizId: businessId, color2: "##2196F3" });
|
", { bizId: businessId, color2: "##2196F3" });
|
||||||
|
|
||||||
|
|
@ -32,18 +32,18 @@ try {
|
||||||
|
|
||||||
// Get current stations
|
// Get current stations
|
||||||
stations = queryExecute("
|
stations = queryExecute("
|
||||||
SELECT StationID, StationName, StationColor, StationSortOrder
|
SELECT ID, Name, Color, SortOrder
|
||||||
FROM Stations
|
FROM Stations
|
||||||
WHERE StationBusinessID = :bizId AND StationIsActive = 1
|
WHERE BusinessID = :bizId AND IsActive = 1
|
||||||
ORDER BY StationSortOrder
|
ORDER BY SortOrder
|
||||||
", { bizId: businessId });
|
", { bizId: businessId });
|
||||||
|
|
||||||
stationArr = [];
|
stationArr = [];
|
||||||
for (s in stations) {
|
for (s in stations) {
|
||||||
arrayAppend(stationArr, {
|
arrayAppend(stationArr, {
|
||||||
"StationID": s.StationID,
|
"StationID": s.ID,
|
||||||
"StationName": s.StationName,
|
"Name": s.Name,
|
||||||
"StationColor": s.StationColor
|
"Color": s.Color
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,67 +9,62 @@ try {
|
||||||
lazyDaisyID = 37;
|
lazyDaisyID = 37;
|
||||||
|
|
||||||
// Get all beacons
|
// Get all beacons
|
||||||
qBeacons = queryExecute("SELECT BeaconID, BeaconUUID FROM Beacons", {}, { datasource: "payfrit" });
|
qBeacons = queryExecute("SELECT ID, UUID FROM Beacons", {}, { datasource: "payfrit" });
|
||||||
response.steps.append("Found " & qBeacons.recordCount & " beacons");
|
response.steps.append("Found " & qBeacons.recordCount & " beacons");
|
||||||
|
|
||||||
// Create service point for Table 1 if it doesn't exist
|
// Create service point for Table 1 if it doesn't exist
|
||||||
qSP = queryExecute("
|
qSP = queryExecute("
|
||||||
SELECT ServicePointID FROM ServicePoints
|
SELECT ID FROM ServicePoints
|
||||||
WHERE ServicePointBusinessID = :bizID AND ServicePointName = 'Table 1'
|
WHERE BusinessID = :bizID AND Name = 'Table 1'
|
||||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qSP.recordCount == 0) {
|
if (qSP.recordCount == 0) {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO ServicePoints (ServicePointBusinessID, ServicePointName, ServicePointTypeID)
|
INSERT INTO ServicePoints (BusinessID, Name)
|
||||||
VALUES (:bizID, 'Table 1', 1)
|
VALUES (:bizID, 'Table 1')
|
||||||
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
", { bizID: lazyDaisyID }, { datasource: "payfrit" });
|
||||||
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
qSP = queryExecute("SELECT LAST_INSERT_ID() as id", {}, { datasource: "payfrit" });
|
||||||
servicePointID = qSP.id;
|
servicePointID = qSP.id;
|
||||||
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
|
response.steps.append("Created service point 'Table 1' (ID: " & servicePointID & ")");
|
||||||
} else {
|
} else {
|
||||||
servicePointID = qSP.ServicePointID;
|
servicePointID = qSP.ID;
|
||||||
response.steps.append("Found existing service point 'Table 1' (ID: " & servicePointID & ")");
|
response.steps.append("Found existing service point 'Table 1' (ID: " & servicePointID & ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map all beacons to Lazy Daisy with Table 1
|
// Assign all beacons to the Table 1 service point
|
||||||
for (i = 1; i <= qBeacons.recordCount; i++) {
|
for (i = 1; i <= qBeacons.recordCount; i++) {
|
||||||
beaconID = qBeacons.BeaconID[i];
|
beaconID = qBeacons.ID[i];
|
||||||
|
|
||||||
// Check if mapping exists
|
// Unassign this beacon from any other service point first
|
||||||
qMap = queryExecute("
|
queryExecute("
|
||||||
SELECT * FROM lt_Beacon_Businesses_ServicePoints WHERE BeaconID = :beaconID
|
UPDATE ServicePoints SET BeaconID = NULL, AssignedByUserID = NULL
|
||||||
|
WHERE BeaconID = :beaconID
|
||||||
", { beaconID: beaconID }, { datasource: "payfrit" });
|
", { beaconID: beaconID }, { datasource: "payfrit" });
|
||||||
|
|
||||||
if (qMap.recordCount == 0) {
|
// Assign beacon to Table 1 service point
|
||||||
queryExecute("
|
queryExecute("
|
||||||
INSERT INTO lt_Beacon_Businesses_ServicePoints (BeaconID, BusinessID, ServicePointID)
|
UPDATE ServicePoints SET BeaconID = :beaconID, AssignedByUserID = 1
|
||||||
VALUES (:beaconID, :bizID, :spID)
|
WHERE ID = :spID AND BusinessID = :bizID
|
||||||
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
||||||
response.steps.append("Created mapping for beacon " & beaconID);
|
response.steps.append("Assigned beacon " & beaconID & " to Table 1");
|
||||||
} else {
|
|
||||||
queryExecute("
|
|
||||||
UPDATE lt_Beacon_Businesses_ServicePoints
|
|
||||||
SET BusinessID = :bizID, ServicePointID = :spID
|
|
||||||
WHERE BeaconID = :beaconID
|
|
||||||
", { beaconID: beaconID, bizID: lazyDaisyID, spID: servicePointID }, { datasource: "payfrit" });
|
|
||||||
response.steps.append("Updated mapping for beacon " & beaconID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get final status
|
// Get final status
|
||||||
qFinal = queryExecute("
|
qFinal = queryExecute("
|
||||||
SELECT lt.BeaconID, b.BeaconUUID, lt.BusinessID, biz.BusinessName, lt.ServicePointID, sp.ServicePointName
|
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
b.Name AS BeaconName, b.UUID, sp.Name AS ServicePointName,
|
||||||
JOIN Beacons b ON b.BeaconID = lt.BeaconID
|
biz.Name AS BusinessName
|
||||||
JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
FROM ServicePoints sp
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
|
JOIN Businesses biz ON biz.ID = sp.BusinessID
|
||||||
|
WHERE sp.BeaconID IS NOT NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
beacons = [];
|
beacons = [];
|
||||||
for (i = 1; i <= qFinal.recordCount; i++) {
|
for (i = 1; i <= qFinal.recordCount; i++) {
|
||||||
arrayAppend(beacons, {
|
arrayAppend(beacons, {
|
||||||
"BeaconID": qFinal.BeaconID[i],
|
"BeaconID": qFinal.BeaconID[i],
|
||||||
"UUID": qFinal.BeaconUUID[i],
|
"UUID": qFinal.UUID[i],
|
||||||
"BusinessID": qFinal.BusinessID[i],
|
"BusinessID": qFinal.BusinessID[i],
|
||||||
"BusinessName": qFinal.BusinessName[i],
|
"BusinessName": qFinal.BusinessName[i],
|
||||||
"ServicePointID": qFinal.ServicePointID[i],
|
"ServicePointID": qFinal.ServicePointID[i],
|
||||||
|
|
|
||||||
|
|
@ -11,32 +11,32 @@
|
||||||
<cfscript>
|
<cfscript>
|
||||||
/**
|
/**
|
||||||
* Setup Modifier Templates system
|
* Setup Modifier Templates system
|
||||||
* 1. Add ItemIsModifierTemplate column to Items
|
* 1. Add IsModifierTemplate column to Items
|
||||||
* 2. Create ItemTemplateLinks table
|
* 2. Create lt_ItemID_TemplateItemID table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
response = { "OK": false, "steps": [] };
|
response = { "OK": false, "steps": [] };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Step 1: Add ItemIsModifierTemplate column if it doesn't exist
|
// Step 1: Add IsModifierTemplate column if it doesn't exist
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
ALTER TABLE Items ADD COLUMN ItemIsModifierTemplate TINYINT(1) DEFAULT 0
|
ALTER TABLE Items ADD COLUMN IsModifierTemplate TINYINT(1) DEFAULT 0
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(response.steps, "Added ItemIsModifierTemplate column");
|
arrayAppend(response.steps, "Added IsModifierTemplate column");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
if (findNoCase("Duplicate column", e.message)) {
|
if (findNoCase("Duplicate column", e.message)) {
|
||||||
arrayAppend(response.steps, "ItemIsModifierTemplate column already exists");
|
arrayAppend(response.steps, "IsModifierTemplate column already exists");
|
||||||
} else {
|
} else {
|
||||||
arrayAppend(response.steps, "Error adding column: " & e.message);
|
arrayAppend(response.steps, "Error adding column: " & e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Create ItemTemplateLinks table if it doesn't exist
|
// Step 2: Create lt_ItemID_TemplateItemID table if it doesn't exist
|
||||||
try {
|
try {
|
||||||
queryExecute("
|
queryExecute("
|
||||||
CREATE TABLE IF NOT EXISTS ItemTemplateLinks (
|
CREATE TABLE IF NOT EXISTS lt_ItemID_TemplateItemID (
|
||||||
LinkID INT AUTO_INCREMENT PRIMARY KEY,
|
ID INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
ItemID INT NOT NULL,
|
ItemID INT NOT NULL,
|
||||||
TemplateItemID INT NOT NULL,
|
TemplateItemID INT NOT NULL,
|
||||||
SortOrder INT DEFAULT 0,
|
SortOrder INT DEFAULT 0,
|
||||||
|
|
@ -45,9 +45,9 @@ try {
|
||||||
INDEX idx_template (TemplateItemID)
|
INDEX idx_template (TemplateItemID)
|
||||||
)
|
)
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
arrayAppend(response.steps, "Created ItemTemplateLinks table");
|
arrayAppend(response.steps, "Created lt_ItemID_TemplateItemID table");
|
||||||
} catch (any e) {
|
} catch (any e) {
|
||||||
arrayAppend(response.steps, "ItemTemplateLinks: " & e.message);
|
arrayAppend(response.steps, "lt_ItemID_TemplateItemID: " & e.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
response["OK"] = true;
|
response["OK"] = true;
|
||||||
|
|
|
||||||
|
|
@ -13,20 +13,20 @@
|
||||||
<cfset queryExecute("
|
<cfset queryExecute("
|
||||||
CREATE TABLE IF NOT EXISTS Stations (
|
CREATE TABLE IF NOT EXISTS Stations (
|
||||||
StationID INT AUTO_INCREMENT PRIMARY KEY,
|
StationID INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
StationBusinessID INT NOT NULL,
|
BusinessID INT NOT NULL,
|
||||||
StationName VARCHAR(100) NOT NULL,
|
Name VARCHAR(100) NOT NULL,
|
||||||
StationColor VARCHAR(7) DEFAULT '##666666',
|
Color VARCHAR(7) DEFAULT '##666666',
|
||||||
StationSortOrder INT DEFAULT 0,
|
SortOrder INT DEFAULT 0,
|
||||||
StationIsActive TINYINT(1) DEFAULT 1,
|
IsActive TINYINT(1) DEFAULT 1,
|
||||||
StationAddedOn DATETIME DEFAULT NOW(),
|
AddedOn DATETIME DEFAULT NOW(),
|
||||||
FOREIGN KEY (StationBusinessID) REFERENCES Businesses(BusinessID)
|
FOREIGN KEY (BusinessID) REFERENCES Businesses(BusinessID)
|
||||||
)
|
)
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<!--- Add ItemStationID column to Items table if it doesn't exist --->
|
<!--- Add StationID column to Items table if it doesn't exist --->
|
||||||
<cftry>
|
<cftry>
|
||||||
<cfset queryExecute("
|
<cfset queryExecute("
|
||||||
ALTER TABLE Items ADD COLUMN ItemStationID INT DEFAULT NULL
|
ALTER TABLE Items ADD COLUMN StationID INT DEFAULT NULL
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
<cfset stationColumnAdded = true>
|
<cfset stationColumnAdded = true>
|
||||||
<cfcatch>
|
<cfcatch>
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
<cfif stationColumnAdded>
|
<cfif stationColumnAdded>
|
||||||
<cftry>
|
<cftry>
|
||||||
<cfset queryExecute("
|
<cfset queryExecute("
|
||||||
ALTER TABLE Items ADD FOREIGN KEY (ItemStationID) REFERENCES Stations(StationID)
|
ALTER TABLE Items ADD FOREIGN KEY (StationID) REFERENCES Stations(StationID)
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
<cfcatch></cfcatch>
|
<cfcatch></cfcatch>
|
||||||
</cftry>
|
</cftry>
|
||||||
|
|
@ -47,12 +47,12 @@
|
||||||
|
|
||||||
<!--- Create some default stations for business 1 (In and Out Burger) if none exist --->
|
<!--- Create some default stations for business 1 (In and Out Burger) if none exist --->
|
||||||
<cfset qCheck = queryExecute("
|
<cfset qCheck = queryExecute("
|
||||||
SELECT COUNT(*) AS cnt FROM Stations WHERE StationBusinessID = 1
|
SELECT COUNT(*) AS cnt FROM Stations WHERE BusinessID = 1
|
||||||
", [], { datasource = "payfrit" })>
|
", [], { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfif qCheck.cnt EQ 0>
|
<cfif qCheck.cnt EQ 0>
|
||||||
<cfset queryExecute("
|
<cfset queryExecute("
|
||||||
INSERT INTO Stations (StationBusinessID, StationName, StationColor, StationSortOrder) VALUES
|
INSERT INTO Stations (BusinessID, Name, Color, SortOrder) VALUES
|
||||||
(1, 'Grill', '##FF5722', 1),
|
(1, 'Grill', '##FF5722', 1),
|
||||||
(1, 'Fry', '##FFC107', 2),
|
(1, 'Fry', '##FFC107', 2),
|
||||||
(1, 'Drinks', '##2196F3', 3),
|
(1, 'Drinks', '##2196F3', 3),
|
||||||
|
|
|
||||||
|
|
@ -3,36 +3,57 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Switch all beacons from one business to another
|
// Switch beacon mapping from one business to another via join table.
|
||||||
|
// Beacons.BusinessID (owner) is NOT touched.
|
||||||
fromBiz = 17; // In-N-Out
|
fromBiz = 17; // In-N-Out
|
||||||
toBiz = 27; // Big Dean's
|
toBiz = 27; // Big Dean's
|
||||||
|
|
||||||
|
// Remove mapping for source business
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE lt_Beacon_Businesses_ServicePoints
|
DELETE FROM lt_BeaconsID_BusinessesID
|
||||||
SET BusinessID = :toBiz
|
WHERE BusinessID = :fromBiz
|
||||||
WHERE BusinessID = :fromBiz
|
", { fromBiz: fromBiz }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
// Add mapping for target business (for beacons owned by source)
|
||||||
|
queryExecute("
|
||||||
|
INSERT INTO lt_BeaconsID_BusinessesID (BeaconID, BusinessID)
|
||||||
|
SELECT ID, :toBiz FROM Beacons WHERE BusinessID = :fromBiz
|
||||||
|
ON DUPLICATE KEY UPDATE ID = ID
|
||||||
", { toBiz: toBiz, fromBiz: fromBiz }, { datasource: "payfrit" });
|
", { toBiz: toBiz, fromBiz: fromBiz }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
// Clear ServicePoints.BeaconID for source business (no longer valid)
|
||||||
|
queryExecute("
|
||||||
|
UPDATE ServicePoints
|
||||||
|
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||||
|
WHERE BusinessID = :fromBiz AND BeaconID IS NOT NULL
|
||||||
|
", { fromBiz: fromBiz }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Get current state
|
// Get current state
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT lt.*, b.BusinessName
|
SELECT sp.ID AS ServicePointID, sp.BeaconID, sp.BusinessID,
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
b.Name AS BeaconName, biz.Name AS BusinessName,
|
||||||
JOIN Businesses b ON b.BusinessID = lt.BusinessID
|
sp.Name AS ServicePointName
|
||||||
|
FROM ServicePoints sp
|
||||||
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
|
JOIN Businesses biz ON biz.ID = sp.BusinessID
|
||||||
|
WHERE sp.BeaconID IS NOT NULL
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
for (row in q) {
|
for (row in q) {
|
||||||
arrayAppend(rows, {
|
arrayAppend(rows, {
|
||||||
"BeaconID": row.BeaconID,
|
"BeaconID": row.BeaconID,
|
||||||
"BusinessID": row.BusinessID,
|
"BeaconName": row.BeaconName,
|
||||||
"BusinessName": row.BusinessName,
|
"BusinessID": row.BusinessID,
|
||||||
"ServicePointID": row.ServicePointID
|
"BusinessName": row.BusinessName,
|
||||||
});
|
"ServicePointID": row.ServicePointID,
|
||||||
|
"ServicePointName": row.ServicePointName
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Switched beacons from BusinessID #fromBiz# to #toBiz#",
|
"MESSAGE": "Switched beacons from BusinessID #fromBiz# to #toBiz#",
|
||||||
"MAPPINGS": rows
|
"MAPPINGS": rows
|
||||||
}));
|
}));
|
||||||
</cfscript>
|
</cfscript>
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
<cfset queryExecute(
|
<cfset queryExecute(
|
||||||
"
|
"
|
||||||
INSERT INTO Tasks (
|
INSERT INTO Tasks (
|
||||||
TaskBusinessID,
|
BusinessID,
|
||||||
TaskOrderID,
|
OrderID,
|
||||||
TaskClaimedByUserID,
|
ClaimedByUserID,
|
||||||
TaskAddedOn
|
CreatedOn
|
||||||
) VALUES (
|
) VALUES (
|
||||||
1,
|
1,
|
||||||
999,
|
999,
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
<cfscript>
|
<cfscript>
|
||||||
qTask = queryExecute("
|
qTask = queryExecute("
|
||||||
SELECT TaskID, TaskTypeID, TaskClaimedByUserID, TaskCompletedOn
|
SELECT ID, TaskTypeID, ClaimedByUserID, CompletedOn
|
||||||
FROM Tasks
|
FROM Tasks
|
||||||
WHERE TaskID = 57
|
WHERE ID = 57
|
||||||
", [], { datasource: "payfrit" });
|
", [], { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"TaskID": qTask.TaskID,
|
"TaskID": qTask.ID,
|
||||||
"TaskTypeID": qTask.TaskTypeID,
|
"TaskTypeID": qTask.TaskTypeID,
|
||||||
"TaskClaimedByUserID": qTask.TaskClaimedByUserID,
|
"ClaimedByUserID": qTask.ClaimedByUserID,
|
||||||
"TaskCompletedOn": qTask.TaskCompletedOn
|
"CompletedOn": qTask.CompletedOn
|
||||||
}));
|
}));
|
||||||
</cfscript>
|
</cfscript>
|
||||||
|
|
|
||||||
|
|
@ -3,50 +3,65 @@
|
||||||
<cfcontent type="application/json; charset=utf-8" reset="true">
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
||||||
|
|
||||||
<cfscript>
|
<cfscript>
|
||||||
// Update Beacon 2 to point to In-N-Out (BusinessID 17)
|
// Update beacon mapping via join table. Owner (Beacons.BusinessID) is NOT changed.
|
||||||
beaconId = 2;
|
beaconId = 2;
|
||||||
|
oldBusinessId = 37; // previous mapping
|
||||||
newBusinessId = 17;
|
newBusinessId = 17;
|
||||||
|
|
||||||
|
// Remove old mapping
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE lt_Beacon_Businesses_ServicePoints
|
DELETE FROM lt_BeaconsID_BusinessesID
|
||||||
SET BusinessID = :newBizId
|
WHERE BeaconID = :beaconId AND BusinessID = :oldBizId
|
||||||
WHERE BeaconID = :beaconId
|
", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" });
|
||||||
", { newBizId: newBusinessId, beaconId: beaconId }, { datasource: "payfrit" });
|
|
||||||
|
// Add new mapping
|
||||||
|
queryExecute("
|
||||||
|
INSERT INTO lt_BeaconsID_BusinessesID (BeaconID, BusinessID)
|
||||||
|
VALUES (:beaconId, :newBizId)
|
||||||
|
ON DUPLICATE KEY UPDATE ID = ID
|
||||||
|
", { beaconId: beaconId, newBizId: newBusinessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
// Clear ServicePoints.BeaconID for old business where this beacon was assigned
|
||||||
|
queryExecute("
|
||||||
|
UPDATE ServicePoints
|
||||||
|
SET BeaconID = NULL, AssignedByUserID = NULL
|
||||||
|
WHERE BeaconID = :beaconId AND BusinessID = :oldBizId
|
||||||
|
", { beaconId: beaconId, oldBizId: oldBusinessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Get current state
|
// Get current state
|
||||||
q = queryExecute("
|
q = queryExecute("
|
||||||
SELECT
|
SELECT
|
||||||
b.BeaconID,
|
b.ID AS BeaconID,
|
||||||
b.BeaconUUID,
|
b.UUID,
|
||||||
b.BeaconName,
|
b.Name AS BeaconName,
|
||||||
lt.BusinessID,
|
b.BusinessID AS BeaconBusinessID,
|
||||||
lt.ServicePointID,
|
sp.ID AS ServicePointID,
|
||||||
biz.BusinessName,
|
sp.Name AS ServicePointName,
|
||||||
sp.ServicePointName
|
sp.BusinessID AS ServicePointBusinessID,
|
||||||
FROM Beacons b
|
biz.Name AS BusinessName
|
||||||
LEFT JOIN lt_Beacon_Businesses_ServicePoints lt ON lt.BeaconID = b.BeaconID
|
FROM Beacons b
|
||||||
LEFT JOIN Businesses biz ON biz.BusinessID = lt.BusinessID
|
LEFT JOIN ServicePoints sp ON sp.BeaconID = b.ID
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
LEFT JOIN Businesses biz ON biz.ID = b.BusinessID
|
||||||
WHERE b.BeaconIsActive = 1
|
WHERE b.IsActive = 1
|
||||||
ORDER BY b.BeaconID
|
ORDER BY b.ID
|
||||||
", {}, { datasource: "payfrit" });
|
", {}, { datasource: "payfrit" });
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
for (row in q) {
|
for (row in q) {
|
||||||
arrayAppend(rows, {
|
arrayAppend(rows, {
|
||||||
"BeaconID": row.BeaconID,
|
"BeaconID": row.BeaconID,
|
||||||
"BeaconUUID": row.BeaconUUID,
|
"UUID": row.UUID,
|
||||||
"BeaconName": row.BeaconName ?: "",
|
"BeaconName": row.BeaconName,
|
||||||
"BusinessID": row.BusinessID ?: 0,
|
"BeaconBusinessID": row.BeaconBusinessID,
|
||||||
"BusinessName": row.BusinessName ?: "",
|
"BusinessName": row.BusinessName,
|
||||||
"ServicePointID": row.ServicePointID ?: 0,
|
"ServicePointID": row.ServicePointID ?: 0,
|
||||||
"ServicePointName": row.ServicePointName ?: ""
|
"ServicePointName": row.ServicePointName ?: ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Updated beacon #beaconId# to BusinessID #newBusinessId#",
|
"MESSAGE": "Updated beacon #beaconId# to BusinessID #newBusinessId#",
|
||||||
"BEACONS": rows
|
"BEACONS": rows
|
||||||
}));
|
}));
|
||||||
</cfscript>
|
</cfscript>
|
||||||
|
|
|
||||||
|
|
@ -6,72 +6,68 @@
|
||||||
// Update Big Dean's business info
|
// Update Big Dean's business info
|
||||||
businessId = 27;
|
businessId = 27;
|
||||||
|
|
||||||
// Big Dean's actual address and hours
|
// Big Dean's actual info
|
||||||
address = "1615 Ocean Front Walk, Santa Monica, CA 90401";
|
|
||||||
phone = "(310) 393-2666";
|
phone = "(310) 393-2666";
|
||||||
hours = "Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm";
|
hours = "Mon-Thu: 11am-10pm, Fri-Sat: 11am-11pm, Sun: 11am-10pm";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First get column names from INFORMATION_SCHEMA
|
// Update phone and hours on Businesses table
|
||||||
cols = queryExecute("
|
|
||||||
SELECT COLUMN_NAME
|
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
|
||||||
WHERE TABLE_SCHEMA = 'payfrit' AND TABLE_NAME = 'Businesses'
|
|
||||||
ORDER BY ORDINAL_POSITION
|
|
||||||
");
|
|
||||||
|
|
||||||
colNames = [];
|
|
||||||
for (c in cols) {
|
|
||||||
arrayAppend(colNames, c.COLUMN_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we have the columns we need
|
|
||||||
hasAddress = arrayFindNoCase(colNames, "BusinessAddress") > 0;
|
|
||||||
hasPhone = arrayFindNoCase(colNames, "BusinessPhone") > 0;
|
|
||||||
hasHours = arrayFindNoCase(colNames, "BusinessHours") > 0;
|
|
||||||
|
|
||||||
// Add columns if missing
|
|
||||||
if (!hasAddress) {
|
|
||||||
queryExecute("ALTER TABLE Businesses ADD COLUMN BusinessAddress VARCHAR(255)");
|
|
||||||
}
|
|
||||||
if (!hasPhone) {
|
|
||||||
queryExecute("ALTER TABLE Businesses ADD COLUMN BusinessPhone VARCHAR(50)");
|
|
||||||
}
|
|
||||||
if (!hasHours) {
|
|
||||||
queryExecute("ALTER TABLE Businesses ADD COLUMN BusinessHours VARCHAR(255)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update with new info
|
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Businesses
|
UPDATE Businesses
|
||||||
SET BusinessAddress = :address,
|
SET Phone = :phone,
|
||||||
BusinessPhone = :phone,
|
Hours = :hours
|
||||||
BusinessHours = :hours
|
WHERE ID = :bizId
|
||||||
WHERE BusinessID = :bizId
|
|
||||||
", {
|
", {
|
||||||
address: address,
|
|
||||||
phone: phone,
|
phone: phone,
|
||||||
hours: hours,
|
hours: hours,
|
||||||
bizId: businessId
|
bizId: businessId
|
||||||
});
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
// Update or insert address in Addresses table
|
||||||
|
qAddr = queryExecute("
|
||||||
|
SELECT ID FROM Addresses
|
||||||
|
WHERE BusinessID = :bizId AND IsDeleted = 0
|
||||||
|
LIMIT 1
|
||||||
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
if (qAddr.recordCount > 0) {
|
||||||
|
queryExecute("
|
||||||
|
UPDATE Addresses
|
||||||
|
SET Line1 = :line1, City = :city, ZIPCode = :zip
|
||||||
|
WHERE ID = :addrId
|
||||||
|
", {
|
||||||
|
line1: "1615 Ocean Front Walk",
|
||||||
|
city: "Santa Monica",
|
||||||
|
zip: "90401",
|
||||||
|
addrId: qAddr.ID
|
||||||
|
}, { datasource: "payfrit" });
|
||||||
|
} else {
|
||||||
|
queryExecute("
|
||||||
|
INSERT INTO Addresses (BusinessID, UserID, AddressTypeID, Line1, City, ZIPCode, AddedOn)
|
||||||
|
VALUES (:bizId, 0, 'business', :line1, :city, :zip, NOW())
|
||||||
|
", {
|
||||||
|
bizId: businessId,
|
||||||
|
line1: "1615 Ocean Front Walk",
|
||||||
|
city: "Santa Monica",
|
||||||
|
zip: "90401"
|
||||||
|
}, { datasource: "payfrit" });
|
||||||
|
}
|
||||||
|
|
||||||
// Get updated record
|
// Get updated record
|
||||||
updated = queryExecute("
|
updated = queryExecute("
|
||||||
SELECT BusinessID, BusinessName, BusinessAddress, BusinessPhone, BusinessHours
|
SELECT ID, Name, Phone, Hours
|
||||||
FROM Businesses
|
FROM Businesses
|
||||||
WHERE BusinessID = :bizId
|
WHERE ID = :bizId
|
||||||
", { bizId: businessId });
|
", { bizId: businessId }, { datasource: "payfrit" });
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"MESSAGE": "Updated Big Dean's info",
|
"MESSAGE": "Updated Big Dean's info",
|
||||||
"COLUMNS_EXISTED": { "address": hasAddress, "phone": hasPhone, "hours": hasHours },
|
|
||||||
"BUSINESS": {
|
"BUSINESS": {
|
||||||
"BusinessID": updated.BusinessID,
|
"BusinessID": updated.ID,
|
||||||
"BusinessName": updated.BusinessName,
|
"Name": updated.Name,
|
||||||
"BusinessAddress": updated.BusinessAddress,
|
"Phone": updated.Phone,
|
||||||
"BusinessPhone": updated.BusinessPhone,
|
"Hours": updated.Hours
|
||||||
"BusinessHours": updated.BusinessHours
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,28 +34,20 @@ if (!structKeyExists(request,"BusinessID") || !isNumeric(request.BusinessID) ||
|
||||||
/* ---------- INPUT ---------- */
|
/* ---------- INPUT ---------- */
|
||||||
data = readJsonBody();
|
data = readJsonBody();
|
||||||
|
|
||||||
if (
|
if (!structKeyExists(data,"ServicePointID") || !isNumeric(data.ServicePointID) || int(data.ServicePointID) LTE 0){
|
||||||
!structKeyExists(data,"lt_Beacon_Businesses_ServicePointID")
|
apiAbort({OK=false,ERROR="missing_ServicePointID"});
|
||||||
|| !isNumeric(data.lt_Beacon_Businesses_ServicePointID)
|
|
||||||
|| int(data.lt_Beacon_Businesses_ServicePointID) LTE 0
|
|
||||||
){
|
|
||||||
apiAbort({OK=false,ERROR="missing_lt_Beacon_Businesses_ServicePointID"});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RelID = int(data.lt_Beacon_Businesses_ServicePointID);
|
ServicePointID = int(data.ServicePointID);
|
||||||
</cfscript>
|
</cfscript>
|
||||||
|
|
||||||
<!--- Confirm the row exists for this BusinessID (and capture what it was) --->
|
<!--- Confirm the service point exists for this business and has a beacon assigned --->
|
||||||
<cfquery name="qFind" datasource="payfrit">
|
<cfquery name="qFind" datasource="payfrit">
|
||||||
SELECT
|
SELECT ID, BeaconID
|
||||||
lt_Beacon_Businesses_ServicePointID,
|
FROM ServicePoints
|
||||||
BeaconID,
|
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
||||||
ServicePointID
|
AND BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
FROM lt_Beacon_Businesses_ServicePoints
|
AND BeaconID IS NOT NULL
|
||||||
WHERE lt_Beacon_Businesses_ServicePointID =
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#RelID#">
|
|
||||||
AND BusinessID =
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
|
|
@ -63,28 +55,28 @@ RelID = int(data.lt_Beacon_Businesses_ServicePointID);
|
||||||
<cfoutput>#serializeJSON({
|
<cfoutput>#serializeJSON({
|
||||||
"OK"=false,
|
"OK"=false,
|
||||||
"ERROR"="not_found",
|
"ERROR"="not_found",
|
||||||
"lt_Beacon_Businesses_ServicePointID"=RelID,
|
"ServicePointID"=ServicePointID,
|
||||||
"BusinessID"=(request.BusinessID & "")
|
"BusinessID"=(request.BusinessID & "")
|
||||||
})#</cfoutput>
|
})#</cfoutput>
|
||||||
<cfabort>
|
<cfabort>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<!--- Delete it --->
|
<cfset removedBeaconID = qFind.BeaconID>
|
||||||
|
|
||||||
|
<!--- Unassign beacon from service point --->
|
||||||
<cfquery datasource="payfrit">
|
<cfquery datasource="payfrit">
|
||||||
DELETE FROM lt_Beacon_Businesses_ServicePoints
|
UPDATE ServicePoints
|
||||||
WHERE lt_Beacon_Businesses_ServicePointID =
|
SET BeaconID = NULL,
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#RelID#">
|
AssignedByUserID = NULL
|
||||||
AND BusinessID =
|
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
AND BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
LIMIT 1
|
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfoutput>#serializeJSON({
|
<cfoutput>#serializeJSON({
|
||||||
"OK"=true,
|
"OK"=true,
|
||||||
"ERROR"="",
|
"ERROR"="",
|
||||||
"ACTION"="deleted",
|
"ACTION"="unassigned",
|
||||||
"lt_Beacon_Businesses_ServicePointID"=RelID,
|
"ServicePointID"=ServicePointID,
|
||||||
"BeaconID"=qFind.BeaconID,
|
"BeaconID"=removedBeaconID,
|
||||||
"ServicePointID"=qFind.ServicePointID,
|
|
||||||
"BusinessID"=(request.BusinessID & "")
|
"BusinessID"=(request.BusinessID & "")
|
||||||
})#</cfoutput>
|
})#</cfoutput>
|
||||||
|
|
|
||||||
|
|
@ -17,32 +17,29 @@ if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) ||
|
||||||
|
|
||||||
<cfquery name="q" datasource="payfrit">
|
<cfquery name="q" datasource="payfrit">
|
||||||
SELECT
|
SELECT
|
||||||
lt.lt_Beacon_Businesses_ServicePointID,
|
sp.ID AS ServicePointID,
|
||||||
lt.BeaconID,
|
sp.BeaconID,
|
||||||
lt.BusinessID,
|
sp.BusinessID,
|
||||||
lt.ServicePointID,
|
sp.AssignedByUserID,
|
||||||
lt.lt_Beacon_Businesses_ServicePointNotes,
|
b.Name AS BeaconName,
|
||||||
b.BeaconName,
|
b.UUID,
|
||||||
b.BeaconUUID,
|
sp.Name AS ServicePointName
|
||||||
sp.ServicePointName
|
FROM ServicePoints sp
|
||||||
FROM lt_Beacon_Businesses_ServicePoints lt
|
JOIN Beacons b ON b.ID = sp.BeaconID
|
||||||
JOIN Beacons b ON b.BeaconID = lt.BeaconID
|
WHERE sp.BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
LEFT JOIN ServicePoints sp ON sp.ServicePointID = lt.ServicePointID
|
AND sp.BeaconID IS NOT NULL
|
||||||
WHERE lt.BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
ORDER BY b.Name, sp.Name
|
||||||
ORDER BY b.BeaconName, sp.ServicePointName
|
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfset assignments = []>
|
<cfset assignments = []>
|
||||||
<cfloop query="q">
|
<cfloop query="q">
|
||||||
<cfset arrayAppend(assignments, {
|
<cfset arrayAppend(assignments, {
|
||||||
"lt_Beacon_Businesses_ServicePointID" = q.lt_Beacon_Businesses_ServicePointID,
|
"ServicePointID" = q.ServicePointID,
|
||||||
"BeaconID" = q.BeaconID,
|
"BeaconID" = q.BeaconID,
|
||||||
"BusinessID" = q.BusinessID,
|
"BusinessID" = q.BusinessID,
|
||||||
"ServicePointID" = q.ServicePointID,
|
|
||||||
"BeaconName" = q.BeaconName,
|
"BeaconName" = q.BeaconName,
|
||||||
"BeaconUUID" = q.BeaconUUID,
|
"UUID" = q.UUID,
|
||||||
"ServicePointName"= q.ServicePointName,
|
"ServicePointName"= q.ServicePointName
|
||||||
"lt_Beacon_Businesses_ServicePointNotes" = q.lt_Beacon_Businesses_ServicePointNotes
|
|
||||||
})>
|
})>
|
||||||
</cfloop>
|
</cfloop>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,6 @@ function readJsonBody(){
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normStr(v){
|
|
||||||
if (isNull(v)) return "";
|
|
||||||
return trim(toString(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------- AUTH CONTEXT ---------- */
|
/* ---------- AUTH CONTEXT ---------- */
|
||||||
if (!structKeyExists(request,"BusinessID") || !isNumeric(request.BusinessID) || request.BusinessID LTE 0){
|
if (!structKeyExists(request,"BusinessID") || !isNumeric(request.BusinessID) || request.BusinessID LTE 0){
|
||||||
apiAbort({OK=false,ERROR="no_business_selected"});
|
apiAbort({OK=false,ERROR="no_business_selected"});
|
||||||
|
|
@ -48,43 +43,45 @@ if (!structKeyExists(data,"ServicePointID") || !isNumeric(data.ServicePointID) |
|
||||||
|
|
||||||
BeaconID = int(data.BeaconID);
|
BeaconID = int(data.BeaconID);
|
||||||
ServicePointID = int(data.ServicePointID);
|
ServicePointID = int(data.ServicePointID);
|
||||||
Notes = "";
|
|
||||||
if (structKeyExists(data,"Notes")){
|
|
||||||
Notes = left(normStr(data.Notes), 255);
|
|
||||||
}
|
|
||||||
</cfscript>
|
</cfscript>
|
||||||
|
|
||||||
<!--- Validate Beacon belongs to Business OR to Business's parent --->
|
<!--- Validate Beacon is allowed for this Business:
|
||||||
|
Owner (Beacons.BusinessID) OR join table (lt_BeaconsID_BusinessesID) OR parent's owner --->
|
||||||
<cfquery name="qBiz" datasource="payfrit">
|
<cfquery name="qBiz" datasource="payfrit">
|
||||||
SELECT BusinessID, BusinessParentBusinessID
|
SELECT ID, ParentBusinessID
|
||||||
FROM Businesses
|
FROM Businesses
|
||||||
WHERE BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfquery name="qB" datasource="payfrit">
|
<cfquery name="qB" datasource="payfrit">
|
||||||
SELECT BeaconID
|
SELECT b.ID
|
||||||
FROM Beacons
|
FROM Beacons b
|
||||||
WHERE BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#BeaconID#">
|
WHERE b.ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#BeaconID#">
|
||||||
AND (
|
AND (
|
||||||
BeaconBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
b.BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
<cfif qBiz.recordCount GT 0 AND len(trim(qBiz.BusinessParentBusinessID)) GT 0 AND isNumeric(qBiz.BusinessParentBusinessID) AND qBiz.BusinessParentBusinessID GT 0>
|
<cfif qBiz.recordCount GT 0 AND len(trim(qBiz.ParentBusinessID)) GT 0 AND isNumeric(qBiz.ParentBusinessID) AND qBiz.ParentBusinessID GT 0>
|
||||||
OR BeaconBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#qBiz.BusinessParentBusinessID#">
|
OR b.BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#qBiz.ParentBusinessID#">
|
||||||
</cfif>
|
</cfif>
|
||||||
|
OR EXISTS (
|
||||||
|
SELECT 1 FROM lt_BeaconsID_BusinessesID lt
|
||||||
|
WHERE lt.BeaconID = b.ID
|
||||||
|
AND lt.BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
|
)
|
||||||
)
|
)
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfif qB.recordCount EQ 0>
|
<cfif qB.recordCount EQ 0>
|
||||||
<cfoutput>#serializeJSON({OK=false,ERROR="beacon_not_found_for_business"})#</cfoutput>
|
<cfoutput>#serializeJSON({OK=false,ERROR="beacon_not_allowed"})#</cfoutput>
|
||||||
<cfabort>
|
<cfabort>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<!--- Validate ServicePoint belongs to Business --->
|
<!--- Validate ServicePoint belongs to Business --->
|
||||||
<cfquery name="qS" datasource="payfrit">
|
<cfquery name="qS" datasource="payfrit">
|
||||||
SELECT ServicePointID
|
SELECT ID
|
||||||
FROM ServicePoints
|
FROM ServicePoints
|
||||||
WHERE ServicePointID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
||||||
AND ServicePointBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
AND BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfif qS.recordCount EQ 0>
|
<cfif qS.recordCount EQ 0>
|
||||||
|
|
@ -92,14 +89,12 @@ if (structKeyExists(data,"Notes")){
|
||||||
<cfabort>
|
<cfabort>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<!--- Check if THIS BUSINESS already has this exact beacon+servicepoint combo --->
|
<!--- Check if this ServicePoint already has this beacon assigned --->
|
||||||
<!--- (Multiple businesses CAN share the same beacon, but one business shouldn't duplicate) --->
|
|
||||||
<cfquery name="qDuplicate" datasource="payfrit">
|
<cfquery name="qDuplicate" datasource="payfrit">
|
||||||
SELECT lt_Beacon_Businesses_ServicePointID
|
SELECT ID
|
||||||
FROM lt_Beacon_Businesses_ServicePoints
|
FROM ServicePoints
|
||||||
WHERE BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
||||||
AND BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#BeaconID#">
|
AND BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#BeaconID#">
|
||||||
AND ServicePointID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</cfquery>
|
</cfquery>
|
||||||
<cfif qDuplicate.recordCount GT 0>
|
<cfif qDuplicate.recordCount GT 0>
|
||||||
|
|
@ -107,31 +102,19 @@ if (structKeyExists(data,"Notes")){
|
||||||
<cfabort>
|
<cfabort>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<!--- INSERT --->
|
<!--- Assign beacon to service point --->
|
||||||
<cfquery datasource="payfrit">
|
<cfquery datasource="payfrit">
|
||||||
INSERT INTO lt_Beacon_Businesses_ServicePoints
|
UPDATE ServicePoints
|
||||||
(BusinessID, BeaconID, ServicePointID,
|
SET BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#BeaconID#">,
|
||||||
lt_Beacon_Businesses_ServicePointAssignedByUserID,
|
AssignedByUserID = <cfqueryparam cfsqltype="cf_sql_integer" value="1">
|
||||||
lt_Beacon_Businesses_ServicePointNotes)
|
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">
|
||||||
VALUES
|
AND BusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">
|
||||||
(
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#request.BusinessID#">,
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#BeaconID#">,
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="#ServicePointID#">,
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_integer" value="1">,
|
|
||||||
<cfqueryparam cfsqltype="cf_sql_varchar" value="#Notes#" null="#(len(Notes) EQ 0)#">
|
|
||||||
)
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
<cfquery name="qID" datasource="payfrit">
|
|
||||||
SELECT LAST_INSERT_ID() AS NewID
|
|
||||||
</cfquery>
|
</cfquery>
|
||||||
|
|
||||||
<cfoutput>#serializeJSON({
|
<cfoutput>#serializeJSON({
|
||||||
"OK"=true,
|
"OK"=true,
|
||||||
"ACTION"="inserted",
|
"ACTION"="assigned",
|
||||||
"lt_Beacon_Businesses_ServicePointID"=qID.NewID,
|
|
||||||
"BeaconID"=BeaconID,
|
|
||||||
"ServicePointID"=ServicePointID,
|
"ServicePointID"=ServicePointID,
|
||||||
|
"BeaconID"=BeaconID,
|
||||||
"BusinessID"=(request.BusinessID & "")
|
"BusinessID"=(request.BusinessID & "")
|
||||||
})#</cfoutput>
|
})#</cfoutput>
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,9 @@ try {
|
||||||
|
|
||||||
// Check if email is already used by another verified account
|
// Check if email is already used by another verified account
|
||||||
qEmailCheck = queryExecute("
|
qEmailCheck = queryExecute("
|
||||||
SELECT UserID FROM Users
|
SELECT ID FROM Users
|
||||||
WHERE UserEmailAddress = :email
|
WHERE EmailAddress = :email
|
||||||
AND UserIsEmailVerified = 1
|
AND IsEmailVerified = 1
|
||||||
AND UserID != :userId
|
AND UserID != :userId
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
", {
|
", {
|
||||||
|
|
@ -87,19 +87,19 @@ try {
|
||||||
|
|
||||||
// Get current user UUID for email confirmation link
|
// Get current user UUID for email confirmation link
|
||||||
qUser = queryExecute("
|
qUser = queryExecute("
|
||||||
SELECT UserUUID FROM Users WHERE UserID = :userId
|
SELECT UUID FROM Users WHERE ID = :userId
|
||||||
", { userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
|
", { userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Update user profile AND mark account as verified/active
|
// Update user profile AND mark account as verified/active
|
||||||
// This completes the signup process
|
// This completes the signup process
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Users
|
UPDATE Users
|
||||||
SET UserFirstName = :firstName,
|
SET FirstName = :firstName,
|
||||||
UserLastName = :lastName,
|
LastName = :lastName,
|
||||||
UserEmailAddress = :email,
|
EmailAddress = :email,
|
||||||
UserIsEmailVerified = 0,
|
IsEmailVerified = 0,
|
||||||
UserIsContactVerified = 1,
|
IsContactVerified = 1,
|
||||||
UserIsActive = 1
|
IsActive = 1
|
||||||
WHERE UserID = :userId
|
WHERE UserID = :userId
|
||||||
", {
|
", {
|
||||||
firstName: { value: firstName, cfsqltype: "cf_sql_varchar" },
|
firstName: { value: firstName, cfsqltype: "cf_sql_varchar" },
|
||||||
|
|
@ -109,7 +109,7 @@ try {
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Send confirmation email (non-blocking - don't fail if mail fails)
|
// Send confirmation email (non-blocking - don't fail if mail fails)
|
||||||
confirmLink = "https://biz.payfrit.com/confirm_email.cfm?UUID=" & qUser.UserUUID;
|
confirmLink = "https://biz.payfrit.com/confirm_email.cfm?UUID=" & qUser.UUID;
|
||||||
emailBody = "
|
emailBody = "
|
||||||
<p>Welcome to Payfrit, #firstName#!</p>
|
<p>Welcome to Payfrit, #firstName#!</p>
|
||||||
<p>Please click the link below to confirm your email address:</p>
|
<p>Please click the link below to confirm your email address:</p>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
{ "username": "...", "password": "..." }
|
{ "username": "...", "password": "..." }
|
||||||
|
|
||||||
OUTPUT (JSON):
|
OUTPUT (JSON):
|
||||||
{ OK:true, ERROR:"", UserID:123, UserFirstName:"...", Token:"..." }
|
{ OK:true, ERROR:"", UserID:123, FirstName:"...", Token:"..." }
|
||||||
|
|
||||||
Uses existing UserTokens table:
|
Uses existing UserTokens table:
|
||||||
TokenID (auto), UserID, Token, CreatedAt (DEFAULT CURRENT_TIMESTAMP)
|
TokenID (auto), UserID, Token, CreatedAt (DEFAULT CURRENT_TIMESTAMP)
|
||||||
|
|
@ -55,16 +55,16 @@ if (!len(username) || !len(password)) {
|
||||||
try {
|
try {
|
||||||
q = queryExecute(
|
q = queryExecute(
|
||||||
"
|
"
|
||||||
SELECT UserID, UserFirstName
|
SELECT ID, FirstName
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE
|
WHERE
|
||||||
(
|
(
|
||||||
(UserEmailAddress = ?) OR
|
(EmailAddress = ?) OR
|
||||||
(UserContactNumber = ?)
|
(ContactNumber = ?)
|
||||||
)
|
)
|
||||||
AND UserPassword = ?
|
AND Password = ?
|
||||||
AND UserIsEmailVerified = 1
|
AND IsEmailVerified = 1
|
||||||
AND UserIsContactVerified > 0
|
AND IsContactVerified > 0
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
",
|
",
|
||||||
[
|
[
|
||||||
|
|
@ -84,7 +84,7 @@ try {
|
||||||
queryExecute(
|
queryExecute(
|
||||||
"INSERT INTO UserTokens (UserID, Token) VALUES (?, ?)",
|
"INSERT INTO UserTokens (UserID, Token) VALUES (?, ?)",
|
||||||
[
|
[
|
||||||
{ value = q.UserID, cfsqltype = "cf_sql_integer" },
|
{ value = q.ID, cfsqltype = "cf_sql_integer" },
|
||||||
{ value = token, cfsqltype = "cf_sql_varchar" }
|
{ value = token, cfsqltype = "cf_sql_varchar" }
|
||||||
],
|
],
|
||||||
{ datasource = "payfrit" }
|
{ datasource = "payfrit" }
|
||||||
|
|
@ -92,15 +92,15 @@ try {
|
||||||
|
|
||||||
// Optional: also set session for browser tools
|
// Optional: also set session for browser tools
|
||||||
lock timeout="15" throwontimeout="yes" type="exclusive" scope="session" {
|
lock timeout="15" throwontimeout="yes" type="exclusive" scope="session" {
|
||||||
session.UserID = q.UserID;
|
session.UserID = q.ID;
|
||||||
}
|
}
|
||||||
request.UserID = q.UserID;
|
request.UserID = q.ID;
|
||||||
|
|
||||||
writeOutput(serializeJSON({
|
writeOutput(serializeJSON({
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"ERROR": "",
|
"ERROR": "",
|
||||||
"UserID": q.UserID,
|
"UserID": q.ID,
|
||||||
"UserFirstName": q.UserFirstName,
|
"FirstName": q.FirstName,
|
||||||
"Token": token
|
"Token": token
|
||||||
}));
|
}));
|
||||||
abort;
|
abort;
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,10 @@ try {
|
||||||
|
|
||||||
// Find verified account with this phone
|
// Find verified account with this phone
|
||||||
qUser = queryExecute("
|
qUser = queryExecute("
|
||||||
SELECT UserID, UserUUID
|
SELECT ID, UUID
|
||||||
FROM Users
|
FROM Users
|
||||||
WHERE UserContactNumber = :phone
|
WHERE ContactNumber = :phone
|
||||||
AND UserIsContactVerified = 1
|
AND IsContactVerified = 1
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
|
||||||
|
|
||||||
|
|
@ -65,14 +65,14 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If user has no UUID (legacy account), generate one
|
// If user has no UUID (legacy account), generate one
|
||||||
userUUID = qUser.UserUUID;
|
userUUID = qUser.UUID;
|
||||||
if (!len(trim(userUUID))) {
|
if (!len(trim(userUUID))) {
|
||||||
userUUID = replace(createUUID(), "-", "", "all");
|
userUUID = replace(createUUID(), "-", "", "all");
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Users SET UserUUID = :uuid WHERE UserID = :userId
|
UPDATE Users SET UUID = :uuid WHERE UserID = :userId
|
||||||
", {
|
", {
|
||||||
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
|
uuid: { value: userUUID, cfsqltype: "cf_sql_varchar" },
|
||||||
userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" }
|
userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,11 +80,11 @@ try {
|
||||||
otp = generateOTP();
|
otp = generateOTP();
|
||||||
queryExecute("
|
queryExecute("
|
||||||
UPDATE Users
|
UPDATE Users
|
||||||
SET UserMobileVerifyCode = :otp
|
SET MobileVerifyCode = :otp
|
||||||
WHERE UserID = :userId
|
WHERE UserID = :userId
|
||||||
", {
|
", {
|
||||||
otp: { value: otp, cfsqltype: "cf_sql_varchar" },
|
otp: { value: otp, cfsqltype: "cf_sql_varchar" },
|
||||||
userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" }
|
userId: { value: qUser.ID, cfsqltype: "cf_sql_integer" }
|
||||||
}, { datasource: "payfrit" });
|
}, { datasource: "payfrit" });
|
||||||
|
|
||||||
// Send OTP via Twilio (skip on dev server)
|
// Send OTP via Twilio (skip on dev server)
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue