Add role-aware cash routing and backend improvements
Staff cash goes to worker payout ledger, admin/manager cash deletes pending payout and reverses withholding. Add RoleID to myBusinesses response. Various order and webhook improvements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9c09e18833
commit
b9755a1e72
10 changed files with 197 additions and 79 deletions
|
|
@ -136,8 +136,8 @@ try {
|
||||||
// Send via SMS
|
// Send via SMS
|
||||||
try {
|
try {
|
||||||
if (structKeyExists(application, "twilioObj")) {
|
if (structKeyExists(application, "twilioObj")) {
|
||||||
smsMessage = "Your Payfrit code is: " & code;
|
smsMessage = "Your Payfrit login code is: " & code & ". It expires in 10 minutes.";
|
||||||
application.twilioObj.sendSMS(to=qUser.ContactNumber, message=smsMessage);
|
application.twilioObj.sendSMS(recipientNumber="+1" & qUser.ContactNumber, messageBody=smsMessage);
|
||||||
}
|
}
|
||||||
} catch (any smsErr) {
|
} catch (any smsErr) {
|
||||||
writeLog(file="otp_errors", text="SMS send failed for user #userId#: #smsErr.message#");
|
writeLog(file="otp_errors", text="SMS send failed for user #userId#: #smsErr.message#");
|
||||||
|
|
|
||||||
|
|
@ -37,24 +37,26 @@
|
||||||
<cfset qOrder = queryTimed(
|
<cfset qOrder = queryTimed(
|
||||||
"
|
"
|
||||||
SELECT
|
SELECT
|
||||||
ID,
|
o.ID,
|
||||||
UUID,
|
o.UUID,
|
||||||
UserID,
|
o.UserID,
|
||||||
BusinessID,
|
o.BusinessID,
|
||||||
DeliveryMultiplier,
|
o.DeliveryMultiplier,
|
||||||
OrderTypeID,
|
o.OrderTypeID,
|
||||||
DeliveryFee,
|
o.DeliveryFee,
|
||||||
StatusID,
|
o.StatusID,
|
||||||
AddressID,
|
o.AddressID,
|
||||||
PaymentID,
|
o.PaymentID,
|
||||||
PaymentStatus,
|
o.PaymentStatus,
|
||||||
Remarks,
|
o.Remarks,
|
||||||
AddedOn,
|
o.AddedOn,
|
||||||
LastEditedOn,
|
o.LastEditedOn,
|
||||||
SubmittedOn,
|
o.SubmittedOn,
|
||||||
ServicePointID
|
o.ServicePointID,
|
||||||
FROM Orders
|
sp.Name AS ServicePointName
|
||||||
WHERE ID = ?
|
FROM Orders o
|
||||||
|
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||||
|
WHERE o.ID = ?
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
",
|
",
|
||||||
[ { value = OrderID, cfsqltype = "cf_sql_integer" } ],
|
[ { value = OrderID, cfsqltype = "cf_sql_integer" } ],
|
||||||
|
|
@ -161,7 +163,8 @@
|
||||||
"AddedOn": qOrder.AddedOn,
|
"AddedOn": qOrder.AddedOn,
|
||||||
"LastEditedOn": qOrder.LastEditedOn,
|
"LastEditedOn": qOrder.LastEditedOn,
|
||||||
"SubmittedOn": qOrder.SubmittedOn,
|
"SubmittedOn": qOrder.SubmittedOn,
|
||||||
"ServicePointID": val(qOrder.ServicePointID)
|
"ServicePointID": val(qOrder.ServicePointID),
|
||||||
|
"ServicePointName": qOrder.ServicePointName ?: ""
|
||||||
},
|
},
|
||||||
"ORDERLINEITEMS": rows
|
"ORDERLINEITEMS": rows
|
||||||
})>
|
})>
|
||||||
|
|
|
||||||
|
|
@ -33,28 +33,30 @@
|
||||||
<cfset var qOrder = queryTimed(
|
<cfset var qOrder = queryTimed(
|
||||||
"
|
"
|
||||||
SELECT
|
SELECT
|
||||||
ID,
|
o.ID,
|
||||||
UUID,
|
o.UUID,
|
||||||
UserID,
|
o.UserID,
|
||||||
BusinessID,
|
o.BusinessID,
|
||||||
DeliveryMultiplier,
|
o.DeliveryMultiplier,
|
||||||
OrderTypeID,
|
o.OrderTypeID,
|
||||||
DeliveryFee,
|
o.DeliveryFee,
|
||||||
StatusID,
|
o.StatusID,
|
||||||
AddressID,
|
o.AddressID,
|
||||||
PaymentID,
|
o.PaymentID,
|
||||||
Remarks,
|
o.Remarks,
|
||||||
AddedOn,
|
o.AddedOn,
|
||||||
LastEditedOn,
|
o.LastEditedOn,
|
||||||
SubmittedOn,
|
o.SubmittedOn,
|
||||||
ServicePointID,
|
o.ServicePointID,
|
||||||
GrantID,
|
sp.Name AS ServicePointName,
|
||||||
GrantOwnerBusinessID,
|
o.GrantID,
|
||||||
GrantEconomicsType,
|
o.GrantOwnerBusinessID,
|
||||||
GrantEconomicsValue,
|
o.GrantEconomicsType,
|
||||||
TabID
|
o.GrantEconomicsValue,
|
||||||
FROM Orders
|
o.TabID
|
||||||
WHERE ID = ?
|
FROM Orders o
|
||||||
|
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||||
|
WHERE o.ID = ?
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
",
|
",
|
||||||
[ { value = arguments.OrderID, cfsqltype = "cf_sql_integer" } ],
|
[ { value = arguments.OrderID, cfsqltype = "cf_sql_integer" } ],
|
||||||
|
|
@ -94,6 +96,7 @@
|
||||||
"LastEditedOn": qOrder.LastEditedOn,
|
"LastEditedOn": qOrder.LastEditedOn,
|
||||||
"SubmittedOn": qOrder.SubmittedOn,
|
"SubmittedOn": qOrder.SubmittedOn,
|
||||||
"ServicePointID": val(qOrder.ServicePointID),
|
"ServicePointID": val(qOrder.ServicePointID),
|
||||||
|
"ServicePointName": qOrder.ServicePointName ?: "",
|
||||||
"GrantID": val(qOrder.GrantID),
|
"GrantID": val(qOrder.GrantID),
|
||||||
"GrantOwnerBusinessID": val(qOrder.GrantOwnerBusinessID),
|
"GrantOwnerBusinessID": val(qOrder.GrantOwnerBusinessID),
|
||||||
"GrantEconomicsType": qOrder.GrantEconomicsType ?: "",
|
"GrantEconomicsType": qOrder.GrantEconomicsType ?: "",
|
||||||
|
|
@ -172,6 +175,16 @@
|
||||||
})>
|
})>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
|
<!--- Require ServicePointID for now (delivery/takeaway not yet supported) --->
|
||||||
|
<cfif ServicePointID LTE 0>
|
||||||
|
<cfset apiAbort({
|
||||||
|
"OK": false,
|
||||||
|
"ERROR": "missing_service_point",
|
||||||
|
"MESSAGE": "ServicePointID is required. Please scan a table beacon.",
|
||||||
|
"DETAIL": ""
|
||||||
|
})>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
<!--- OrderTypeID can be 0 (undecided) for delivery/takeaway flow, or 1 for dine-in --->
|
<!--- OrderTypeID can be 0 (undecided) for delivery/takeaway flow, or 1 for dine-in --->
|
||||||
<cfif OrderTypeID LT 0 OR OrderTypeID GT 3>
|
<cfif OrderTypeID LT 0 OR OrderTypeID GT 3>
|
||||||
<cfset apiAbort({
|
<cfset apiAbort({
|
||||||
|
|
|
||||||
|
|
@ -191,9 +191,11 @@
|
||||||
o.LastEditedOn,
|
o.LastEditedOn,
|
||||||
o.SubmittedOn,
|
o.SubmittedOn,
|
||||||
o.ServicePointID,
|
o.ServicePointID,
|
||||||
|
sp.Name AS ServicePointName,
|
||||||
COALESCE(b.DeliveryFlatFee, 0) AS BusinessDeliveryFee
|
COALESCE(b.DeliveryFlatFee, 0) AS BusinessDeliveryFee
|
||||||
FROM Orders o
|
FROM Orders o
|
||||||
LEFT JOIN Businesses b ON b.ID = o.BusinessID
|
LEFT JOIN Businesses b ON b.ID = o.BusinessID
|
||||||
|
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||||
WHERE o.ID = ?
|
WHERE o.ID = ?
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
",
|
",
|
||||||
|
|
@ -221,6 +223,7 @@
|
||||||
"LastEditedOn": qOrder.LastEditedOn,
|
"LastEditedOn": qOrder.LastEditedOn,
|
||||||
"SubmittedOn": qOrder.SubmittedOn,
|
"SubmittedOn": qOrder.SubmittedOn,
|
||||||
"ServicePointID": val(qOrder.ServicePointID),
|
"ServicePointID": val(qOrder.ServicePointID),
|
||||||
|
"ServicePointName": qOrder.ServicePointName ?: "",
|
||||||
"BusinessDeliveryFee": val(qOrder.BusinessDeliveryFee)
|
"BusinessDeliveryFee": val(qOrder.BusinessDeliveryFee)
|
||||||
}>
|
}>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,23 +33,25 @@
|
||||||
<cfset var qOrder = queryTimed(
|
<cfset var qOrder = queryTimed(
|
||||||
"
|
"
|
||||||
SELECT
|
SELECT
|
||||||
ID,
|
o.ID,
|
||||||
UUID,
|
o.UUID,
|
||||||
UserID,
|
o.UserID,
|
||||||
BusinessID,
|
o.BusinessID,
|
||||||
DeliveryMultiplier,
|
o.DeliveryMultiplier,
|
||||||
OrderTypeID,
|
o.OrderTypeID,
|
||||||
DeliveryFee,
|
o.DeliveryFee,
|
||||||
StatusID,
|
o.StatusID,
|
||||||
AddressID,
|
o.AddressID,
|
||||||
PaymentID,
|
o.PaymentID,
|
||||||
Remarks,
|
o.Remarks,
|
||||||
AddedOn,
|
o.AddedOn,
|
||||||
LastEditedOn,
|
o.LastEditedOn,
|
||||||
SubmittedOn,
|
o.SubmittedOn,
|
||||||
ServicePointID
|
o.ServicePointID,
|
||||||
FROM Orders
|
sp.Name AS ServicePointName
|
||||||
WHERE ID = ?
|
FROM Orders o
|
||||||
|
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||||
|
WHERE o.ID = ?
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
",
|
",
|
||||||
[ { value = arguments.OrderID, cfsqltype = "cf_sql_integer" } ],
|
[ { value = arguments.OrderID, cfsqltype = "cf_sql_integer" } ],
|
||||||
|
|
@ -84,7 +86,8 @@
|
||||||
"AddedOn": qOrder.AddedOn,
|
"AddedOn": qOrder.AddedOn,
|
||||||
"LastEditedOn": qOrder.LastEditedOn,
|
"LastEditedOn": qOrder.LastEditedOn,
|
||||||
"SubmittedOn": qOrder.SubmittedOn,
|
"SubmittedOn": qOrder.SubmittedOn,
|
||||||
"ServicePointID": val(qOrder.ServicePointID)
|
"ServicePointID": val(qOrder.ServicePointID),
|
||||||
|
"ServicePointName": qOrder.ServicePointName ?: ""
|
||||||
}>
|
}>
|
||||||
|
|
||||||
<cfset var qLI = queryTimed(
|
<cfset var qLI = queryTimed(
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ try {
|
||||||
|
|
||||||
if (orderID > 0) {
|
if (orderID > 0) {
|
||||||
// Update order status to paid/submitted (status 1)
|
// Update order status to paid/submitted (status 1)
|
||||||
// Note: Task is created later when order status changes to Ready (3) in updateStatus.cfm
|
|
||||||
queryTimed("
|
queryTimed("
|
||||||
UPDATE Orders
|
UPDATE Orders
|
||||||
SET PaymentStatus = 'paid',
|
SET PaymentStatus = 'paid',
|
||||||
|
|
@ -134,6 +133,34 @@ try {
|
||||||
", { amount: val(qBalOrder.BalanceApplied), userID: val(qBalOrder.UserID) });
|
", { amount: val(qBalOrder.BalanceApplied), userID: val(qBalOrder.UserID) });
|
||||||
writeLog(file="stripe_webhooks", text="Order #orderID# balance deducted: $#qBalOrder.BalanceApplied#");
|
writeLog(file="stripe_webhooks", text="Order #orderID# balance deducted: $#qBalOrder.BalanceApplied#");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create kitchen task for the order
|
||||||
|
qOrder = queryTimed("
|
||||||
|
SELECT o.BusinessID, o.ServicePointID, sp.Name AS ServicePointName
|
||||||
|
FROM Orders o
|
||||||
|
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
|
||||||
|
WHERE o.ID = :orderID
|
||||||
|
", { orderID: orderID });
|
||||||
|
|
||||||
|
if (qOrder.recordCount > 0) {
|
||||||
|
tableName = len(trim(qOrder.ServicePointName)) ? qOrder.ServicePointName : "Table";
|
||||||
|
taskTitle = "Prepare Order ##" & orderID & " for " & tableName;
|
||||||
|
|
||||||
|
queryTimed("
|
||||||
|
INSERT INTO Tasks (
|
||||||
|
BusinessID, OrderID, ServicePointID, Title, CreatedOn, ClaimedByUserID
|
||||||
|
) VALUES (
|
||||||
|
:businessID, :orderID, :servicePointID, :title, NOW(), 0
|
||||||
|
)
|
||||||
|
", {
|
||||||
|
businessID: qOrder.BusinessID,
|
||||||
|
orderID: orderID,
|
||||||
|
servicePointID: val(qOrder.ServicePointID),
|
||||||
|
title: taskTitle
|
||||||
|
});
|
||||||
|
|
||||||
|
writeLog(file="stripe_webhooks", text="Kitchen task created for order #orderID#");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === WORKER PAYOUT TRANSFER ===
|
// === WORKER PAYOUT TRANSFER ===
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,16 @@ try {
|
||||||
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "BusinessID is required" });
|
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "BusinessID is required" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If servicePointID not provided but orderID is, look it up from the order
|
||||||
|
if (servicePointID == 0 && orderID > 0) {
|
||||||
|
qOrderSP = queryExecute("
|
||||||
|
SELECT ServicePointID FROM Orders WHERE ID = :orderID
|
||||||
|
", { orderID: { value: orderID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
|
||||||
|
if (qOrderSP.recordCount && val(qOrderSP.ServicePointID) > 0) {
|
||||||
|
servicePointID = val(qOrderSP.ServicePointID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (servicePointID == 0) {
|
if (servicePointID == 0) {
|
||||||
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "ServicePointID is required" });
|
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "ServicePointID is required" });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,26 @@
|
||||||
<!--- === CASH TRANSACTION PROCESSING === --->
|
<!--- === CASH TRANSACTION PROCESSING === --->
|
||||||
<cfset cashProcessed = false>
|
<cfset cashProcessed = false>
|
||||||
<cfif isCashTask AND CashReceivedCents GT 0 AND qTask.OrderID GT 0 AND NOT CancelOrder>
|
<cfif isCashTask AND CashReceivedCents GT 0 AND qTask.OrderID GT 0 AND NOT CancelOrder>
|
||||||
|
<!--- Look up worker's role for this business (1=Staff, 2=Manager, 3=Admin) --->
|
||||||
|
<cfset workerRoleID = 1>
|
||||||
|
<cfif workerUserID_for_payout GT 0>
|
||||||
|
<cfset qWorkerRole = queryTimed("
|
||||||
|
SELECT COALESCE(RoleID, 1) AS RoleID
|
||||||
|
FROM Employees
|
||||||
|
WHERE UserID = ? AND BusinessID = ? AND IsActive = b'1'
|
||||||
|
ORDER BY RoleID DESC
|
||||||
|
LIMIT 1
|
||||||
|
", [
|
||||||
|
{ value = workerUserID_for_payout, cfsqltype = "cf_sql_integer" },
|
||||||
|
{ value = qTask.BusinessID, cfsqltype = "cf_sql_integer" }
|
||||||
|
], { datasource = "payfrit" })>
|
||||||
|
<cfif qWorkerRole.recordCount GT 0>
|
||||||
|
<cfset workerRoleID = val(qWorkerRole.RoleID)>
|
||||||
|
</cfif>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfset isAdmin = (workerRoleID GTE 2)>
|
||||||
|
|
||||||
<!--- Credit customer change to their balance --->
|
<!--- Credit customer change to their balance --->
|
||||||
<cfif changeCents GT 0 AND customerUserID GT 0>
|
<cfif changeCents GT 0 AND customerUserID GT 0>
|
||||||
<cfset queryTimed("
|
<cfset queryTimed("
|
||||||
|
|
@ -318,20 +338,46 @@
|
||||||
|
|
||||||
<!--- Debit for physical cash received --->
|
<!--- Debit for physical cash received --->
|
||||||
<!--- Staff: debit the worker (they pocketed the cash) --->
|
<!--- Staff: debit the worker (they pocketed the cash) --->
|
||||||
<!--- Admin/Manager: debit the business owner (restaurant has the cash) --->
|
<!--- Admin/Manager: cash goes to the business, delete worker's pending payout --->
|
||||||
<cfset cashDebitUserID = isAdminRole ? businessOwnerUserID : workerUserID_for_payout>
|
<cfif isAdmin>
|
||||||
<cfif cashDebitUserID GT 0>
|
<!--- Admin/Manager: cash goes to the business, delete worker's pending payout --->
|
||||||
<cfset queryTimed("
|
<!--- Remove the task earning ledger entry (admin hands cash to register) --->
|
||||||
INSERT INTO WorkPayoutLedgers
|
<cfif workerUserID_for_payout GT 0>
|
||||||
(UserID, TaskID, GrossEarningsCents, ActivationWithheldCents, NetTransferCents, Status)
|
<cfset queryTimed("
|
||||||
VALUES
|
DELETE FROM WorkPayoutLedgers
|
||||||
(:userID, :taskID, :gross, 0, :net, 'cash_debit')
|
WHERE TaskID = :taskID AND UserID = :userID AND Status = 'pending_charge'
|
||||||
", {
|
", {
|
||||||
userID: cashDebitUserID,
|
taskID: TaskID,
|
||||||
taskID: TaskID,
|
userID: workerUserID_for_payout
|
||||||
gross: -CashReceivedCents,
|
}, { datasource = "payfrit" })>
|
||||||
net: -CashReceivedCents
|
|
||||||
}, { datasource = "payfrit" })>
|
<!--- Reverse activation withholding if any was applied --->
|
||||||
|
<cfif ledgerCreated AND activationWithhold GT 0>
|
||||||
|
<cfset queryTimed("
|
||||||
|
UPDATE Users
|
||||||
|
SET ActivationBalanceCents = GREATEST(0, ActivationBalanceCents - :withhold)
|
||||||
|
WHERE ID = :userID
|
||||||
|
", {
|
||||||
|
withhold: activationWithhold,
|
||||||
|
userID: workerUserID_for_payout
|
||||||
|
}, { datasource = "payfrit" })>
|
||||||
|
</cfif>
|
||||||
|
</cfif>
|
||||||
|
<cfelse>
|
||||||
|
<!--- Staff: cash stays in their pocket, debit their payout balance --->
|
||||||
|
<cfif workerUserID_for_payout GT 0>
|
||||||
|
<cfset queryTimed("
|
||||||
|
INSERT INTO WorkPayoutLedgers
|
||||||
|
(UserID, TaskID, GrossEarningsCents, ActivationWithheldCents, NetTransferCents, Status)
|
||||||
|
VALUES
|
||||||
|
(:userID, :taskID, :gross, 0, :net, 'cash_debit')
|
||||||
|
", {
|
||||||
|
userID: workerUserID_for_payout,
|
||||||
|
taskID: TaskID,
|
||||||
|
gross: -CashReceivedCents,
|
||||||
|
net: -CashReceivedCents
|
||||||
|
}, { datasource = "payfrit" })>
|
||||||
|
</cfif>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<!--- Log transaction in Payments table --->
|
<!--- Log transaction in Payments table --->
|
||||||
|
|
@ -345,7 +391,7 @@
|
||||||
:sentBy, :receivedBy, :orderID,
|
:sentBy, :receivedBy, :orderID,
|
||||||
0, 0, :cashAmount,
|
0, 0, :cashAmount,
|
||||||
:payfritCut, 0, :bizFee,
|
:payfritCut, 0, :bizFee,
|
||||||
'Cash payment', NOW()
|
:remark, NOW()
|
||||||
)
|
)
|
||||||
", {
|
", {
|
||||||
sentBy: customerUserID,
|
sentBy: customerUserID,
|
||||||
|
|
@ -353,7 +399,8 @@
|
||||||
orderID: qTask.OrderID,
|
orderID: qTask.OrderID,
|
||||||
cashAmount: CashReceivedCents / 100,
|
cashAmount: CashReceivedCents / 100,
|
||||||
payfritCut: payfritRevenueCents / 100,
|
payfritCut: payfritRevenueCents / 100,
|
||||||
bizFee: round(businessFeeDollars * 100) / 100
|
bizFee: round(businessFeeDollars * 100) / 100,
|
||||||
|
remark: isAdmin ? "Cash payment (collected by manager)" : "Cash payment"
|
||||||
}, { datasource = "payfrit" })>
|
}, { datasource = "payfrit" })>
|
||||||
|
|
||||||
<cfset cashProcessed = true>
|
<cfset cashProcessed = true>
|
||||||
|
|
@ -430,6 +477,8 @@
|
||||||
<cfset response["BalanceApplied"] = numberFormat(balanceAppliedCents / 100, "0.00")>
|
<cfset response["BalanceApplied"] = numberFormat(balanceAppliedCents / 100, "0.00")>
|
||||||
<cfset response["CashOwed"] = numberFormat(cashOwedCents / 100, "0.00")>
|
<cfset response["CashOwed"] = numberFormat(cashOwedCents / 100, "0.00")>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
<cfset response["CashRoutedTo"] = isAdmin ? "business" : "worker">
|
||||||
|
<cfset response["WorkerRoleID"] = workerRoleID>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<cfset apiAbort(response)>
|
<cfset apiAbort(response)>
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,16 @@ try {
|
||||||
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "BusinessID is required" });
|
apiAbort({ "OK": false, "ERROR": "missing_params", "MESSAGE": "BusinessID is required" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If servicePointID not provided but orderID is, look it up from the order
|
||||||
|
if (servicePointID == 0 && orderID > 0) {
|
||||||
|
qOrderSP = queryTimed("
|
||||||
|
SELECT ServicePointID FROM Orders WHERE ID = :orderID
|
||||||
|
", { orderID: { value: orderID, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" });
|
||||||
|
if (qOrderSP.recordCount && val(qOrderSP.ServicePointID) > 0) {
|
||||||
|
servicePointID = val(qOrderSP.ServicePointID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Look up "Chat With Staff" task type for this business
|
// Look up "Chat With Staff" task type for this business
|
||||||
ttQuery = queryTimed("
|
ttQuery = queryTimed("
|
||||||
SELECT ID FROM tt_TaskTypes
|
SELECT ID FROM tt_TaskTypes
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
e.BusinessID,
|
e.BusinessID,
|
||||||
MIN(e.StatusID) AS StatusID,
|
MIN(e.StatusID) AS StatusID,
|
||||||
MAX(e.IsActive) AS IsActive,
|
MAX(e.IsActive) AS IsActive,
|
||||||
MAX(e.RoleID) AS RoleID,
|
MAX(COALESCE(e.RoleID, 1)) AS RoleID,
|
||||||
b.Name AS Name,
|
b.Name AS Name,
|
||||||
(SELECT COUNT(*) FROM Tasks t WHERE t.BusinessID = e.BusinessID AND t.ClaimedByUserID = 0 AND t.CompletedOn IS NULL) AS PendingTaskCount,
|
(SELECT COUNT(*) FROM Tasks t WHERE t.BusinessID = e.BusinessID AND t.ClaimedByUserID = 0 AND t.CompletedOn IS NULL) AS PendingTaskCount,
|
||||||
(SELECT COUNT(*) FROM Tasks t WHERE t.BusinessID = e.BusinessID AND t.ClaimedByUserID = ? AND t.CompletedOn IS NULL) AS ActiveTaskCount
|
(SELECT COUNT(*) FROM Tasks t WHERE t.BusinessID = e.BusinessID AND t.ClaimedByUserID = ? AND t.CompletedOn IS NULL) AS ActiveTaskCount
|
||||||
|
|
|
||||||
Reference in a new issue