38929-vm/api/checkout.php
2026-03-03 13:15:17 +00:00

170 lines
7.9 KiB
PHP

<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/whatsapp.php';
session_start();
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
$order_id = $input['order_id'] ?? null;
$customer_id = $input['customer_id'] ?: null;
$items = $input['items'] ?? [];
$vat_total = (float)($input['vat_total'] ?? 0);
$total_price = (float)($input['total_price'] ?? 0);
$payment_method = $input['payment_method'] ?? null;
$points_to_redeem = (float)($input['points_to_redeem'] ?? 0);
$branch_id = $_SESSION['branch_id'];
$user_id = $_SESSION['user_id'];
// Check if branch_id is 'all'
if ($branch_id === 'all') {
try {
$pdo = db();
$stmt_u = $pdo->prepare("SELECT branch_id FROM users WHERE id = ?");
$stmt_u->execute([$user_id]);
$u_branch = $stmt_u->fetchColumn();
if ($u_branch && $u_branch != 'all') {
$branch_id = $u_branch;
} else {
$stmt_ub = $pdo->prepare("SELECT branch_id FROM user_branches WHERE user_id = ? LIMIT 1");
$stmt_ub->execute([$user_id]);
$ub_branch = $stmt_ub->fetchColumn();
$branch_id = $ub_branch ?: $pdo->query("SELECT id FROM branches LIMIT 1")->fetchColumn();
}
} catch (Exception $e) {}
}
if (empty($items)) {
echo json_encode(['success' => false, 'error' => 'Cart is empty']);
exit;
}
try {
$pdo = db();
$pdo->beginTransaction();
$payment_status = ($payment_method && $payment_method !== 'pay_later') ? 'paid' : 'unpaid';
if ($order_id) {
$stmt = $pdo->prepare("UPDATE orders SET customer_id = ?, total_price = ?, vat_total = ?, payment_status = ? WHERE id = ? AND branch_id = ?");
$stmt->execute([$customer_id, $total_price, $vat_total, $payment_status, $order_id, $branch_id]);
$stmt = $pdo->prepare("DELETE FROM order_items WHERE order_id = ?");
$stmt->execute([$order_id]);
} else {
$stmt = $pdo->prepare("INSERT INTO orders (branch_id, customer_id, user_id, order_number, total_price, vat_total, status, payment_status)
VALUES (?, ?, ?, NULL, ?, ?, 'received', ?)");
$stmt->execute([$branch_id, $customer_id, $user_id, $total_price, $vat_total, $payment_status]);
$order_id = $pdo->lastInsertId();
// Order Number Generation
$stmt_prefix = $pdo->prepare("SELECT prefix FROM branches WHERE id = ?");
$stmt_prefix->execute([$branch_id]);
$prefix = strtoupper(str_pad(substr($stmt_prefix->fetchColumn() ?: 'ORD', 0, 3), 3, 'X'));
$stmt_max = $pdo->prepare("SELECT order_number FROM orders WHERE branch_id = ? AND order_number LIKE ? ORDER BY id DESC LIMIT 100");
$stmt_max->execute([$branch_id, "$prefix-%"]);
$existing = $stmt_max->fetchAll(PDO::FETCH_COLUMN);
$max_serial = 0;
foreach ($existing as $onum) {
if (preg_match('/' . preg_quote($prefix) . '-(\d{6})/', $onum, $matches)) {
if ((int)$matches[1] > $max_serial) $max_serial = (int)$matches[1];
}
}
$order_number = $prefix . '-' . str_pad($max_serial + 1, 6, '0', STR_PAD_LEFT);
$pdo->prepare("UPDATE orders SET order_number = ? WHERE id = ?")->execute([$order_number, $order_id]);
}
$stmt_item = $pdo->prepare("INSERT INTO order_items (order_id, item_id, variant_id, service_id, quantity, unit_price, vat_amount, subtotal) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
foreach ($items as $item) {
$stmt_item->execute([$order_id, $item['itemId'], $item['variantId'] ?: null, $item['serviceId'], $item['quantity'], $item['price'], $item['vatAmount'] ?: 0, ($item['price'] * $item['quantity'])]);
}
// Loyalty Redemption Logic
$redeem_amount = 0;
if ($customer_id && $points_to_redeem > 0 && get_setting('loyalty_enabled') === '1') {
$stmt_c = $pdo->prepare("SELECT loyalty_points FROM customers WHERE id = ? FOR UPDATE");
$stmt_c->execute([$customer_id]);
$curr_points = (float)$stmt_c->fetchColumn();
if ($curr_points >= $points_to_redeem) {
$point_val = (float)get_setting('loyalty_currency_per_point', 0.05);
$redeem_amount = $points_to_redeem * $point_val;
// Cap redemption at order total
if ($redeem_amount > $total_price) {
$redeem_amount = $total_price;
$points_to_redeem = $redeem_amount / $point_val;
}
// Deduct points
$pdo->prepare("UPDATE customers SET loyalty_points = loyalty_points - ? WHERE id = ?")->execute([$points_to_redeem, $customer_id]);
// Record loyalty transaction
$pdo->prepare("INSERT INTO loyalty_transactions (customer_id, order_id, points, type, description) VALUES (?, ?, ?, 'redeemed', ?)")
->execute([$customer_id, $order_id, -$points_to_redeem, "Redeemed for order $order_number"]);
// Record loyalty payment
$pdo->prepare("INSERT INTO payments (order_id, amount, payment_method) VALUES (?, ?, 'loyalty')")
->execute([$order_id, $redeem_amount]);
// Save loyalty discount to order
$pdo->prepare("UPDATE orders SET loyalty_discount = ? WHERE id = ?")
->execute([$redeem_amount, $order_id]);
}
}
// Handle Remaining Payment
$remaining_to_pay = $total_price - $redeem_amount;
if ($payment_method && $payment_method !== 'pay_later' && $remaining_to_pay > 0) {
$pdo->prepare("INSERT INTO payments (order_id, amount, payment_method) VALUES (?, ?, ?)")
->execute([$order_id, $remaining_to_pay, $payment_method]);
}
// Loyalty Earning Logic
if ($customer_id && get_setting('loyalty_enabled') === '1' && $payment_status === 'paid') {
$pts_per_curr = (float)get_setting('loyalty_points_per_currency', 1);
$points_earned = $remaining_to_pay * $pts_per_curr;
if ($points_earned > 0) {
$pdo->prepare("UPDATE customers SET loyalty_points = loyalty_points + ? WHERE id = ?")->execute([$points_earned, $customer_id]);
$pdo->prepare("INSERT INTO loyalty_transactions (customer_id, order_id, points, type, description) VALUES (?, ?, ?, 'earned', ?)")
->execute([$customer_id, $order_id, $points_earned, "Earned from order $order_number"]);
}
}
$customer = null;
if ($customer_id) {
$stmt_cust = $pdo->prepare('SELECT name_ar, phone FROM customers WHERE id = ?');
$stmt_cust->execute([$customer_id]);
$customer = $stmt_cust->fetch();
}
$pdo->commit();
// WhatsApp
try {
if (get_setting('whatsapp_enabled') === '1' && $customer && !empty($customer['phone'])) {
$template = get_setting('msg_order_created_ar');
if (!empty($template)) {
$details_parts = [];
foreach ($items as $item) {
$stmt_names = $pdo->prepare('SELECT i.name_ar as item_name, s.name_ar as service_name FROM items i, services s WHERE i.id = ? AND s.id = ?');
$stmt_names->execute([$item['itemId'], $item['serviceId']]);
$names = $stmt_names->fetch();
$details_parts[] = ($names['item_name'] ?? 'صنف') . ' (' . ($names['service_name'] ?? 'خدمة') . ') x' . $item['quantity'];
}
$message = str_replace(['{customer_name}', '{order_number}', '{order_details}', '{total_price}'], [$customer['name_ar'], $order_number, implode(', ', $details_parts), $total_price], $template);
send_whatsapp_message($customer['phone'], $message);
}
}
} catch (Exception $e) {}
echo json_encode(['success' => true, 'order_id' => $order_id]);
} catch (Exception $e) {
if (isset($pdo)) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}