whereIn('status', $statuses) ->whereBetween('created_at', [$start . ' 00:00:00', $end . ' 23:59:59']) ->get(); } public function getPurchaseOrdersByIds(array $ids, array $with = []): Collection { return PurchaseOrder::whereIn('id', $ids)->with($with)->get(); } public function getDashboardStats(): array { return [ 'vendorsCount' => \App\Modules\Procurement\Models\Vendor::count(), 'purchaseOrdersCount' => PurchaseOrder::count(), 'pendingOrdersCount' => PurchaseOrder::whereIn('status', ['approved', 'partial'])->count(), // 改為真正待進貨的狀態 ]; } public function updateReceivedQuantity(int $poItemId, float $quantity): void { $item = \App\Modules\Procurement\Models\PurchaseOrderItem::findOrFail($poItemId); $item->increment('received_quantity', $quantity); $item->refresh(); // Check PO status $po = $item->purchaseOrder; // Load items to check completion $po->load('items'); $allReceived = $po->items->every(function ($i) { return $i->received_quantity >= $i->quantity; }); $anyReceived = $po->items->contains(function ($i) { return $i->received_quantity > 0; }); if ($allReceived) { $po->status = 'completed'; // or 'received' based on workflow } elseif ($anyReceived) { $po->status = 'partial'; } $po->save(); } public function searchPendingPurchaseOrders(string $query): Collection { return PurchaseOrder::with(['vendor', 'items']) ->whereIn('status', ['approved', 'partial']) ->where(function($q) use ($query) { $q->where('code', 'like', "%{$query}%") ->orWhereHas('vendor', function($vq) use ($query) { $vq->where('name', 'like', "%{$query}%"); }); }) ->limit(20) ->get(); } public function searchVendors(string $query): Collection { return \App\Modules\Procurement\Models\Vendor::where('name', 'like', "%{$query}%") ->orWhere('code', 'like', "%{$query}%") ->limit(20) ->get(['id', 'name', 'code']); } public function getPendingPurchaseOrders(): Collection { return PurchaseOrder::with(['vendor', 'items']) ->whereIn('status', ['approved', 'partial']) ->orderBy('created_at', 'desc') ->limit(50) ->get(); } public function getAllVendors(): Collection { return \App\Modules\Procurement\Models\Vendor::orderBy('name')->get(['id', 'name', 'code']); } public function getVendorsByIds(array $ids): Collection { return \App\Modules\Procurement\Models\Vendor::whereIn('id', $ids)->get(['id', 'name', 'code']); } public function attachProductToVendor(int $vendorId, int $productId, ?float $lastPrice): void { \Illuminate\Support\Facades\DB::table('product_vendor')->insert([ 'vendor_id' => $vendorId, 'product_id' => $productId, 'last_price' => $lastPrice, 'created_at' => now(), 'updated_at' => now(), ]); } public function updateVendorProductPrice(int $vendorId, int $productId, ?float $lastPrice): void { \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->where('product_id', $productId) ->update([ 'last_price' => $lastPrice, 'updated_at' => now(), ]); } public function checkVendorHasProduct(int $vendorId, int $productId): bool { return \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->where('product_id', $productId) ->exists(); } public function getVendorProductPrice(int $vendorId, int $productId): ?float { $pivot = \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->where('product_id', $productId) ->first(); return $pivot ? (float) $pivot->last_price : null; } public function detachProductFromVendor(int $vendorId, int $productId): void { \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->where('product_id', $productId) ->delete(); } public function syncVendorProducts(int $vendorId, array $productsData): void { \Illuminate\Support\Facades\DB::transaction(function () use ($vendorId, $productsData) { $existingPivots = \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->get(); $existingProductIds = $existingPivots->pluck('product_id')->toArray(); $newProductIds = array_column($productsData, 'product_id'); $toDelete = array_diff($existingProductIds, $newProductIds); if (!empty($toDelete)) { \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->whereIn('product_id', $toDelete) ->delete(); } foreach ($productsData as $data) { $exists = in_array($data['product_id'], $existingProductIds); if ($exists) { \Illuminate\Support\Facades\DB::table('product_vendor') ->where('vendor_id', $vendorId) ->where('product_id', $data['product_id']) ->update([ 'last_price' => $data['last_price'] ?? null, 'updated_at' => now(), ]); } else { \Illuminate\Support\Facades\DB::table('product_vendor') ->insert([ 'vendor_id' => $vendorId, 'product_id' => $data['product_id'], 'last_price' => $data['last_price'] ?? null, 'created_at' => now(), 'updated_at' => now(), ]); } } }); } }