Updated all remaining SQL queries to use correct prefixed column names for ServicePoints, Users, Businesses, Addresses, tt_States, tt_Days, and Hours tables across 23 admin/infrastructure API files. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
92 lines
3 KiB
Text
92 lines
3 KiB
Text
<cfsetting showdebugoutput="false">
|
|
<cfcontent type="application/json; charset=utf-8">
|
|
<cfscript>
|
|
/**
|
|
* List completed tasks that admin can rate
|
|
* Returns tasks completed in the last 7 days where admin hasn't yet rated the worker
|
|
*
|
|
* POST: { BusinessID: 123 }
|
|
*/
|
|
|
|
function readJsonBody() {
|
|
var raw = getHttpRequestData().content;
|
|
if (isNull(raw) || len(trim(raw)) == 0) return {};
|
|
try {
|
|
var data = deserializeJSON(raw);
|
|
return isStruct(data) ? data : {};
|
|
} catch (any e) {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
try {
|
|
data = readJsonBody();
|
|
businessID = val(structKeyExists(data, "BusinessID") ? data.BusinessID : 0);
|
|
|
|
if (businessID == 0) {
|
|
writeOutput(serializeJSON({ "OK": false, "ERROR": "missing_business", "MESSAGE": "BusinessID is required." }));
|
|
abort;
|
|
}
|
|
|
|
// Get completed tasks from last 7 days where a worker was assigned
|
|
// and no admin rating exists yet
|
|
qTasks = queryExecute("
|
|
SELECT t.ID, t.Title, t.CompletedOn, t.ClaimedByUserID, t.OrderID,
|
|
u.UserFirstName AS WorkerFirstName, u.UserLastName AS WorkerLastName,
|
|
o.ID, o.UserID,
|
|
cu.UserFirstName AS CustomerFirstName, cu.UserLastName AS CustomerLastName,
|
|
sp.ServicePointName AS Name,
|
|
(SELECT COUNT(*) FROM TaskRatings r
|
|
WHERE r.TaskID = t.ID
|
|
AND r.Direction = 'admin_rates_worker') AS HasAdminRating
|
|
FROM Tasks t
|
|
INNER JOIN Users u ON u.UserID = t.ClaimedByUserID
|
|
LEFT JOIN Orders o ON o.ID = t.OrderID
|
|
LEFT JOIN Users cu ON cu.UserID = o.UserID
|
|
LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.ServicePointID
|
|
WHERE t.BusinessID = :businessID
|
|
AND t.CompletedOn IS NOT NULL
|
|
AND t.CompletedOn > DATE_SUB(NOW(), INTERVAL 7 DAY)
|
|
AND t.ClaimedByUserID > 0
|
|
HAVING HasAdminRating = 0
|
|
ORDER BY t.CompletedOn DESC
|
|
LIMIT 50
|
|
", { businessID: businessID });
|
|
|
|
tasks = [];
|
|
for (row in qTasks) {
|
|
// Build task title
|
|
taskTitle = row.Title;
|
|
if (len(taskTitle) == 0 && row.OrderID > 0) {
|
|
taskTitle = "Order ##" & row.OrderID;
|
|
}
|
|
if (len(taskTitle) == 0) {
|
|
taskTitle = "Task ##" & row.TaskID;
|
|
}
|
|
|
|
arrayAppend(tasks, {
|
|
"TaskID": row.TaskID,
|
|
"Title": taskTitle,
|
|
"CompletedOn": dateTimeFormat(row.CompletedOn, "yyyy-mm-dd HH:nn:ss"),
|
|
"WorkerUserID": row.ClaimedByUserID,
|
|
"WorkerName": trim(row.WorkerFirstName & " " & row.WorkerLastName),
|
|
"CustomerName": len(row.CustomerFirstName) ? trim(row.CustomerFirstName & " " & row.CustomerLastName) : "",
|
|
"Name": row.Name ?: "",
|
|
"OrderID": row.OrderID ?: 0
|
|
});
|
|
}
|
|
|
|
writeOutput(serializeJSON({
|
|
"OK": true,
|
|
"TASKS": tasks
|
|
}));
|
|
|
|
} catch (any e) {
|
|
writeOutput(serializeJSON({
|
|
"OK": false,
|
|
"ERROR": "server_error",
|
|
"MESSAGE": "Error loading tasks",
|
|
"DETAIL": e.message
|
|
}));
|
|
}
|
|
</cfscript>
|