Complete port of all 163 API endpoints from Lucee/CFML to PHP 8.3. Shared helpers in api/helpers.php (DB, auth, request/response, security). PDO prepared statements throughout. Same JSON response shapes as CFML.
103 lines
4.6 KiB
PHP
103 lines
4.6 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../helpers.php';
|
|
runAuth();
|
|
|
|
try {
|
|
$data = readJsonBody();
|
|
$tabID = (int) ($data['TabID'] ?? 0);
|
|
$orderID = (int) ($data['OrderID'] ?? 0);
|
|
$userID = (int) ($data['UserID'] ?? 0);
|
|
|
|
if ($tabID === 0) apiAbort(['OK' => false, 'ERROR' => 'missing_TabID']);
|
|
if ($orderID === 0) apiAbort(['OK' => false, 'ERROR' => 'missing_OrderID']);
|
|
if ($userID === 0) apiAbort(['OK' => false, 'ERROR' => 'missing_UserID']);
|
|
|
|
$qTab = queryOne("
|
|
SELECT t.ID, t.StatusID, t.BusinessID, t.OwnerUserID, t.AuthAmountCents, t.RunningTotalCents,
|
|
t.ApprovalMode, b.TabApprovalRequired, b.TabAutoIncreaseThreshold
|
|
FROM Tabs t JOIN Businesses b ON b.ID = t.BusinessID
|
|
WHERE t.ID = ? LIMIT 1
|
|
", [$tabID]);
|
|
|
|
if (!$qTab) apiAbort(['OK' => false, 'ERROR' => 'tab_not_found']);
|
|
if ((int) $qTab['StatusID'] !== 1) apiAbort(['OK' => false, 'ERROR' => 'tab_not_open']);
|
|
|
|
// Verify user is a member
|
|
$qMember = queryOne("SELECT RoleID FROM TabMembers WHERE TabID = ? AND UserID = ? AND StatusID = 1 LIMIT 1", [$tabID, $userID]);
|
|
if (!$qMember) apiAbort(['OK' => false, 'ERROR' => 'not_a_member']);
|
|
$isOwner = (int) $qMember['RoleID'] === 1;
|
|
|
|
// Verify order
|
|
$qOrder = queryOne("SELECT ID, BusinessID, StatusID, UserID FROM Orders WHERE ID = ? LIMIT 1", [$orderID]);
|
|
if (!$qOrder) apiAbort(['OK' => false, 'ERROR' => 'order_not_found']);
|
|
if ((int) $qOrder['BusinessID'] !== (int) $qTab['BusinessID']) apiAbort(['OK' => false, 'ERROR' => 'wrong_business']);
|
|
if ((int) $qOrder['StatusID'] !== 0) apiAbort(['OK' => false, 'ERROR' => 'order_not_in_cart', 'MESSAGE' => 'Order must be in cart state.']);
|
|
|
|
// Calculate order subtotal + tax
|
|
$qTotals = queryOne("
|
|
SELECT COALESCE(SUM(oli.Price * oli.Quantity), 0) AS Subtotal
|
|
FROM OrderLineItems oli WHERE oli.OrderID = ? AND oli.IsDeleted = 0
|
|
", [$orderID]);
|
|
|
|
$subtotal = (float) $qTotals['Subtotal'];
|
|
$subtotalCents = round($subtotal * 100);
|
|
|
|
$qBizTax = queryOne("SELECT TaxRate FROM Businesses WHERE ID = ?", [$qTab['BusinessID']]);
|
|
$taxRate = (float) ($qBizTax['TaxRate'] ?? 0);
|
|
$taxCents = round($subtotalCents * $taxRate);
|
|
|
|
// Determine approval status
|
|
$approvalMode = $qTab['ApprovalMode'] ?? '';
|
|
$requiresApproval = (is_numeric($approvalMode) && $approvalMode !== '')
|
|
? (int) $approvalMode === 1
|
|
: (int) ($qTab['TabApprovalRequired'] ?? 0) === 1;
|
|
$approvalStatus = (!$isOwner && $requiresApproval) ? 'pending' : 'approved';
|
|
|
|
// Check authorization limit for auto-approved orders
|
|
$newRunning = (int) $qTab['RunningTotalCents'];
|
|
if ($approvalStatus === 'approved') {
|
|
$newRunning = (int) $qTab['RunningTotalCents'] + $subtotalCents + $taxCents;
|
|
if ($newRunning > (int) $qTab['AuthAmountCents']) {
|
|
apiAbort([
|
|
'OK' => false, 'ERROR' => 'exceeds_authorization',
|
|
'MESSAGE' => 'This order would exceed your tab authorization. Please increase your authorization first.',
|
|
'RUNNING_TOTAL_CENTS' => (int) $qTab['RunningTotalCents'],
|
|
'ORDER_CENTS' => $subtotalCents + $taxCents,
|
|
'AUTH_AMOUNT_CENTS' => (int) $qTab['AuthAmountCents'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Link order to tab
|
|
queryTimed("UPDATE Orders SET TabID = ? WHERE ID = ?", [$tabID, $orderID]);
|
|
|
|
queryTimed("
|
|
INSERT INTO TabOrders (TabID, OrderID, UserID, ApprovalStatus, SubtotalCents, TaxCents, AddedOn)
|
|
VALUES (?, ?, ?, ?, ?, ?, NOW())
|
|
ON DUPLICATE KEY UPDATE ApprovalStatus = VALUES(ApprovalStatus), SubtotalCents = VALUES(SubtotalCents), TaxCents = VALUES(TaxCents)
|
|
", [$tabID, $orderID, $userID, $approvalStatus, $subtotalCents, $taxCents]);
|
|
|
|
if ($approvalStatus === 'approved') {
|
|
queryTimed("UPDATE Tabs SET RunningTotalCents = ?, LastActivityOn = NOW() WHERE ID = ?", [$newRunning, $tabID]);
|
|
}
|
|
|
|
// Check auto-increase threshold
|
|
$needsIncrease = false;
|
|
$threshold = (float) ($qTab['TabAutoIncreaseThreshold'] ?? 0);
|
|
if ($threshold > 0 && (int) $qTab['AuthAmountCents'] > 0) {
|
|
$needsIncrease = ($newRunning / (int) $qTab['AuthAmountCents']) >= $threshold;
|
|
}
|
|
|
|
jsonResponse([
|
|
'OK' => true,
|
|
'APPROVAL_STATUS' => $approvalStatus,
|
|
'RUNNING_TOTAL_CENTS' => $newRunning,
|
|
'AUTH_REMAINING_CENTS' => (int) $qTab['AuthAmountCents'] - $newRunning,
|
|
'NEEDS_INCREASE' => $needsIncrease,
|
|
'ORDER_SUBTOTAL_CENTS' => $subtotalCents,
|
|
'ORDER_TAX_CENTS' => $taxCents,
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => $e->getMessage()]);
|
|
}
|