0) { $stmt = db()->prepare("SELECT * FROM shipments WHERE id = :id"); $stmt->execute([':id' => $shipmentId]); $shipment = $stmt->fetch(); } $errors = []; $flash = get_flash(); $userRole = $_SESSION['user_role'] ?? ''; $currentUserId = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0; $isAdmin = $userRole === 'admin'; $isShipper = $userRole === 'shipper'; $isTruckOwner = $userRole === 'truck_owner'; $isAssignedTruckOwner = $shipment && $shipment['truck_owner_id'] == $currentUserId; // Platform Fee Configuration $settings = get_settings(); $platformFeePercentage = (float)($settings['platform_charge_percentage'] ?? 0) / 100; $pricingModel = $settings['pricing_model'] ?? 'percentage'; // Handle POST actions if ($_SERVER['REQUEST_METHOD'] === 'POST') { validate_csrf_token(); $action = $_POST['action'] ?? ''; if ($action === 'submit_offer') { if (!$isTruckOwner && !$isAdmin) { $errors[] = 'Only truck owners can submit offers.'; } $offerOwner = trim($_POST['offer_owner'] ?? ''); $offerPrice = trim($_POST['offer_price'] ?? ''); // Enforce fixed price logic if applicable if ($pricingModel === 'fixed_price' && !empty($shipment['target_price'])) { $offerPrice = $shipment['target_price']; } if ($offerOwner === '' || $offerPrice === '') { $errors[] = t('error_required'); } elseif (!is_numeric($offerPrice)) { $errors[] = t('error_invalid'); } else { $truckOwnerId = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : null; $stmt = db()->prepare( "UPDATE shipments SET offer_owner = :offer_owner, offer_price = :offer_price, status = 'offered', truck_owner_id = :truck_owner_id WHERE id = :id" ); $stmt->execute([ ':offer_owner' => $offerOwner, ':offer_price' => $offerPrice, ':truck_owner_id' => $truckOwnerId, ':id' => $shipmentId, ]); // Notify Shipper if (!empty($shipment['shipper_id'])) { $shipperUser = db()->query("SELECT * FROM users WHERE id = " . (int)$shipment['shipper_id'])->fetch(); if ($shipperUser) { NotificationService::send('shipment_offered', $shipperUser, [ 'shipment_id' => $shipmentId, 'offer_price' => $offerPrice, 'offer_owner' => $offerOwner ]); } } set_flash('success', t('success_offer')); header('Location: ' . url_with_lang('shipment_detail.php', ['id' => $shipmentId])); exit; } } elseif ($action === 'accept_offer' && $isShipper) { if ($shipment && $shipment['status'] === 'offered' && $shipment['offer_price'] > 0) { $offerPrice = (float)$shipment['offer_price']; $platformFee = $offerPrice * $platformFeePercentage; $totalPrice = $offerPrice + $platformFee; $stmt = db()->prepare( "UPDATE shipments SET status = 'confirmed', payment_status = 'paid', platform_fee = :fee, total_price = :total WHERE id = :id" ); $stmt->execute([ ':fee' => $platformFee, ':total' => $totalPrice, ':id' => $shipmentId ]); // Notify Truck Owner if (!empty($shipment['truck_owner_id'])) { $truckOwnerUser = db()->query("SELECT * FROM users WHERE id = " . (int)$shipment['truck_owner_id'])->fetch(); if ($truckOwnerUser) { NotificationService::send('shipment_accepted', $truckOwnerUser, [ 'shipment_id' => $shipmentId ]); } } set_flash('success', t('Payment successful. Shipment confirmed!')); header('Location: ' . url_with_lang('shipment_detail.php', ['id' => $shipmentId])); exit; } } elseif ($action === 'reject_offer' && $isShipper) { if ($shipment && $shipment['status'] === 'offered') { // Notify Truck Owner first (before clearing ID) if (!empty($shipment['truck_owner_id'])) { $truckOwnerUser = db()->query("SELECT * FROM users WHERE id = " . (int)$shipment['truck_owner_id'])->fetch(); if ($truckOwnerUser) { NotificationService::send('shipment_rejected', $truckOwnerUser, [ 'shipment_id' => $shipmentId ]); } } $stmt = db()->prepare( "UPDATE shipments SET status = 'posted', offer_price = NULL, offer_owner = NULL, truck_owner_id = NULL WHERE id = :id" ); $stmt->execute([':id' => $shipmentId]); set_flash('success', 'Offer rejected. Shipment is now open for new offers.'); header('Location: ' . url_with_lang('shipment_detail.php', ['id' => $shipmentId])); exit; } } elseif ($action === 'upload_pod') { if (($isAdmin || ($isTruckOwner && $isAssignedTruckOwner)) && in_array($shipment['status'], ['confirmed', 'in_transit', 'delivered'])) { if (isset($_FILES['pod_file']) && $_FILES['pod_file']['error'] === UPLOAD_ERR_OK) { $fileTmpPath = $_FILES['pod_file']['tmp_name']; $fileName = $_FILES['pod_file']['name']; $fileSize = $_FILES['pod_file']['size']; $fileType = $_FILES['pod_file']['type']; $fileNameCmps = explode(".", $fileName); $fileExtension = strtolower(end($fileNameCmps)); $allowedfileExtensions = ['jpg', 'jpeg', 'png', 'pdf']; if (in_array($fileExtension, $allowedfileExtensions)) { $newFileName = 'pod_' . $shipmentId . '_' . md5(time() . $fileName) . '.' . $fileExtension; $uploadFileDir = __DIR__ . '/uploads/pods/'; if (!is_dir($uploadFileDir)) { mkdir($uploadFileDir, 0777, true); } $dest_path = $uploadFileDir . $newFileName; if(move_uploaded_file($fileTmpPath, $dest_path)) { $dbPath = 'uploads/pods/' . $newFileName; $stmt = db()->prepare("UPDATE shipments SET pod_file = :pod_file, status = 'delivered' WHERE id = :id"); $stmt->execute([':pod_file' => $dbPath, ':id' => $shipmentId]); set_flash('success', 'Proof of Delivery uploaded successfully.'); header('Location: ' . url_with_lang('shipment_detail.php', ['id' => $shipmentId])); exit; } else { $errors[] = 'There was some error moving the file to upload directory.'; } } else { $errors[] = 'Upload failed. Allowed file types: ' . implode(',', $allowedfileExtensions); } } else { $errors[] = 'No file uploaded or upload error.'; } } else { $errors[] = 'You are not authorized to upload POD for this shipment.'; } } } render_header(t('shipment_detail')); ?>
= e(t('no_shipments')) ?>
= e(t('created_at')) ?>: = e($shipment['created_at']) ?>
Secure payment via = e($shipment['payment_method'] === 'bank_transfer' ? 'Bank Transfer' : 'Thawani') ?>
Waiting for truck owners to submit offers.
= t('pending_approval_msg') ?>
This shipment has been confirmed and paid for.