API Improvements: - api/businesses/get.cfm: Fetch address from Addresses table, hours from Hours table - api/tasks/getDetails.cfm: Add CustomerPhone field from UserContactNumber - api/orders/getDetail.cfm: New endpoint for order details with line items - api/Application.cfm: Add new admin endpoints to public allowlist Admin Tools: - api/admin/beaconStatus.cfm: View all beacon-to-business mappings - api/admin/updateBeaconMapping.cfm: Change beacon business assignment - api/admin/setupBigDeansInfo.cfm: Set Big Dean's address and hours - api/admin/listTables.cfm: List all database tables - api/admin/describeTable.cfm: Get table structure and sample data - api/admin/randomizePrices.cfm: Randomize item prices for testing - Various Big Dean's debug/update scripts Portal Enhancements: - Enhanced CSS styling for portal pages - Improved portal.js functionality 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
172 lines
5.1 KiB
Text
172 lines
5.1 KiB
Text
<cfsetting showdebugoutput="false">
|
|
<cfsetting enablecfoutputonly="true">
|
|
<cfcontent type="application/json; charset=utf-8" reset="true">
|
|
<cfheader name="Cache-Control" value="no-store">
|
|
|
|
<cfscript>
|
|
/**
|
|
* Get Order Detail
|
|
* Returns full order info including line items and customer details
|
|
*
|
|
* GET: ?OrderID=123
|
|
* POST: { OrderID: 123 }
|
|
*/
|
|
|
|
response = { "OK": false };
|
|
|
|
try {
|
|
// Get OrderID from request
|
|
orderID = 0;
|
|
|
|
// Check URL params
|
|
if (structKeyExists(url, "OrderID")) {
|
|
orderID = val(url.OrderID);
|
|
}
|
|
|
|
// Check POST body
|
|
if (orderID == 0) {
|
|
requestBody = toString(getHttpRequestData().content);
|
|
if (len(requestBody)) {
|
|
requestData = deserializeJSON(requestBody);
|
|
if (structKeyExists(requestData, "OrderID")) {
|
|
orderID = val(requestData.OrderID);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (orderID == 0) {
|
|
response["ERROR"] = "missing_order_id";
|
|
response["MESSAGE"] = "OrderID is required";
|
|
writeOutput(serializeJSON(response));
|
|
abort;
|
|
}
|
|
|
|
// Get order details
|
|
qOrder = queryExecute("
|
|
SELECT
|
|
o.OrderID,
|
|
o.OrderBusinessID,
|
|
o.OrderUserID,
|
|
o.OrderServicePointID,
|
|
o.OrderStatusID,
|
|
o.OrderRemarks,
|
|
o.OrderAddedOn,
|
|
o.OrderLastEditedOn,
|
|
o.OrderTipAmount,
|
|
u.UserFirstName,
|
|
u.UserLastName,
|
|
u.UserContactNumber,
|
|
u.UserEmailAddress,
|
|
sp.ServicePointName,
|
|
sp.ServicePointTypeID
|
|
FROM Orders o
|
|
LEFT JOIN Users u ON u.UserID = o.OrderUserID
|
|
LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
|
|
WHERE o.OrderID = :orderID
|
|
", { orderID: orderID });
|
|
|
|
if (qOrder.recordCount == 0) {
|
|
response["ERROR"] = "order_not_found";
|
|
response["MESSAGE"] = "Order not found";
|
|
writeOutput(serializeJSON(response));
|
|
abort;
|
|
}
|
|
|
|
// Get line items
|
|
qItems = queryExecute("
|
|
SELECT
|
|
oli.OrderLineItemID,
|
|
oli.OrderLineItemItemID,
|
|
oli.OrderLineItemParentOrderLineItemID,
|
|
oli.OrderLineItemQuantity,
|
|
oli.OrderLineItemPrice,
|
|
oli.OrderLineItemRemark,
|
|
i.ItemName,
|
|
i.ItemPrice
|
|
FROM OrderLineItems oli
|
|
INNER JOIN Items i ON i.ItemID = oli.OrderLineItemItemID
|
|
WHERE oli.OrderLineItemOrderID = :orderID
|
|
ORDER BY oli.OrderLineItemID
|
|
", { orderID: orderID });
|
|
|
|
// Build line items array with parent-child structure
|
|
lineItems = [];
|
|
itemsById = {};
|
|
|
|
// First pass: create all items
|
|
for (row in qItems) {
|
|
item = {
|
|
"LineItemID": row.OrderLineItemID,
|
|
"ItemID": row.OrderLineItemItemID,
|
|
"ParentLineItemID": row.OrderLineItemParentOrderLineItemID,
|
|
"ItemName": row.ItemName,
|
|
"Quantity": row.OrderLineItemQuantity,
|
|
"UnitPrice": row.OrderLineItemPrice,
|
|
"Remarks": row.OrderLineItemRemark,
|
|
"Modifiers": []
|
|
};
|
|
itemsById[row.OrderLineItemID] = item;
|
|
}
|
|
|
|
// Second pass: build hierarchy
|
|
for (row in qItems) {
|
|
item = itemsById[row.OrderLineItemID];
|
|
parentID = row.OrderLineItemParentOrderLineItemID;
|
|
|
|
if (parentID > 0 && structKeyExists(itemsById, parentID)) {
|
|
// This is a modifier - add to parent
|
|
arrayAppend(itemsById[parentID].Modifiers, item);
|
|
} else {
|
|
// This is a top-level item
|
|
arrayAppend(lineItems, item);
|
|
}
|
|
}
|
|
|
|
// Build response
|
|
order = {
|
|
"OrderID": qOrder.OrderID,
|
|
"BusinessID": qOrder.OrderBusinessID,
|
|
"Status": qOrder.OrderStatusID,
|
|
"StatusText": getStatusText(qOrder.OrderStatusID),
|
|
"Tip": qOrder.OrderTipAmount,
|
|
"Notes": qOrder.OrderRemarks,
|
|
"CreatedOn": dateTimeFormat(qOrder.OrderAddedOn, "yyyy-mm-dd HH:nn:ss"),
|
|
"UpdatedOn": len(qOrder.OrderLastEditedOn) ? dateTimeFormat(qOrder.OrderLastEditedOn, "yyyy-mm-dd HH:nn:ss") : "",
|
|
"Customer": {
|
|
"UserID": qOrder.OrderUserID,
|
|
"FirstName": qOrder.UserFirstName,
|
|
"LastName": qOrder.UserLastName,
|
|
"Phone": qOrder.UserContactNumber,
|
|
"Email": qOrder.UserEmailAddress
|
|
},
|
|
"ServicePoint": {
|
|
"ServicePointID": qOrder.OrderServicePointID,
|
|
"Name": qOrder.ServicePointName,
|
|
"TypeID": qOrder.ServicePointTypeID
|
|
},
|
|
"LineItems": lineItems
|
|
};
|
|
|
|
response["OK"] = true;
|
|
response["ORDER"] = order;
|
|
|
|
} catch (any e) {
|
|
response["ERROR"] = "server_error";
|
|
response["MESSAGE"] = e.message;
|
|
}
|
|
|
|
writeOutput(serializeJSON(response));
|
|
|
|
// Helper function
|
|
function getStatusText(status) {
|
|
switch (status) {
|
|
case 0: return "Cart";
|
|
case 1: return "Submitted";
|
|
case 2: return "In Progress";
|
|
case 3: return "Ready";
|
|
case 4: return "Completed";
|
|
case 5: return "Cancelled";
|
|
default: return "Unknown";
|
|
}
|
|
}
|
|
</cfscript>
|