payfrit-works/api/orders/getDetail.cfm
John Mizerek 8092384702 Add team endpoint and chat features for portal
- Add /api/portal/team.cfm for employee listing
- Add chat endpoints (getMessages, sendMessage, markRead, getActiveChat)
- Add OTP authentication endpoints
- Add address management endpoints (delete, setDefault, states)
- Add task completion and chat task endpoints
- Update Application.cfm allowlist

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:03:55 -08:00

229 lines
6.9 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<!--- Force recompile: 2026-01-09 --->
<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.OrderTypeID,
o.OrderRemarks,
o.OrderAddedOn,
o.OrderLastEditedOn,
o.OrderSubmittedOn,
u.UserFirstName,
u.UserLastName,
u.UserContactNumber,
u.UserEmailAddress,
sp.ServicePointName,
sp.ServicePointTypeID,
b.BusinessName
FROM Orders o
LEFT JOIN Users u ON u.UserID = o.OrderUserID
LEFT JOIN ServicePoints sp ON sp.ServicePointID = o.OrderServicePointID
LEFT JOIN Businesses b ON b.BusinessID = o.OrderBusinessID
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 (excluding deleted items)
qItems = queryExecute("
SELECT
oli.OrderLineItemID,
oli.OrderLineItemItemID,
oli.OrderLineItemParentOrderLineItemID,
oli.OrderLineItemQuantity,
oli.OrderLineItemPrice,
oli.OrderLineItemRemark,
i.ItemName,
i.ItemPrice,
i.ItemIsCheckedByDefault
FROM OrderLineItems oli
INNER JOIN Items i ON i.ItemID = oli.OrderLineItemItemID
WHERE oli.OrderLineItemOrderID = :orderID
AND oli.OrderLineItemIsDeleted = 0
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,
"IsDefault": (row.ItemIsCheckedByDefault == 1),
"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);
}
}
// Calculate subtotal from root line items
subtotal = 0;
for (item in lineItems) {
itemTotal = item.UnitPrice * item.Quantity;
// Add modifier prices
for (mod in item.Modifiers) {
itemTotal += mod.UnitPrice * mod.Quantity;
}
subtotal += itemTotal;
}
// Calculate tax (assume 8.75% if not stored)
taxRate = 0.0875;
tax = subtotal * taxRate;
// Look up tip from Payments table if exists
tip = 0;
try {
qPayment = queryExecute("
SELECT PaymentTipAmount
FROM Payments
WHERE PaymentOrderID = :orderID
LIMIT 1
", { orderID: orderID });
if (qPayment.recordCount > 0 && !isNull(qPayment.PaymentTipAmount)) {
tip = qPayment.PaymentTipAmount;
}
} catch (any e) {
// Payments table may not exist or have this column, ignore
}
// Calculate total
total = subtotal + tax + tip;
// Build response
order = {
"OrderID": qOrder.OrderID,
"BusinessID": qOrder.OrderBusinessID,
"BusinessName": qOrder.BusinessName ?: "",
"Status": qOrder.OrderStatusID,
"StatusText": getStatusText(qOrder.OrderStatusID),
"OrderTypeID": qOrder.OrderTypeID ?: 0,
"OrderTypeName": getOrderTypeName(qOrder.OrderTypeID ?: 0),
"Subtotal": subtotal,
"Tax": tax,
"Tip": tip,
"Total": total,
"Notes": qOrder.OrderRemarks,
"CreatedOn": dateTimeFormat(qOrder.OrderAddedOn, "yyyy-mm-dd HH:nn:ss"),
"SubmittedOn": len(qOrder.OrderSubmittedOn) ? dateTimeFormat(qOrder.OrderSubmittedOn, "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 functions
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";
}
}
function getOrderTypeName(orderType) {
switch (orderType) {
case 1: return "Dine-in";
case 2: return "Takeaway";
case 3: return "Delivery";
default: return "Unknown";
}
}
</cfscript>