payfrit-api/api/tasks/getDetails.php
John Mizerek aa986507fd Remove all Lucee references — uploads now live under /opt/payfrit-api
- Moved uploads from Lucee webroot to /opt/payfrit-api/uploads/
- Updated nginx on both dev and biz to alias /uploads/ to new path
- Replaced luceeWebroot() with uploadsRoot() helper
- Temp files now use /opt/payfrit-api/temp/
- No more /opt/lucee or /var/www/biz.payfrit.com references

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 22:26:52 -07:00

182 lines
6.8 KiB
PHP

<?php
require_once __DIR__ . '/../helpers.php';
runAuth();
/**
* Get full task details including order, customer, beacon info
* POST: { TaskID: int }
*/
$data = readJsonBody();
$taskID = (int) ($data['TaskID'] ?? 0);
if ($taskID <= 0) {
apiAbort(['OK' => false, 'ERROR' => 'missing_params', 'MESSAGE' => 'TaskID is required.']);
}
try {
$qTask = queryOne("
SELECT
t.ID AS TaskID,
t.BusinessID,
t.OrderID,
t.TaskTypeID,
t.CreatedOn,
t.ClaimedByUserID,
t.ServicePointID AS TaskServicePointID,
tt.Name AS TaskTypeName,
tt.Color AS TaskTypeColor,
o.ID AS OID,
o.UUID AS OrderUUID,
o.UserID AS OrderUserID,
o.OrderTypeID,
o.StatusID AS OrderStatusID,
o.ServicePointID AS OrderServicePointID,
o.Remarks,
o.SubmittedOn,
o.TipAmount,
o.DeliveryFee,
b.TaxRate,
b.PayfritFee,
COALESCE(sp.Name, tsp.Name) AS ServicePointName,
COALESCE(sp.TypeID, tsp.TypeID) AS ServicePointTypeID,
COALESCE(sp.ID, tsp.ID) AS ServicePointID,
u.ID AS CustomerUserID,
u.FirstName,
u.LastName,
u.ContactNumber,
u.ImageExtension AS CustomerImageExtension
FROM Tasks t
LEFT JOIN tt_TaskTypes tt ON tt.ID = t.TaskTypeID
LEFT JOIN Orders o ON o.ID = t.OrderID
LEFT JOIN Businesses b ON b.ID = t.BusinessID
LEFT JOIN ServicePoints sp ON sp.ID = o.ServicePointID
LEFT JOIN ServicePoints tsp ON tsp.ID = t.ServicePointID
LEFT JOIN Users u ON u.ID = COALESCE(NULLIF(o.UserID, 0), NULLIF(t.UserID, 0))
WHERE t.ID = ?
", [$taskID]);
if (!$qTask) {
apiAbort(['OK' => false, 'ERROR' => 'not_found', 'MESSAGE' => 'Task not found.']);
}
$taskTitle = ((int) ($qTask['OrderID'] ?? 0) > 0)
? "Order #" . $qTask['OrderID']
: "Task #" . $qTask['TaskID'];
// Check if user photo file exists
$customerPhotoUrl = '';
$customerUserID = (int) ($qTask['CustomerUserID'] ?? 0);
if ($customerUserID > 0) {
foreach (['jpg', 'png', 'PNG'] as $ext) {
$checkPath = uploadsRoot() . '/users/' . $customerUserID . '.' . $ext;
if (file_exists($checkPath)) {
$customerPhotoUrl = baseUrl() . '/uploads/users/' . $customerUserID . '.' . $ext;
break;
}
}
}
$result = [
'TaskID' => (int) $qTask['TaskID'],
'TaskBusinessID' => (int) $qTask['BusinessID'],
'TaskTypeID' => (int) ($qTask['TaskTypeID'] ?? 1),
'TaskTypeName' => $qTask['TaskTypeName'] ?? '',
'TaskTypeColor' => !empty(trim($qTask['TaskTypeColor'] ?? '')) ? $qTask['TaskTypeColor'] : '#9C27B0',
'TaskTitle' => $taskTitle,
'TaskCreatedOn' => toISO8601($qTask['CreatedOn']),
'TaskStatusID' => (int) $qTask['ClaimedByUserID'] > 0 ? 1 : 0,
'OrderID' => (int) ($qTask['OrderID'] ?? 0),
'OrderRemarks' => $qTask['Remarks'] ?? '',
'OrderSubmittedOn' => toISO8601($qTask['SubmittedOn'] ?? ''),
'OrderTotal' => 0,
'OrderTotalCents' => 0,
'ServicePointID' => (int) ($qTask['ServicePointID'] ?? 0),
'ServicePointName' => $qTask['ServicePointName'] ?? '',
'ServicePointTypeID' => (int) ($qTask['ServicePointTypeID'] ?? 0),
'DeliveryAddress' => '',
'DeliveryLat' => 0,
'DeliveryLng' => 0,
'CustomerUserID' => $customerUserID,
'CustomerFirstName' => $qTask['FirstName'] ?? '',
'CustomerLastName' => $qTask['LastName'] ?? '',
'CustomerPhone' => $qTask['ContactNumber'] ?? '',
'CustomerPhotoUrl' => $customerPhotoUrl,
'BeaconUUID' => '',
'BeaconMajor' => 0,
'BeaconMinor' => 0,
'LineItems' => [],
'TableMembers' => [],
];
// Get beacon sharding info
$spID = (int) ($qTask['ServicePointID'] ?? 0);
if ($spID > 0) {
$qBeacon = queryOne("
SELECT bs.UUID AS ShardUUID, b.BeaconMajor, sp.BeaconMinor
FROM ServicePoints sp
JOIN Businesses b ON b.ID = sp.BusinessID
JOIN BeaconShards bs ON bs.ID = b.BeaconShardID
WHERE sp.ID = ? AND bs.IsActive = 1
LIMIT 1
", [$spID]);
if ($qBeacon) {
$result['BeaconUUID'] = $qBeacon['ShardUUID'];
$result['BeaconMajor'] = (int) $qBeacon['BeaconMajor'];
$result['BeaconMinor'] = (int) $qBeacon['BeaconMinor'];
}
}
// Get order line items if there's an order
if ((int) ($qTask['OrderID'] ?? 0) > 0) {
$qLineItems = queryTimed("
SELECT
oli.ID AS OrderLineItemID,
oli.ParentOrderLineItemID,
oli.ItemID,
oli.Price AS LineItemPrice,
oli.Quantity,
oli.Remark,
i.ID AS IID,
i.Name AS ItemName,
i.ParentItemID,
i.Price AS ItemPrice,
i.IsCheckedByDefault
FROM OrderLineItems oli
INNER JOIN Items i ON i.ID = oli.ItemID
WHERE oli.OrderID = ? AND oli.IsDeleted = 0
ORDER BY oli.ID
", [$qTask['OrderID']]);
$subtotal = 0;
foreach ($qLineItems as $li) {
$subtotal += (float) $li['LineItemPrice'] * (int) $li['Quantity'];
$result['LineItems'][] = [
'LineItemID' => (int) $li['OrderLineItemID'],
'ParentLineItemID' => (int) $li['ParentOrderLineItemID'],
'ItemID' => (int) $li['ItemID'],
'ItemName' => $li['ItemName'],
'ItemPrice' => (float) $li['LineItemPrice'],
'Quantity' => (int) $li['Quantity'],
'Remark' => $li['Remark'] ?? '',
'IsModifier' => (int) $li['ParentOrderLineItemID'] > 0,
];
}
// Calculate order total
$taxAmount = $subtotal * (float) ($qTask['TaxRate'] ?? 0);
$tipAmount = (float) ($qTask['TipAmount'] ?? 0);
$deliveryFee = ((int) ($qTask['OrderTypeID'] ?? 0) === 3) ? (float) ($qTask['DeliveryFee'] ?? 0) : 0;
$feeRate = (is_numeric($qTask['PayfritFee'] ?? null) && (float) $qTask['PayfritFee'] > 0)
? (float) $qTask['PayfritFee'] : 0.05;
$platformFee = $subtotal * $feeRate;
$totalAmount = $subtotal + $taxAmount + $tipAmount + $deliveryFee + $platformFee;
$result['OrderTotal'] = number_format($totalAmount, 2, '.', '');
$result['OrderTotalCents'] = (int) round($totalAmount * 100);
}
jsonResponse(['OK' => true, 'ERROR' => '', 'TASK' => $result]);
} catch (Exception $e) {
jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => 'Error loading task details', 'DETAIL' => $e->getMessage()]);
}