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:
parent
c5ebb24b39
commit
d4cc4b4a6c
2 changed files with 166 additions and 61 deletions
|
|
@ -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 ?: ""
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
51
hud/hud.js
51
hud/hud.js
|
|
@ -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();
|
||||||
|
|
|
||||||
Reference in a new issue