payfrit-api/api/tabs/addOrder.php
John Mizerek 1f81d98c52 Initial PHP API migration from CFML
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.
2026-03-14 14:26:59 -07:00

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()]);
}