295 lines
13 KiB
PHP
295 lines
13 KiB
PHP
<?php
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
session_start();
|
|
}
|
|
require_once 'mail/MailService.php';
|
|
require_once 'includes/lang.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_list_html = '<ul>';
|
|
$product_list_text = '';
|
|
$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);
|
|
|
|
foreach ($order_items_data as $item) {
|
|
$product_name = $products_by_id_for_email[$item['product_id']] ?? 'Unknown Product';
|
|
$product_list_html .= "<li>{$product_name} (Quantity: {$item['quantity']})</li>";
|
|
$product_list_text .= "- {$product_name} (Quantity: {$item['quantity']})\n";
|
|
}
|
|
$product_list_html .= '</ul>';
|
|
|
|
$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 ---
|
|
if ($client_email) {
|
|
// 1. Client - Order Confirmation
|
|
$subject_client = "Your Order Confirmation (#{$order_id})";
|
|
$body_html_client = "<p>Thank you for your order.</p>"
|
|
. "<p><strong>Order Number:</strong> {$order_id}</p>"
|
|
. "<p><strong>Order Date:</strong> " . date('Y-m-d') . "</p>"
|
|
. "<strong>Products:</strong>{$product_list_html}"
|
|
. "<p><strong>Total Amount:</strong> " . format_money($total_amount_gross, $lang, $pdo) . "</p>"
|
|
. "<p><strong>Payment Method:</strong> {" . strtoupper($_POST['payment_method']) . "}</p>"
|
|
. "<p>You can view your order details here: <a href='{$order_details_link}'>{$order_details_link}</a></p>";
|
|
$body_text_client = "Thank you for your order.\n"
|
|
. "Order Number: {$order_id}\n"
|
|
. "Order Date: " . date('Y-m-d') . "\n"
|
|
. "Products:\n{$product_list_text}"
|
|
. "Total Amount: " . format_money($total_amount_gross, $lang, $pdo) . "\n"
|
|
. "Payment Method: {" . strtoupper($_POST['payment_method']) . "}\n"
|
|
. "View your order details here: {$order_details_link}";
|
|
|
|
MailService::sendMail($client_email, $subject_client, $body_html_client, $body_text_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'));
|
|
|
|
$subject_bank = "Payment Instructions for Order #{$order_id}";
|
|
$body_html_bank = "<p>Please make a payment for your order.</p>"
|
|
. "<p><strong>Order Number:</strong> {$order_id}</p>"
|
|
. "<p><strong>Amount:</strong> " . format_money($total_amount_gross, $lang, $pdo) . "</p>"
|
|
. "<p><strong>Bank Account Details:</strong><br>" . nl2br($bank_account_details) . "</p>"
|
|
. "<p><strong>Transfer Title:</strong> {$transfer_title}</p>"
|
|
. "<p><strong>Payment Deadline:</strong> {$payment_deadline}</p>";
|
|
$body_text_bank = "Please make a payment for your order.\n"
|
|
. "Order Number: {$order_id}\n"
|
|
. "Amount: " . format_money($total_amount_gross, $lang, $pdo) . "\n"
|
|
. "Bank Account Details:\n" . $bank_account_details . "\n"
|
|
. "Transfer Title: {$transfer_title}\n"
|
|
. "Payment Deadline: {$payment_deadline}";
|
|
|
|
MailService::sendMail($client_email, $subject_bank, $body_html_bank, $body_text_bank);
|
|
}
|
|
|
|
// 6. Client - Credit Payment Confirmation
|
|
if ($_POST['payment_method'] === 'credit') {
|
|
$subject_credit = "Your Order Paid with Trade Credit (#{$order_id})";
|
|
$body_html_credit = "<p>Your order has been successfully placed using your trade credit.</p>"
|
|
. "<p><strong>Order Number:</strong> {$order_id}</p>"
|
|
. "<p><strong>Amount:</strong> " . format_money($total_amount_gross, $lang, $pdo) . "</p>"
|
|
. "<p><strong>Remaining Credit Limit:</strong> " . format_money($new_balance, $lang, $pdo) . "</p>"
|
|
. "<p>You can view your order details here: <a href='{$order_details_link}'>{$order_details_link}</a></p>";
|
|
$body_text_credit = "Your order has been successfully placed using your trade credit.\n"
|
|
. "Order Number: {$order_id}\n"
|
|
. "Amount: " . format_money($total_amount_gross, $lang, $pdo) . "\n"
|
|
. "Remaining Credit Limit: " . format_money($new_balance, $lang, $pdo) . "\n"
|
|
. "View your order details here: {$order_details_link}";
|
|
MailService::sendMail($client_email, $subject_credit, $body_html_credit, $body_text_credit);
|
|
}
|
|
}
|
|
|
|
// 2. Admin - New Order Notification
|
|
$subject_admin = "New Order Received (#{$order_id})";
|
|
$body_html_admin = "<p>A new order has been placed.</p>"
|
|
. "<p><strong>Order Number:</strong> {$order_id}</p>"
|
|
. "<p><strong>Client:</strong> {$client_company_name}</p>"
|
|
. "<p><strong>Total Amount:</strong> " . format_money($total_amount_gross, $lang, $pdo) . "</p>"
|
|
. "<p><strong>Payment Method:</strong> {" . strtoupper($_POST['payment_method']) . "}</p>"
|
|
. "<p><strong>Delivery Source:</strong> {$delivery_source}</p>"
|
|
. "<p>View the order here: <a href='{$admin_order_details_link}'>{$admin_order_details_link}</a></p>";
|
|
$body_text_admin = "A new order has been placed.\n"
|
|
. "Order Number: {$order_id}\n"
|
|
. "Client: {$client_company_name}\n"
|
|
. "Total Amount: " . format_money($total_amount_gross, $lang, $pdo) . "\n"
|
|
. "Payment Method: {" . strtoupper($_POST['payment_method']) . "}\n"
|
|
. "Delivery Source: {$delivery_source}\n"
|
|
. "View the order here: {$admin_order_details_link}";
|
|
|
|
MailService::sendMail($admin_email, $subject_admin, $body_html_admin, $body_text_admin);
|
|
|
|
// 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'])) {
|
|
$product_list_supplier_html = '<ul>';
|
|
$product_list_supplier_text = '';
|
|
foreach ($supplier_data['items'] as $product) {
|
|
$product_list_supplier_html .= "<li>{$product['name']}\n (Quantity: {$product['quantity']})</li>";
|
|
$product_list_supplier_text .= "- {$product['name']}\n (Quantity: {$product['quantity']})\n";
|
|
}
|
|
$product_list_supplier_html .= '</ul>';
|
|
|
|
$subject_supplier = "New Items in Order #{$order_id}";
|
|
$body_html_supplier = "<p>You have new items in order #{$order_id}.</p>"
|
|
. "<p><strong>Order Number:</strong> {$order_id}</p>"
|
|
. "<strong>Products:</strong>{$product_list_supplier_html}";
|
|
$body_text_supplier = "You have new items in order #{$order_id}.\n"
|
|
. "Order Number: {$order_id}\n"
|
|
. "Products:\n{$product_list_supplier_text}";
|
|
|
|
MailService::sendMail($supplier_data['email'], $subject_supplier, $body_html_supplier, $body_text_supplier);
|
|
}
|
|
}
|
|
|
|
|
|
// 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());
|
|
}
|
|
|