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 = '
Thank you for your order.
" . "Order Number: {$order_id}
" . "Order Date: " . date('Y-m-d') . "
" . "Products:{$product_list_html}" . "Total Amount: " . format_money($total_amount_gross, $lang, $pdo) . "
" . "Payment Method: {" . strtoupper($_POST['payment_method']) . "}
" . "You can view your order details here: {$order_details_link}
"; $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 = "Please make a payment for your order.
" . "Order Number: {$order_id}
" . "Amount: " . format_money($total_amount_gross, $lang, $pdo) . "
" . "Bank Account Details:
" . nl2br($bank_account_details) . "
Transfer Title: {$transfer_title}
" . "Payment Deadline: {$payment_deadline}
"; $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 = "Your order has been successfully placed using your trade credit.
" . "Order Number: {$order_id}
" . "Amount: " . format_money($total_amount_gross, $lang, $pdo) . "
" . "Remaining Credit Limit: " . format_money($new_balance, $lang, $pdo) . "
" . "You can view your order details here: {$order_details_link}
"; $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 = "A new order has been placed.
" . "Order Number: {$order_id}
" . "Client: {$client_company_name}
" . "Total Amount: " . format_money($total_amount_gross, $lang, $pdo) . "
" . "Payment Method: {" . strtoupper($_POST['payment_method']) . "}
" . "Delivery Source: {$delivery_source}
" . "View the order here: {$admin_order_details_link}
"; $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 = 'You have new items in order #{$order_id}.
" . "Order Number: {$order_id}
" . "Products:{$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()); }