Enforce roles on admin endpoints and return real status codes

- users, SMTP and batch-lock endpoints are owner/admin only
- engines answer 400/403/404/409/500 instead of 200 with an error body;
  database errors no longer leak to the client
This commit is contained in:
Thanakorn
2026-09-24 14:53:40 +07:00
parent 73c680e844
commit 8705be0d1b
35 changed files with 131 additions and 4 deletions
@@ -12,6 +12,7 @@ $discount = (float)($data['discount'] ?? 0);
$shipping_fee = (float)($data['shipping_fee'] ?? 0);
if (!$request_id) {
http_response_code(400);
$answer['message'] = 'Purchase request ID is required.';
exit(json_encode($answer));
}
@@ -21,6 +22,7 @@ $prm = new PurchaseRequestManager($pdo2, $company_id);
// Load PR — must be Approved
$pr = $prm->getById($request_id);
if (!$pr || (int)$pr['status'] !== 2) {
http_response_code(400);
$answer['message'] = 'Purchase request not found or not in Approved status.';
exit(json_encode($answer));
}
@@ -30,17 +32,20 @@ if (!$contact_id) {
$contact_id = (int)($pr['contact_id'] ?? 0);
}
if (!$contact_id) {
http_response_code(400);
$answer['message'] = 'Set a Preferred Supplier on this purchase request before converting it to a PO.';
exit(json_encode($answer));
}
$pr_items = $pr['items'];
if (empty($pr_items)) {
http_response_code(400);
$answer['message'] = 'Purchase request has no items.';
exit(json_encode($answer));
}
if ((float)$pr['total_remaining'] <= 0.000001) {
http_response_code(400);
$answer['message'] = 'Purchase request is already fully converted.';
exit(json_encode($answer));
}
@@ -72,6 +77,7 @@ foreach ($convert_items as $ci) {
if ($qty <= 0) continue;
if (!isset($pr_by_id[$item_id])) {
http_response_code(400);
$answer['message'] = "Item #{$item_id} not found in this purchase request.";
exit(json_encode($answer));
}
@@ -81,6 +87,7 @@ foreach ($convert_items as $ci) {
if ($qty - $remaining > 0.000001) {
$name = $pi['product_name'] ?: $pi['product_sku'];
http_response_code(400);
$answer['message'] = "Cannot convert {$qty} for \"{$name}\": only {$remaining} remaining.";
exit(json_encode($answer));
}
@@ -105,6 +112,7 @@ foreach ($convert_items as $ci) {
}
if (empty($po_items)) {
http_response_code(400);
$answer['message'] = 'No valid items to convert.';
exit(json_encode($answer));
}