36782-vm/order_process.php
2025-12-28 19:43:55 +00:00

260 lines
9.5 KiB
PHP

<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once 'mail/MailService.php';
require_once 'includes/init.php';
require_once 'includes/auth.php';
require_login();
require_once 'includes/helpers.php';
require_once 'includes/currency.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: checkout.php');
exit;
}
$cart = $_SESSION['cart'] ?? [];
if (empty($cart)) {
header('Location: index.php');
exit;
}
$pdo = db();
try {
$pdo->beginTransaction();
// 1. Get product details from the database
$product_ids = array_keys($cart);
$placeholders = implode(',', array_fill(0, count($product_ids), '?'));
$stmt = $pdo->prepare("SELECT id, price, units_per_pallet FROM products WHERE id IN ($placeholders)");
$stmt->execute($product_ids);
$products_by_id = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
// 2. Calculate total amount
$total_amount_gross = 0;
$client_id = $_SESSION['client_id'] ?? null;
$order_items_data = [];
$is_supplier_delivery = false;
foreach ($cart as $product_id => $quantity) {
if (isset($products_by_id[$product_id])) {
$product = $products_by_id[$product_id];
$price_info = getEffectivePrice($pdo, $product_id, $client_id);
$price_gross = $price_info['gross'];
$total_amount_gross += $price_gross * $quantity;
$order_items_data[] = [
'product_id' => $product_id,
'quantity' => $quantity,
'unit_price' => $price_gross, // Save gross price
'line_total' => $price_gross * $quantity,
];
$units_per_pallet = $product['units_per_pallet'];
if (isset($units_per_pallet) && $units_per_pallet > 0) {
if ($quantity >= $units_per_pallet) {
$is_supplier_delivery = true;
}
}
}
}
$delivery_source = $is_supplier_delivery ? 'supplier' : 'cs';
if ($_POST['payment_method'] === 'credit') {
$stmt = $pdo->prepare('SELECT credit_balance, credit_enabled FROM clients WHERE id = ? FOR UPDATE');
$stmt->execute([$client_id]);
$credit_info = $stmt->fetch();
if (!$credit_info || !$credit_info['credit_enabled'] || $credit_info['credit_balance'] < $total_amount_gross) {
throw new Exception('Invalid payment method or insufficient credit.');
}
$new_balance = $credit_info['credit_balance'] - $total_amount_gross;
$stmt = $pdo->prepare('UPDATE clients SET credit_balance = ? WHERE id = ?');
$stmt->execute([$new_balance, $client_id]);
}
// 3. Create the order
$stmt = $pdo->prepare(
'INSERT INTO orders (client_id, total_amount, payment_method, delivery_source, notes, status) VALUES (?, ?, ?, ?, ?, ?)'
);
$stmt->execute([
$client_id,
$total_amount_gross,
$_POST['payment_method'],
$delivery_source,
$_POST['notes'],
$_POST['payment_method'] === 'credit' ? 'in_progress' : 'pending_payment'
]);
$order_id = $pdo->lastInsertId();
// 4. Insert order items
$stmt = $pdo->prepare(
'INSERT INTO order_items (order_id, product_id, quantity, unit_price, line_total) VALUES (?, ?, ?, ?, ?)'
);
foreach ($order_items_data as $item) {
$stmt->execute([
$order_id,
$item['product_id'],
$item['quantity'],
$item['unit_price'],
$item['line_total'],
]);
}
// 5. Commit the transaction
$pdo->commit();
// 6. Send email notifications
// --- Data Fetching for Emails ---
$user_id = $_SESSION['user_id'] ?? null;
$stmt = $pdo->prepare('SELECT email FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user = $stmt->fetch();
$client_email = $user['email'] ?? null;
$stmt = $pdo->prepare('SELECT name FROM clients WHERE id = ?');
$stmt->execute([$client_id]);
$client = $stmt->fetch();
$client_company_name = $client['name'] ?? 'N/A';
$product_ids_for_names = array_map(function($item) { return $item['product_id']; }, $order_items_data);
$placeholders = implode(',', array_fill(0, count($product_ids_for_names), '?'));
$stmt = $pdo->prepare("SELECT id, name FROM products WHERE id IN ($placeholders)");
$stmt->execute($product_ids_for_names);
$products_by_id_for_email = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$order_details_link = get_site_url() . '/order_details.php?id=' . $order_id;
$admin_order_details_link = get_site_url() . '/admin/order_details.php?id=' . $order_id;
$admin_email = getenv('MAIL_TO') ?: 'admin@example.com';
// --- Email Sending Logic ---
$site_name = get_site_url(); // Or your site name
if ($client_email) {
// 1. Client - Order Confirmation
$data_client = [
'order_id' => $order_id,
'order_items' => $order_items_data,
'products' => $products_by_id_for_email,
'total_amount_gross' => $total_amount_gross,
'payment_method' => $_POST['payment_method'],
'order_details_link' => $order_details_link,
'site_name' => $site_name,
'pdo' => $pdo,
];
MailService::sendTemplatedMail($client_email, $lang, 'order_confirmation', $data_client);
// 3. Client - Payment Instructions (Bank Transfer)
if ($_POST['payment_method'] === 'bank_transfer') {
// TODO: Fetch bank details from a settings table or config
$bank_account_details = "Bank: Example Bank\nAccount Number: 123456789";
$transfer_title = "Order #{$order_id}";
$payment_deadline = date('Y-m-d', strtotime('+7 days'));
$data_bank = [
'order_id' => $order_id,
'total_amount_gross' => $total_amount_gross,
'bank_account_details' => $bank_account_details,
'transfer_title' => $transfer_title,
'payment_deadline' => $payment_deadline,
'site_name' => $site_name,
'pdo' => $pdo,
];
MailService::sendTemplatedMail($client_email, $lang, 'payment_instructions', $data_bank);
}
// 6. Client - Credit Payment Confirmation
if ($_POST['payment_method'] === 'credit') {
$data_credit = [
'order_id' => $order_id,
'total_amount_gross' => $total_amount_gross,
'new_balance' => $new_balance,
'order_details_link' => $order_details_link,
'site_name' => $site_name,
'pdo' => $pdo,
];
MailService::sendTemplatedMail($client_email, $lang, 'credit_payment_confirmation', $data_credit);
}
}
// 2. Admin - New Order Notification
$data_admin = [
'order_id' => $order_id,
'client_company_name' => $client_company_name,
'total_amount_gross' => $total_amount_gross,
'payment_method' => $_POST['payment_method'],
'delivery_source' => $delivery_source,
'admin_order_details_link' => $admin_order_details_link,
'site_name' => $site_name,
'pdo' => $pdo,
];
MailService::sendTemplatedMail($admin_email, 'en', 'admin_new_order', $data_admin); // Admin email in English
// 7. Supplier - New Order Items
$stmt = $pdo->prepare("\n SELECT p.supplier_id, s.name as supplier_name, s.email as supplier_email, p.name as product_name, oi.quantity\n FROM order_items oi\n JOIN products p ON oi.product_id = p.id\n JOIN suppliers s ON p.supplier_id = s.id\n WHERE oi.order_id = ? AND p.supplier_id IS NOT NULL\n ");
$stmt->execute([$order_id]);
$supplier_items = $stmt->fetchAll(PDO::FETCH_ASSOC);
$items_by_supplier = [];
foreach ($supplier_items as $item) {
$items_by_supplier[$item['supplier_id']]['name'] = $item['supplier_name'];
$items_by_supplier[$item['supplier_id']]['email'] = $item['supplier_email'];
$items_by_supplier[$item['supplier_id']]['items'][] = [
'name' => $item['product_name'],
'quantity' => $item['quantity'],
];
}
foreach ($items_by_supplier as $supplier_id => $supplier_data) {
if (!empty($supplier_data['email'])) {
$data_supplier = [
'order_id' => $order_id,
'supplier_items' => $supplier_data['items'],
'site_name' => $site_name,
'pdo' => $pdo,
];
MailService::sendTemplatedMail($supplier_data['email'], 'en', 'supplier_new_order_items', $data_supplier); // Supplier email in English
}
}
// 8. Clear the cart and store order ID in session for the confirmation page
unset($_SESSION['cart']);
$_SESSION['latest_order_id'] = $order_id;
// 9. Redirect to confirmation page
header('Location: order_confirmation.php');
exit;
} catch (Exception $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
// In a real application, log this error
die("Błąd podczas przetwarzania zamówienia: " . $e->getMessage());
} catch (PDOException $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
// In a real application, log this error
die("Błąd podczas przetwarzania zamówienia: " . $e->getMessage());
} catch (Throwable $t) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
die("An unexpected error occurred: " . $t->getMessage());
}