inventoryService = $inventoryService; $this->procurementService = $procurementService; } public function index() { $centralDomains = config('tenancy.central_domains', []); $demoPort = config('tenancy.demo_tenant_port'); if ((!$demoPort || request()->getPort() != $demoPort) && in_array(request()->getHost(), $centralDomains)) { return redirect()->route('landlord.dashboard'); } $invStats = $this->inventoryService->getDashboardStats(); $procStats = $this->procurementService->getDashboardStats(); // 銷售統計 (本月營收) $thisMonthRevenue = \App\Modules\Sales\Models\SalesImportItem::whereMonth('transaction_at', now()->month) ->whereYear('transaction_at', now()->year) ->sum('amount'); // 生產統計 (待核准工單) $pendingProductionCount = \App\Modules\Production\Models\ProductionOrder::where('status', 'pending')->count(); // 生產狀態分佈 // 近30日銷售趨勢 (Area Chart) $startDate = now()->subDays(29)->startOfDay(); $salesData = \App\Modules\Sales\Models\SalesImportItem::where('transaction_at', '>=', $startDate) ->selectRaw('DATE(transaction_at) as date, SUM(amount) as total') ->groupBy('date') ->orderBy('date') ->get() ->mapWithKeys(function ($item) { return [$item->date => (int)$item->total]; }); $salesTrend = []; for ($i = 0; $i < 30; $i++) { $date = $startDate->copy()->addDays($i)->format('Y-m-d'); $salesTrend[] = [ 'date' => $startDate->copy()->addDays($i)->format('m/d'), 'amount' => $salesData[$date] ?? 0, ]; } // 本月熱銷商品 Top 5 (Bar Chart) $topSellingProducts = \App\Modules\Sales\Models\SalesImportItem::with('product') ->whereMonth('transaction_at', now()->month) ->whereYear('transaction_at', now()->year) ->select('product_code', 'product_id', \Illuminate\Support\Facades\DB::raw('SUM(amount) as total_amount')) ->groupBy('product_code', 'product_id') ->orderByDesc('total_amount') ->limit(5) ->get() ->map(function ($item) { return [ 'name' => $item->product ? $item->product->name : $item->product_code, 'amount' => (int)$item->total_amount, ]; }); // 庫存積壓排行 (Top Inventory Value) $topInventoryValue = \App\Modules\Inventory\Models\Inventory::with('product') ->select('product_id', \Illuminate\Support\Facades\DB::raw('SUM(quantity * unit_cost) as total_value')) ->where('quantity', '>', 0) ->groupBy('product_id') ->orderByDesc('total_value') ->limit(5) ->get() ->map(function ($item) { return [ 'name' => $item->product ? $item->product->name : 'Unknown Product', 'code' => $item->product ? $item->product->code : '', 'value' => (int)$item->total_value, ]; }); // 熱銷數量排行 (Top Selling by Quantity) $topSellingByQuantity = \App\Modules\Sales\Models\SalesImportItem::with('product') ->whereMonth('transaction_at', now()->month) ->whereYear('transaction_at', now()->year) ->select('product_code', 'product_id', \Illuminate\Support\Facades\DB::raw('SUM(quantity) as total_quantity')) ->groupBy('product_code', 'product_id') ->orderByDesc('total_quantity') ->limit(5) ->get() ->map(function ($item) { return [ 'name' => $item->product ? $item->product->name : $item->product_code, 'code' => $item->product_code, 'value' => (int)$item->total_quantity, ]; }); // 即將過期商品 (Expiring Soon) $expiringSoon = \App\Modules\Inventory\Models\Inventory::with('product') ->where('quantity', '>', 0) ->whereNotNull('expiry_date') ->where('expiry_date', '>=', now()) // 只顯示未過期但即將過期的 ->orderBy('expiry_date', 'asc') ->limit(5) ->get() ->map(function ($item) { return [ 'name' => $item->product ? $item->product->name : 'Unknown Product', 'batch_number' => $item->batch_number, 'expiry_date' => $item->expiry_date->format('Y-m-d'), 'quantity' => (int)$item->quantity, ]; }); return Inertia::render('Dashboard', [ 'stats' => [ 'totalItems' => $invStats['productsCount'], 'lowStockCount' => $invStats['lowStockCount'], 'negativeCount' => $invStats['negativeCount'] ?? 0, 'expiringCount' => $invStats['expiringCount'] ?? 0, 'totalInventoryValue' => $invStats['totalInventoryValue'] ?? 0, 'thisMonthRevenue' => $thisMonthRevenue, 'pendingOrdersCount' => $procStats['pendingOrdersCount'] ?? 0, 'pendingTransferCount' => $invStats['pendingTransferCount'] ?? 0, 'pendingProductionCount' => $pendingProductionCount, 'todoCount' => ($procStats['pendingOrdersCount'] ?? 0) + ($invStats['pendingTransferCount'] ?? 0) + $pendingProductionCount, 'salesTrend' => $salesTrend, 'topSellingProducts' => $topSellingProducts, 'topInventoryValue' => $topInventoryValue, 'topSellingByQuantity' => $topSellingByQuantity, 'expiringSoon' => $expiringSoon, ], ]); } }