Fix service bell task creation for Android app

- Update create.cfm to handle TaskTypeID for service bell tasks
- Update hud.js to prefer TaskTypeColor/TaskTypeName for task display

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-01-27 20:52:59 -08:00
parent c5ebb24b39
commit d4cc4b4a6c
2 changed files with 166 additions and 61 deletions

View file

@ -1,6 +1,7 @@
<cfscript> <cfscript>
// Create a task (e.g., photo task for menu item) // Create a task (service bell request or photo task)
// Input: BusinessID, ItemID, TaskType, Instructions, PYTReward // Input for service bell: BusinessID, ServicePointID, TaskTypeID, Message
// Input for photo task: BusinessID, ItemID, TaskType, Instructions, PYTReward
// Output: { OK: true, TASK_ID: ... } // Output: { OK: true, TASK_ID: ... }
response = { "OK": false }; response = { "OK": false };
@ -13,71 +14,129 @@ try {
jsonData = deserializeJSON(requestBody); jsonData = deserializeJSON(requestBody);
businessID = val(jsonData.BusinessID ?: 0); businessID = val(jsonData.BusinessID ?: 0);
itemID = val(jsonData.ItemID ?: 0);
taskType = jsonData.TaskType ?: "employee_photo";
instructions = jsonData.Instructions ?: "";
pytReward = val(jsonData.PYTReward ?: 0);
if (businessID == 0) { if (businessID == 0) {
throw("BusinessID is required"); throw("BusinessID is required");
} }
// Get item info if itemID provided // Check if this is a service bell request (has TaskTypeID)
itemName = ""; taskTypeID = val(jsonData.TaskTypeID ?: 0);
if (itemID > 0) {
itemQuery = queryExecute(" if (taskTypeID > 0) {
SELECT ItemName FROM Items WHERE ItemID = :itemID // Service bell task
", { itemID: itemID }); servicePointID = val(jsonData.ServicePointID ?: 0);
if (itemQuery.recordCount) { orderID = val(jsonData.OrderID ?: 0);
itemName = itemQuery.ItemName; userID = val(jsonData.UserID ?: 0);
message = jsonData.Message ?: "";
// Get task type info for display
taskTypeQuery = queryExecute("
SELECT tt_TaskTypeName, tt_TaskTypeColor, tt_TaskTypeIcon
FROM tt_TaskTypes
WHERE tt_TaskTypeID = :taskTypeID
", { taskTypeID: taskTypeID }, { datasource: "payfrit" });
taskTitle = message;
if (taskTypeQuery.recordCount && len(taskTypeQuery.tt_TaskTypeName)) {
taskTitle = taskTypeQuery.tt_TaskTypeName;
} }
}
// Create task description // Use message as details
taskDescription = ""; taskDetails = message;
switch(taskType) {
case "employee_photo":
taskDescription = "Take a photo of: " & itemName;
break;
case "user_photo":
taskDescription = "Submit a photo of " & itemName & " to earn " & pytReward & " PYT";
break;
default:
taskDescription = instructions;
}
// Insert task // Insert service bell task
queryExecute(" queryExecute("
INSERT INTO Tasks ( INSERT INTO Tasks (
TaskBusinessID, TaskBusinessID,
TaskItemID, TaskTypeID,
TaskType, TaskCategoryID,
TaskDescription, TaskOrderID,
TaskInstructions, TaskTitle,
TaskPYTReward, TaskDetails,
TaskStatus, TaskAddedOn,
TaskCreatedOn TaskClaimedByUserID
) VALUES ( ) VALUES (
:businessID, :businessID,
:itemID, :taskTypeID,
:taskType, 0,
:description, :orderID,
:instructions, :taskTitle,
:pytReward, :taskDetails,
'pending', NOW(),
NOW() 0
) )
", { ", {
businessID: businessID, businessID: businessID,
itemID: itemID, taskTypeID: taskTypeID,
taskType: taskType, orderID: orderID,
description: taskDescription, taskTitle: taskTitle,
instructions: instructions, taskDetails: taskDetails
pytReward: pytReward }, { datasource: "payfrit" });
});
} else {
// Legacy photo task
itemID = val(jsonData.ItemID ?: 0);
taskType = jsonData.TaskType ?: "employee_photo";
instructions = jsonData.Instructions ?: "";
pytReward = val(jsonData.PYTReward ?: 0);
// Get item info if itemID provided
itemName = "";
if (itemID > 0) {
itemQuery = queryExecute("
SELECT ItemName FROM Items WHERE ItemID = :itemID
", { itemID: itemID });
if (itemQuery.recordCount) {
itemName = itemQuery.ItemName;
}
}
// Create task description
taskDescription = "";
switch(taskType) {
case "employee_photo":
taskDescription = "Take a photo of: " & itemName;
break;
case "user_photo":
taskDescription = "Submit a photo of " & itemName & " to earn " & pytReward & " PYT";
break;
default:
taskDescription = instructions;
}
// Insert legacy task
queryExecute("
INSERT INTO Tasks (
TaskBusinessID,
TaskItemID,
TaskType,
TaskDescription,
TaskInstructions,
TaskPYTReward,
TaskStatus,
TaskCreatedOn
) VALUES (
:businessID,
:itemID,
:taskType,
:description,
:instructions,
:pytReward,
'pending',
NOW()
)
", {
businessID: businessID,
itemID: itemID,
taskType: taskType,
description: taskDescription,
instructions: instructions,
pytReward: pytReward
});
}
// Get the new task ID // Get the new task ID
result = queryExecute("SELECT LAST_INSERT_ID() as newID"); result = queryExecute("SELECT LAST_INSERT_ID() as newID", {}, { datasource: "payfrit" });
taskID = result.newID; taskID = result.newID;
response = { response = {
@ -89,7 +148,8 @@ try {
} catch (any e) { } catch (any e) {
response = { response = {
"OK": false, "OK": false,
"ERROR": e.message "ERROR": e.message,
"DETAIL": e.detail ?: ""
}; };
} }

View file

@ -225,17 +225,23 @@ const HUD = {
return `${mins}:${String(secs).padStart(2, '0')}`; return `${mins}:${String(secs).padStart(2, '0')}`;
}, },
// Get category name - use task's category name if available, fall back to hardcoded // Get category/task type name - prefer task type for service bell tasks
getCategoryName(task) { getCategoryName(task) {
if (task && task.TaskTypeName && task.TaskTypeName.length > 0) {
return task.TaskTypeName;
}
if (task && task.TaskCategoryName) { if (task && task.TaskCategoryName) {
return task.TaskCategoryName; return task.TaskCategoryName;
} }
return this.categories[task?.TaskCategoryID]?.name || 'Task'; return this.categories[task?.TaskCategoryID]?.name || 'Task';
}, },
// Get category color - use task's category color if available, fall back to hardcoded // Get category/task type color - prefer task type color for service bell tasks
getCategoryColor(task) { getCategoryColor(task) {
if (task && task.TaskCategoryColor) { if (task && task.TaskTypeColor && task.TaskTypeColor.length > 0 && task.TaskTypeColor !== '#9C27B0') {
return task.TaskTypeColor;
}
if (task && task.TaskCategoryColor && task.TaskCategoryColor !== '#888888') {
return task.TaskCategoryColor; return task.TaskCategoryColor;
} }
return this.categories[task?.TaskCategoryID]?.color || '#888888'; return this.categories[task?.TaskCategoryID]?.color || '#888888';
@ -361,6 +367,45 @@ function acceptTask() {
HUD.acceptTask(); HUD.acceptTask();
} }
function toggleFullscreen() {
const body = document.body;
const isMaximized = body.classList.contains('maximized');
if (isMaximized) {
// Restore normal view
body.classList.remove('maximized');
// Also exit native fullscreen if active
if (document.fullscreenElement) {
document.exitFullscreen().catch(() => {});
} else if (document.webkitFullscreenElement) {
document.webkitExitFullscreen();
}
} else {
// Maximize - hide header for more space
body.classList.add('maximized');
// Also try native fullscreen on desktop
const elem = document.documentElement;
if (elem.requestFullscreen) {
elem.requestFullscreen().catch(() => {});
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
}
}
}
// Exit maximized mode when exiting native fullscreen
document.addEventListener('fullscreenchange', () => {
if (!document.fullscreenElement) {
document.body.classList.remove('maximized');
}
});
document.addEventListener('webkitfullscreenchange', () => {
if (!document.webkitFullscreenElement) {
document.body.classList.remove('maximized');
}
});
// Initialize on load // Initialize on load
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
HUD.init(); HUD.init();