purchaseOrderRepository->all(); return PurchaseOrderResource::collection($purchaseOrders); } catch (\Exception $e) { Log::error('Error fetching purchase orders: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), ]); return response()->json([ 'message' => 'Une erreur est survenue lors de la récupération des commandes fournisseurs.', 'error' => config('app.debug') ? $e->getMessage() : null, ], 500); } } /** * Store a newly created purchase order. */ public function store(StorePurchaseOrderRequest $request): PurchaseOrderResource|JsonResponse { try { $purchaseOrder = $this->purchaseOrderRepository->create($request->validated()); return new PurchaseOrderResource($purchaseOrder); } catch (\Exception $e) { Log::error('Error creating purchase order: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), 'data' => $request->validated(), ]); return response()->json([ 'message' => 'Une erreur est survenue lors de la création de la commande fournisseur.', 'error' => config('app.debug') ? $e->getMessage() : null, ], 500); } } /** * Display the specified purchase order. */ public function show(string $id): PurchaseOrderResource|JsonResponse { try { $purchaseOrder = $this->purchaseOrderRepository->find($id); if (!$purchaseOrder) { return response()->json([ 'message' => 'Commande fournisseur non trouvée.', ], 404); } return new PurchaseOrderResource($purchaseOrder); } catch (\Exception $e) { Log::error('Error fetching purchase order: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), 'purchase_order_id' => $id, ]); return response()->json([ 'message' => 'Une erreur est survenue lors de la récupération de la commande fournisseur.', 'error' => config('app.debug') ? $e->getMessage() : null, ], 500); } } /** * Update the specified purchase order. */ public function update(UpdatePurchaseOrderRequest $request, string $id): PurchaseOrderResource|JsonResponse { try { $existingPurchaseOrder = $this->purchaseOrderRepository->find($id); $previousStatus = $existingPurchaseOrder?->status; $updated = $this->purchaseOrderRepository->update($id, $request->validated()); if (!$updated) { return response()->json([ 'message' => 'Commande fournisseur non trouvée ou échec de la mise à jour.', ], 404); } $purchaseOrder = $this->purchaseOrderRepository->find($id); // On validation/delivery (status => confirmee|livree), create a draft goods receipt automatically. if ( $purchaseOrder && in_array($purchaseOrder->status, ['confirmee', 'livree'], true) && !in_array($previousStatus, ['confirmee', 'livree'], true) ) { $this->createGoodsReceiptFromValidatedPurchaseOrder($purchaseOrder); } return new PurchaseOrderResource($purchaseOrder); } catch (\Exception $e) { Log::error('Error updating purchase order: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), 'purchase_order_id' => $id, 'data' => $request->validated(), ]); return response()->json([ 'message' => 'Une erreur est survenue lors de la mise à jour de la commande fournisseur.', 'error' => config('app.debug') ? $e->getMessage() : null, ], 500); } } /** * Create a draft goods receipt when a purchase order is validated. */ protected function createGoodsReceiptFromValidatedPurchaseOrder($purchaseOrder): void { $alreadyExists = GoodsReceipt::query() ->where('purchase_order_id', $purchaseOrder->id) ->exists(); if ($alreadyExists) { return; } $warehouseId = Warehouse::query()->value('id'); if (!$warehouseId) { throw new \RuntimeException('Aucun entrepôt disponible pour créer la réception de marchandise.'); } $receiptNumber = 'GR-' . now()->format('Ym') . '-' . str_pad((string) $purchaseOrder->id, 4, '0', STR_PAD_LEFT); $lines = collect($purchaseOrder->lines ?? []) ->filter(fn($line) => !empty($line->product_id)) ->map(function ($line) { return [ 'product_id' => (int) $line->product_id, 'packaging_id' => null, 'packages_qty_received' => null, 'units_qty_received' => (float) $line->quantity, 'qty_received_base' => (float) $line->quantity, 'unit_price' => (float) $line->unit_price, 'unit_price_per_package' => null, 'tva_rate_id' => null, ]; }) ->values() ->all(); $this->goodsReceiptRepository->create([ 'purchase_order_id' => $purchaseOrder->id, 'warehouse_id' => (int) $warehouseId, 'receipt_number' => $receiptNumber, 'receipt_date' => now()->toDateString(), 'status' => 'draft', 'lines' => $lines, ]); } /** * Remove the specified purchase order. */ public function destroy(string $id): JsonResponse { try { $deleted = $this->purchaseOrderRepository->delete($id); if (!$deleted) { return response()->json([ 'message' => 'Commande fournisseur non trouvée ou échec de la suppression.', ], 404); } return response()->json([ 'message' => 'Commande fournisseur supprimée avec succès.', ], 200); } catch (\Exception $e) { Log::error('Error deleting purchase order: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), 'purchase_order_id' => $id, ]); return response()->json([ 'message' => 'Une erreur est survenue lors de la suppression de la commande fournisseur.', 'error' => config('app.debug') ? $e->getMessage() : null, ], 500); } } }