File manager - Edit - /home/webapp69.cm.in.th/u69319090039/Shop39/database/app/Controllers/Seller/SellerOrderController.php
Back
<?php class SellerOrderController extends Controller { public function index(): void { $seller = Auth::sellerProfile(); $db = Database::getInstance(); // Check if is_read column exists in orders $colsStmt = $db->query("SHOW COLUMNS FROM orders"); $orderCols = $colsStmt ? $colsStmt->fetchAll(PDO::FETCH_COLUMN) : []; if (!in_array('is_read', $orderCols)) { $db->exec("ALTER TABLE orders ADD COLUMN is_read TINYINT(1) NOT NULL DEFAULT 0 AFTER status"); } $search = trim($_GET['search'] ?? ''); $statusFilter = trim($_GET['status'] ?? 'all'); $paymentFilter = trim($_GET['payment'] ?? 'all'); $dateFilter = trim($_GET['date_filter'] ?? 'all'); $dateFrom = trim($_GET['date_from'] ?? ''); $dateTo = trim($_GET['date_to'] ?? ''); $where = ["o.seller_id = :sid"]; $params = ['sid' => $seller['id']]; // 1. Text Search (Order number, Customer name, Phone, Tracking) if (!empty($search)) { $where[] = "(o.order_number LIKE :q OR u.full_name LIKE :q OR u.phone LIKE :q OR o.shipping_address LIKE :q OR o.tracking_number LIKE :q)"; $params['q'] = '%' . $search . '%'; } // 2. Status Filter if (!empty($statusFilter) && $statusFilter !== 'all') { if ($statusFilter === 'new') { $where[] = "o.status IN ('pending', 'waiting_payment', 'paid') AND o.is_read = 0"; } elseif ($statusFilter === 'preparing_all') { $where[] = "o.status IN ('order_accepted', 'preparing')"; } else { $where[] = "o.status = :status"; $params['status'] = $statusFilter; } } // 3. Payment Method / Status Filter if (!empty($paymentFilter) && $paymentFilter !== 'all') { if ($paymentFilter === 'cod') { $where[] = "o.payment_method = 'cod'"; } elseif ($paymentFilter === 'prepaid') { $where[] = "o.payment_method = 'prepaid'"; } elseif ($paymentFilter === 'paid') { $where[] = "o.payment_status = 'paid'"; } elseif ($paymentFilter === 'pending_payment') { $where[] = "o.payment_status = 'pending'"; } } // 4. Date Filters if ($dateFilter === 'today') { $where[] = "DATE(o.created_at) = CURDATE()"; } elseif ($dateFilter === '7days') { $where[] = "o.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)"; } elseif ($dateFilter === '30days') { $where[] = "o.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)"; } elseif ($dateFilter === 'custom' && !empty($dateFrom)) { if (!empty($dateTo)) { $where[] = "DATE(o.created_at) BETWEEN :dfrom AND :dto"; $params['dfrom'] = $dateFrom; $params['dto'] = $dateTo; } else { $where[] = "DATE(o.created_at) >= :dfrom"; $params['dfrom'] = $dateFrom; } } $whereSql = implode(' AND ', $where); $sql = "SELECT o.*, u.full_name AS customer_name, u.email AS customer_email, u.phone AS customer_phone, (SELECT COUNT(*) FROM order_items WHERE order_id = o.id) as item_count, (SELECT p.title FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = o.id LIMIT 1) as first_item_title FROM orders o JOIN users u ON o.user_id = u.id WHERE {$whereSql} ORDER BY o.id DESC"; $stmt = $db->prepare($sql); $stmt->execute($params); $orders = $stmt->fetchAll(); // Calculate summary metrics for seller $summarySql = "SELECT SUM(CASE WHEN status IN ('pending', 'waiting_payment', 'paid') AND is_read = 0 THEN 1 ELSE 0 END) as new_unread_cnt, SUM(CASE WHEN status IN ('pending', 'waiting_payment') THEN 1 ELSE 0 END) as pending_cnt, SUM(CASE WHEN status IN ('order_accepted', 'preparing') THEN 1 ELSE 0 END) as preparing_cnt, SUM(CASE WHEN status = 'shipping' THEN 1 ELSE 0 END) as shipping_cnt, SUM(CASE WHEN status = 'delivered' THEN 1 ELSE 0 END) as delivered_cnt, SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed_cnt, SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_cnt, COALESCE(SUM(CASE WHEN status IN ('delivered', 'completed') THEN total_amount ELSE 0 END), 0) as total_sales FROM orders WHERE seller_id = :sid"; $sumStmt = $db->prepare($summarySql); $sumStmt->execute(['sid' => $seller['id']]); $summary = $sumStmt->fetch() ?: [ 'new_unread_cnt' => 0, 'pending_cnt' => 0, 'preparing_cnt' => 0, 'shipping_cnt' => 0, 'delivered_cnt' => 0, 'completed_cnt' => 0, 'cancelled_cnt' => 0, 'total_sales' => 0, ]; $this->render('seller/orders/index', [ 'title' => 'จัดการคำสั่งซื้อในร้าน (Seller Orders)', 'seller' => $seller, 'orders' => $orders, 'summary' => $summary, 'search' => $search, 'statusFilter' => $statusFilter, 'paymentFilter' => $paymentFilter, 'dateFilter' => $dateFilter, 'dateFrom' => $dateFrom, 'dateTo' => $dateTo ], 'seller'); } public function getOrderDetail(string $id): void { header('Content-Type: application/json; charset=utf-8'); $seller = Auth::sellerProfile(); $orderId = (int)$id; if (!$seller || empty($seller['id'])) { $this->json(['success' => false, 'status' => 'error', 'message' => 'Unauthorized: กรุณาเข้าสู่ระบบร้านค้า'], 401); return; } if ($orderId <= 0) { $this->json(['success' => false, 'status' => 'error', 'message' => 'Invalid Order ID'], 400); return; } try { $db = Database::getInstance(); // Mark order as read for this seller (safe update) try { $readStmt = $db->prepare("UPDATE orders SET is_read = 1 WHERE id = :oid AND seller_id = :sid"); $readStmt->execute(['oid' => $orderId, 'sid' => $seller['id']]); } catch (Throwable $e) { // Column is_read might not exist on older DB versions, ignore silently } $sql = "SELECT o.*, u.full_name AS customer_name, u.email AS customer_email, u.phone AS customer_phone FROM orders o JOIN users u ON o.user_id = u.id WHERE o.id = :oid AND o.seller_id = :sid LIMIT 1"; $stmt = $db->prepare($sql); $stmt->execute(['oid' => $orderId, 'sid' => $seller['id']]); $order = $stmt->fetch(); if (!$order) { $this->json(['success' => false, 'status' => 'error', 'message' => 'ไม่พบคำสั่งซื้อ หรือไม่มีสิทธิ์เข้าถึง'], 404); return; } // Order Items with images $itemSql = "SELECT oi.*, p.title, p.slug, p.sku, (SELECT image_path FROM product_images WHERE product_id = p.id AND is_primary = 1 LIMIT 1) AS primary_image FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = :oid"; $itemStmt = $db->prepare($itemSql); $itemStmt->execute(['oid' => $orderId]); $items = $itemStmt->fetchAll() ?: []; // History timeline (safe fallback if table does not exist) $history = []; try { if (class_exists('OrderStatusHistory')) { $history = OrderStatusHistory::getHistory($orderId) ?: []; } } catch (Throwable $th) { $history = []; } // Tracking URL helper $trackingUrl = ''; try { if (class_exists('TrackingService')) { $trackingUrl = TrackingService::buildTrackingUrl($order['shipping_company'] ?? '', $order['tracking_number'] ?? ''); } } catch (Throwable $th) { $trackingUrl = ''; } $this->json([ 'success' => true, 'status' => 'success', 'order' => $order, 'items' => $items, 'history' => $history, 'tracking_url' => $trackingUrl, 'data' => [ 'order_id' => (int)$order['id'], 'order_number' => $order['order_number'], 'customer_name' => $order['customer_name'] ?? '', 'phone' => $order['customer_phone'] ?? '', 'email' => $order['customer_email'] ?? '', 'total' => (float)($order['total_amount'] ?? 0), 'status' => $order['status'] ?? '', 'items' => $items, 'history' => $history, 'tracking_url' => $trackingUrl ] ]); } catch (Throwable $e) { error_log("Seller Order Detail Error: " . $e->getMessage()); $this->json([ 'success' => false, 'status' => 'error', 'message' => 'เกิดข้อผิดพลาดในการดึงข้อมูลคำสั่งซื้อ: ' . $e->getMessage() ], 500); } } public function updateStatus(string $id): void { $this->validateCsrf(); $seller = Auth::sellerProfile(); $orderId = (int)$id; $db = Database::getInstance(); $input = json_decode(file_get_contents('php://input'), true); if (!$input) { $input = $_POST; } $newStatus = trim($input['status'] ?? ''); $shippingCompany = trim($input['shipping_company'] ?? ''); $trackingNumber = trim($input['tracking_number'] ?? ''); $note = trim($input['note'] ?? ''); // Fetch Order $stmt = $db->prepare("SELECT * FROM orders WHERE id = :oid AND seller_id = :sid LIMIT 1"); $stmt->execute(['oid' => $orderId, 'sid' => $seller['id']]); $order = $stmt->fetch(); if (!$order) { $this->json(['status' => 'error', 'message' => 'ไม่พบรายการคำสั่งซื้อ หรือไม่มีสิทธิ์เข้าถึง'], 403); return; } $currentStatus = $order['status']; // Terminal status validation if ($currentStatus === 'cancelled') { $this->json(['status' => 'error', 'message' => 'คำสั่งซื้อที่ยกเลิกแล้ว ไม่สามารถเปลี่ยนสถานะได้'], 400); return; } if ($currentStatus === 'completed' && $newStatus !== 'completed') { $this->json(['status' => 'error', 'message' => 'คำสั่งซื้อเสร็จสมบูรณ์แล้ว ไม่สามารถเปลี่ยนสถานะย้อนกลับได้'], 400); return; } $validStatuses = ['pending', 'order_accepted', 'preparing', 'shipping', 'delivered', 'completed', 'cancelled']; if (!in_array($newStatus, $validStatuses)) { $this->json(['status' => 'error', 'message' => 'สถานะไม่ถูกต้อง'], 400); return; } // Update SQL $updateFields = ["status = :status"]; $params = ['status' => $newStatus, 'id' => $orderId]; // If order is COD and delivered/completed, update payment_status to 'paid' if (in_array($newStatus, ['delivered', 'completed']) && ($order['payment_method'] ?? '') === 'cod') { $updateFields[] = "payment_status = 'paid'"; $updateFields[] = "paid_at = NOW()"; $updateFields[] = "payment_amount = total_amount"; } if ($newStatus === 'shipping' || !empty($shippingCompany) || !empty($trackingNumber)) { if (!empty($shippingCompany)) { $updateFields[] = "shipping_company = :scomp"; $params['scomp'] = $shippingCompany; } if (!empty($trackingNumber)) { $updateFields[] = "tracking_number = :track"; $params['track'] = $trackingNumber; } } $sql = "UPDATE orders SET " . implode(', ', $updateFields) . " WHERE id = :id"; $upStmt = $db->prepare($sql); $upStmt->execute($params); // Record History $histNote = $note; if ($newStatus === 'shipping' && (!empty($shippingCompany) || !empty($trackingNumber))) { $histNote .= ($histNote ? ' | ' : '') . "ขนส่ง: {$shippingCompany} (เลขพัสดุ: {$trackingNumber})"; } OrderStatusHistory::add( $orderId, $newStatus, $currentStatus, $histNote, 'Seller (' . Security::e($seller['shop_name']) . ')' ); // Calculate updated summary metrics $summarySql = "SELECT SUM(CASE WHEN status IN ('pending', 'waiting_payment') THEN 1 ELSE 0 END) as pending_cnt, SUM(CASE WHEN status IN ('order_accepted', 'preparing') THEN 1 ELSE 0 END) as preparing_cnt, SUM(CASE WHEN status = 'shipping' THEN 1 ELSE 0 END) as shipping_cnt, SUM(CASE WHEN status = 'delivered' THEN 1 ELSE 0 END) as delivered_cnt, SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed_cnt, SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled_cnt FROM orders WHERE seller_id = :sid"; $sumStmt = $db->prepare($summarySql); $sumStmt->execute(['sid' => $seller['id']]); $summary = $sumStmt->fetch(); $trackingUrl = TrackingService::buildTrackingUrl($updatedOrder['shipping_company'] ?? '', $updatedOrder['tracking_number'] ?? ''); $this->json([ 'status' => 'success', 'message' => 'อัปเดตสถานะคำสั่งซื้อเรียบร้อยแล้ว', 'order' => $updatedOrder, 'history' => $history, 'summary' => $summary, 'tracking_url' => $trackingUrl ]); } public function updateShipping(string $id): void { $this->validateCsrf(); $seller = Auth::sellerProfile(); $orderId = (int)$id; $db = Database::getInstance(); $input = json_decode(file_get_contents('php://input'), true) ?: $_POST; $shippingCompany = trim($input['shipping_company'] ?? ''); $trackingNumber = trim($input['tracking_number'] ?? ''); $stmt = $db->prepare("SELECT * FROM orders WHERE id = :oid AND seller_id = :sid LIMIT 1"); $stmt->execute(['oid' => $orderId, 'sid' => $seller['id']]); $order = $stmt->fetch(); if (!$order) { $this->json(['status' => 'error', 'message' => 'ไม่พบรายการคำสั่งซื้อ หรือไม่มีสิทธิ์เข้าถึง'], 403); return; } $upStmt = $db->prepare("UPDATE orders SET shipping_company = :scomp, tracking_number = :track WHERE id = :id"); $upStmt->execute([ 'scomp' => $shippingCompany, 'track' => $trackingNumber, 'id' => $orderId ]); OrderStatusHistory::add( $orderId, $order['status'], $order['status'], "อัปเดตข้อมูลขนส่ง: {$shippingCompany} (เลขพัสดุ: {$trackingNumber})", 'Seller (' . Security::e($seller['shop_name']) . ')' ); $stmt->execute(['oid' => $orderId, 'sid' => $seller['id']]); $updatedOrder = $stmt->fetch(); $history = OrderStatusHistory::getHistory($orderId); $trackingUrl = TrackingService::buildTrackingUrl($updatedOrder['shipping_company'] ?? '', $updatedOrder['tracking_number'] ?? ''); $this->json([ 'status' => 'success', 'message' => 'บันทึกข้อมูลจัดส่งเรียบร้อยแล้ว', 'order' => $updatedOrder, 'history' => $history, 'tracking_url' => $trackingUrl ]); } public function printSlip(string $id): void { $seller = Auth::sellerProfile(); $orderId = (int)$id; $db = Database::getInstance(); $sql = "SELECT o.*, u.full_name AS customer_name, u.email AS customer_email, u.phone AS customer_phone FROM orders o JOIN users u ON o.user_id = u.id WHERE o.id = :oid AND o.seller_id = :sid LIMIT 1"; $stmt = $db->prepare($sql); $stmt->execute(['oid' => $orderId, 'sid' => $seller['id']]); $order = $stmt->fetch(); if (!$order) { Session::setFlash('danger', 'ไม่พบคำสั่งซื้อ หรือไม่มีสิทธิ์เข้าถึง'); $this->redirect('seller/orders'); return; } $itemSql = "SELECT oi.*, p.title, p.sku, p.barcode FROM order_items oi JOIN products p ON oi.product_id = p.id WHERE oi.order_id = :oid"; $itemStmt = $db->prepare($itemSql); $itemStmt->execute(['oid' => $orderId]); $items = $itemStmt->fetchAll(); foreach ($items as &$item) { if (empty($item['barcode'])) { $item['barcode'] = '885' . str_pad((string)$item['product_id'], 9, '0', STR_PAD_LEFT); } } $this->render('seller/orders/print_slip', [ 'title' => 'พิมพ์ใบปะหน้าพัสดุ #' . $order['order_number'], 'seller' => $seller, 'order' => $order, 'items' => $items ], 'blank'); } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.24 |
proxy
|
phpinfo
|
Settings