diff --git a/thanasoft-back/app/Http/Controllers/Api/PurchaseOrderController.php b/thanasoft-back/app/Http/Controllers/Api/PurchaseOrderController.php new file mode 100644 index 0000000..0d39d71 --- /dev/null +++ b/thanasoft-back/app/Http/Controllers/Api/PurchaseOrderController.php @@ -0,0 +1,156 @@ +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 { + $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); + 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); + } + } + + /** + * 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); + } + } +} diff --git a/thanasoft-back/app/Http/Requests/StorePurchaseOrderRequest.php b/thanasoft-back/app/Http/Requests/StorePurchaseOrderRequest.php new file mode 100644 index 0000000..f3ff1ee --- /dev/null +++ b/thanasoft-back/app/Http/Requests/StorePurchaseOrderRequest.php @@ -0,0 +1,80 @@ +|string> + */ + public function rules(): array + { + return [ + 'fournisseur_id' => ['required', 'exists:fournisseurs,id'], + 'po_number' => ['nullable', 'string', 'max:191', 'unique:purchase_orders,po_number'], + 'status' => ['nullable', 'in:brouillon,confirmee,livree,facturee,annulee'], + 'order_date' => ['nullable', 'date'], + 'expected_date' => ['nullable', 'date'], + 'currency' => ['nullable', 'string', 'size:3'], + 'total_ht' => ['required', 'numeric', 'min:0'], + 'total_tva' => ['required', 'numeric', 'min:0'], + 'total_ttc' => ['required', 'numeric', 'min:0'], + 'notes' => ['nullable', 'string'], + 'delivery_address' => ['nullable', 'string'], + 'lines' => ['required', 'array', 'min:1'], + 'lines.*.product_id' => ['nullable', 'exists:products,id'], + 'lines.*.description' => ['required', 'string'], + 'lines.*.quantity' => ['required', 'numeric', 'min:0.001'], + 'lines.*.unit_price' => ['required', 'numeric', 'min:0'], + 'lines.*.tva_rate' => ['required', 'numeric', 'min:0'], + 'lines.*.discount_pct' => ['nullable', 'numeric', 'min:0', 'max:100'], + 'lines.*.total_ht' => ['required', 'numeric', 'min:0'], + ]; + } + + /** + * Get the error messages for the defined validation rules. + * + * @return array + */ + public function messages(): array + { + return [ + 'fournisseur_id.required' => 'Le fournisseur est obligatoire.', + 'fournisseur_id.exists' => 'Le fournisseur sélectionné est invalide.', + 'po_number.unique' => 'Ce numéro de commande existe déjà.', + 'order_date.date' => 'La date de commande n\'est pas valide.', + 'expected_date.date' => 'La date de livraison prévue n\'est pas valide.', + 'status.in' => 'Le statut sélectionné est invalide.', + 'total_ht.required' => 'Le total HT est obligatoire.', + 'total_tva.required' => 'Le total TVA est obligatoire.', + 'total_ttc.required' => 'Le total TTC est obligatoire.', + 'lines.required' => 'Au moins une ligne d\'article est requise.', + 'lines.array' => 'Les lignes doivent être un tableau.', + 'lines.min' => 'Vous devez ajouter au moins une ligne d\'article.', + 'lines.*.description.required' => 'La désignation est obligatoire pour toutes les lignes.', + 'lines.*.quantity.required' => 'La quantité est obligatoire.', + 'lines.*.quantity.numeric' => 'La quantité doit être un nombre.', + 'lines.*.quantity.min' => 'La quantité doit être supérieure à 0.', + 'lines.*.unit_price.required' => 'Le prix unitaire est obligatoire.', + 'lines.*.unit_price.numeric' => 'Le prix unitaire doit être un nombre.', + 'lines.*.unit_price.min' => 'Le prix unitaire doit être positif.', + 'lines.*.tva_rate.required' => 'Le taux de TVA est obligatoire.', + 'lines.*.total_ht.required' => 'Le total HT de la ligne est obligatoire.', + ]; + } +} diff --git a/thanasoft-back/app/Http/Requests/UpdatePurchaseOrderRequest.php b/thanasoft-back/app/Http/Requests/UpdatePurchaseOrderRequest.php new file mode 100644 index 0000000..82576d2 --- /dev/null +++ b/thanasoft-back/app/Http/Requests/UpdatePurchaseOrderRequest.php @@ -0,0 +1,48 @@ +|string> + */ + public function rules(): array + { + return [ + 'fournisseur_id' => ['nullable', 'exists:fournisseurs,id'], + 'po_number' => ['nullable', 'string', 'max:191', 'unique:purchase_orders,po_number,' . $this->route('purchase_order')], + 'status' => ['nullable', 'in:brouillon,confirmee,livree,facturee,annulee'], + 'order_date' => ['nullable', 'date'], + 'expected_date' => ['nullable', 'date'], + 'currency' => ['nullable', 'string', 'size:3'], + 'total_ht' => ['nullable', 'numeric', 'min:0'], + 'total_tva' => ['nullable', 'numeric', 'min:0'], + 'total_ttc' => ['nullable', 'numeric', 'min:0'], + 'notes' => ['nullable', 'string'], + 'delivery_address' => ['nullable', 'string'], + 'lines' => ['nullable', 'array', 'min:1'], + 'lines.*.product_id' => ['nullable', 'exists:products,id'], + 'lines.*.description' => ['required', 'string'], + 'lines.*.quantity' => ['required', 'numeric', 'min:0.001'], + 'lines.*.unit_price' => ['required', 'numeric', 'min:0'], + 'lines.*.tva_rate' => ['required', 'numeric', 'min:0'], + 'lines.*.discount_pct' => ['nullable', 'numeric', 'min:0', 'max:100'], + 'lines.*.total_ht' => ['required', 'numeric', 'min:0'], + ]; + } +} diff --git a/thanasoft-back/app/Http/Resources/Fournisseur/PurchaseOrderResource.php b/thanasoft-back/app/Http/Resources/Fournisseur/PurchaseOrderResource.php new file mode 100644 index 0000000..dce42cc --- /dev/null +++ b/thanasoft-back/app/Http/Resources/Fournisseur/PurchaseOrderResource.php @@ -0,0 +1,38 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'fournisseur_id' => $this->fournisseur_id, + 'fournisseur' => $this->whenLoaded('fournisseur'), + 'po_number' => $this->po_number, + 'status' => $this->status, + 'order_date' => $this->order_date ? $this->order_date->format('Y-m-d') : null, + 'expected_date' => $this->expected_date ? $this->expected_date->format('Y-m-d') : null, + 'currency' => $this->currency, + 'total_ht' => $this->total_ht, + 'total_tva' => $this->total_tva, + 'total_ttc' => $this->total_ttc, + 'notes' => $this->notes, + 'delivery_address' => $this->delivery_address, + 'lines' => $this->whenLoaded('lines'), + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/thanasoft-back/app/Models/PurchaseOrder.php b/thanasoft-back/app/Models/PurchaseOrder.php new file mode 100644 index 0000000..88a73b0 --- /dev/null +++ b/thanasoft-back/app/Models/PurchaseOrder.php @@ -0,0 +1,69 @@ +po_number)) { + $prefix = 'CMD-' . now()->format('Ym') . '-'; + $lastOrder = self::where('po_number', 'like', $prefix . '%') + ->orderBy('po_number', 'desc') + ->first(); + + if ($lastOrder) { + $lastNumber = intval(substr($lastOrder->po_number, -4)); + $newNumber = $lastNumber + 1; + } else { + $newNumber = 1; + } + + $purchaseOrder->po_number = $prefix . str_pad((string)$newNumber, 4, '0', STR_PAD_LEFT); + } + }); + } + + protected $fillable = [ + 'fournisseur_id', + 'po_number', + 'status', + 'order_date', + 'expected_date', + 'currency', + 'total_ht', + 'total_tva', + 'total_ttc', + 'notes', + 'delivery_address', + ]; + + protected $casts = [ + 'order_date' => 'date', + 'expected_date' => 'date', + 'total_ht' => 'decimal:2', + 'total_tva' => 'decimal:2', + 'total_ttc' => 'decimal:2', + ]; + + public function fournisseur(): BelongsTo + { + return $this->belongsTo(Fournisseur::class); + } + + public function lines(): HasMany + { + return $this->hasMany(PurchaseOrderLine::class); + } +} diff --git a/thanasoft-back/app/Models/PurchaseOrderLine.php b/thanasoft-back/app/Models/PurchaseOrderLine.php new file mode 100644 index 0000000..922f2b3 --- /dev/null +++ b/thanasoft-back/app/Models/PurchaseOrderLine.php @@ -0,0 +1,43 @@ + 'decimal:3', + 'unit_price' => 'decimal:2', + 'tva_rate' => 'decimal:2', + 'discount_pct' => 'decimal:2', + 'total_ht' => 'decimal:2', + ]; + + public function purchaseOrder(): BelongsTo + { + return $this->belongsTo(PurchaseOrder::class); + } + + public function product(): BelongsTo + { + return $this->belongsTo(Product::class); + } +} diff --git a/thanasoft-back/app/Providers/AppServiceProvider.php b/thanasoft-back/app/Providers/AppServiceProvider.php index c5414be..cf3bfee 100644 --- a/thanasoft-back/app/Providers/AppServiceProvider.php +++ b/thanasoft-back/app/Providers/AppServiceProvider.php @@ -105,6 +105,9 @@ class AppServiceProvider extends ServiceProvider $this->app->bind(\App\Repositories\QuoteLineRepositoryInterface::class, \App\Repositories\QuoteLineRepository::class); $this->app->bind(\App\Repositories\ClientActivityTimelineRepositoryInterface::class, \App\Repositories\ClientActivityTimelineRepository::class); + + $this->app->bind(\App\Repositories\PurchaseOrderRepositoryInterface::class, \App\Repositories\PurchaseOrderRepository::class); + $this->app->bind(\App\Repositories\DeceasedDocumentRepositoryInterface::class, \App\Repositories\DeceasedDocumentRepository::class); } diff --git a/thanasoft-back/app/Providers/RepositoryServiceProvider.php b/thanasoft-back/app/Providers/RepositoryServiceProvider.php index 2c59e19..cf70563 100644 --- a/thanasoft-back/app/Providers/RepositoryServiceProvider.php +++ b/thanasoft-back/app/Providers/RepositoryServiceProvider.php @@ -23,6 +23,7 @@ class RepositoryServiceProvider extends ServiceProvider $this->app->bind(DeceasedDocumentRepositoryInterface::class, DeceasedDocumentRepository::class); $this->app->bind(InterventionRepositoryInterface::class, InterventionRepository::class); $this->app->bind(FileRepositoryInterface::class, FileRepository::class); + $this->app->bind(\App\Repositories\PurchaseOrderRepositoryInterface::class, \App\Repositories\PurchaseOrderRepository::class); } diff --git a/thanasoft-back/app/Repositories/PurchaseOrderRepository.php b/thanasoft-back/app/Repositories/PurchaseOrderRepository.php new file mode 100644 index 0000000..46a366a --- /dev/null +++ b/thanasoft-back/app/Repositories/PurchaseOrderRepository.php @@ -0,0 +1,86 @@ +model->with(['fournisseur', 'lines.product'])->get($columns); + } + + public function find(int|string $id, array $columns = ['*']): ?PurchaseOrder + { + return $this->model->with(['fournisseur', 'lines.product'])->find($id, $columns); + } + + public function create(array $attributes): PurchaseOrder + { + return DB::transaction(function () use ($attributes) { + try { + $lines = $attributes['lines'] ?? []; + unset($attributes['lines']); + + $purchaseOrder = parent::create($attributes); + + foreach ($lines as $line) { + $purchaseOrder->lines()->create($line); + } + + return $purchaseOrder->load('lines.product'); + } catch (\Exception $e) { + Log::error('Error creating PurchaseOrder with lines: ' . $e->getMessage(), [ + 'attributes' => $attributes, + 'exception' => $e + ]); + throw $e; + } + }); + } + + public function update(int|string $id, array $attributes): bool + { + return DB::transaction(function () use ($id, $attributes) { + try { + $purchaseOrder = $this->find($id); + if (!$purchaseOrder) { + return false; + } + + $lines = $attributes['lines'] ?? null; + unset($attributes['lines']); + + $updated = parent::update($id, $attributes); + + if ($lines !== null && $updated) { + $purchaseOrder->lines()->delete(); + foreach ($lines as $line) { + $purchaseOrder->lines()->create($line); + } + } + + return $updated; + } catch (\Exception $e) { + Log::error('Error updating PurchaseOrder with lines: ' . $e->getMessage(), [ + 'id' => $id, + 'attributes' => $attributes, + 'exception' => $e + ]); + throw $e; + } + }); + } +} diff --git a/thanasoft-back/app/Repositories/PurchaseOrderRepositoryInterface.php b/thanasoft-back/app/Repositories/PurchaseOrderRepositoryInterface.php new file mode 100644 index 0000000..78c8c01 --- /dev/null +++ b/thanasoft-back/app/Repositories/PurchaseOrderRepositoryInterface.php @@ -0,0 +1,9 @@ +group(function () { // Fournisseur management Route::get('/fournisseurs/searchBy', [FournisseurController::class, 'searchBy']); + Route::apiResource('purchase-orders', PurchaseOrderController::class); Route::apiResource('fournisseurs', FournisseurController::class); Route::get('fournisseurs/{fournisseurId}/contacts', [ContactController::class, 'getContactsByFournisseur']); diff --git a/thanasoft-front/src/components/Organism/Avoir/AvoirListPresentation.vue b/thanasoft-front/src/components/Organism/Avoir/AvoirListPresentation.vue index 94bd7ec..2860ed0 100644 --- a/thanasoft-front/src/components/Organism/Avoir/AvoirListPresentation.vue +++ b/thanasoft-front/src/components/Organism/Avoir/AvoirListPresentation.vue @@ -8,7 +8,7 @@
{ - if (!activeFilter.value) { - return avoirs.value; - } - return avoirs.value.filter(avoir => avoir.status === activeFilter.value); -}); +const handleFilter = (status) => { + activeFilter.value = status; + avoirStore.fetchAvoirs({ status: status || undefined }); +}; const openCreateModal = () => { router.push("/avoirs/new"); @@ -98,13 +44,8 @@ const handleView = (id) => { router.push(`/avoirs/${id}`); }; -const handleFilter = (status) => { - activeFilter.value = status; -}; - const handleExport = () => { - // Export filtered avoirs to CSV - const dataToExport = filteredAvoirs.value; + const dataToExport = avoirs.value; const headers = [ "N° Avoir", "Date", @@ -118,17 +59,16 @@ const handleExport = () => { headers.join(","), ...dataToExport.map((avoir) => [ - avoir.number, - avoir.date.toLocaleDateString("fr-FR"), + avoir.avoir_number, + new Date(avoir.avoir_date).toLocaleDateString("fr-FR"), getStatusLabel(avoir.status), - avoir.clientName, - avoir.invoiceNumber, - avoir.amount.toFixed(2) + " EUR", + avoir.client?.name || "N/A", + avoir.invoice?.invoice_number || "N/A", + (avoir.total_ttc || 0).toFixed(2) + " EUR", ].join(",") ), ].join("\n"); - // Create blob and download const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" }); const link = document.createElement("a"); const url = URL.createObjectURL(blob); @@ -154,12 +94,20 @@ const getStatusLabel = (status) => { const handleDelete = async (id) => { if (confirm("Êtes-vous sûr de vouloir supprimer cet avoir ?")) { - avoirs.value = avoirs.value.filter((a) => a.id !== id); - alert("Avoir supprimé avec succès"); + try { + await avoirStore.deleteAvoir(id); + alert("Avoir supprimé avec succès"); + } catch (err) { + alert("Erreur lors de la suppression de l'avoir"); + } } }; -onMounted(() => { - loading.value = false; +onMounted(async () => { + try { + await avoirStore.fetchAvoirs(); + } catch (err) { + console.error("Failed to fetch avoirs:", err); + } }); diff --git a/thanasoft-front/src/components/Organism/Commande/CommandeDetailPresentation.vue b/thanasoft-front/src/components/Organism/Commande/CommandeDetailPresentation.vue index e3cf716..6d79e71 100644 --- a/thanasoft-front/src/components/Organism/Commande/CommandeDetailPresentation.vue +++ b/thanasoft-front/src/components/Organism/Commande/CommandeDetailPresentation.vue @@ -98,13 +98,15 @@ diff --git a/thanasoft-front/src/components/Organism/Commande/CommandeListPresentation.vue b/thanasoft-front/src/components/Organism/Commande/CommandeListPresentation.vue index aacd25c..363c919 100644 --- a/thanasoft-front/src/components/Organism/Commande/CommandeListPresentation.vue +++ b/thanasoft-front/src/components/Organism/Commande/CommandeListPresentation.vue @@ -8,7 +8,7 @@
{ - if (!activeFilter.value) { - return commandes.value; - } - return commandes.value.filter(cmd => cmd.status === activeFilter.value); -}); +const handleFilter = (status) => { + activeFilter.value = status; + // If backend supports filtering, we can call fetchPurchaseOrders({ status }) + purchaseOrderStore.fetchPurchaseOrders({ status: status || undefined }); +}; const openCreateModal = () => { router.push("/fournisseurs/commandes/new"); @@ -93,19 +45,14 @@ const handleView = (id) => { router.push(`/fournisseurs/commandes/${id}`); }; -const handleFilter = (status) => { - activeFilter.value = status; -}; - const handleExport = () => { - // Export filtered commandes to CSV - const dataToExport = filteredCommandes.value; + const dataToExport = purchaseOrders.value; const headers = [ "N° Commande", "Date", "Fournisseur", "Statut", - "Montant", + "Montant TTC", "Articles", ]; @@ -113,17 +60,16 @@ const handleExport = () => { headers.join(","), ...dataToExport.map((cmd) => [ - cmd.number, - cmd.date.toLocaleDateString("fr-FR"), - cmd.supplier, + cmd.po_number, + new Date(cmd.order_date).toLocaleDateString("fr-FR"), + cmd.fournisseur?.name || "N/A", getStatusLabel(cmd.status), - cmd.amount.toFixed(2) + " EUR", - cmd.items_count, + (cmd.total_ttc || 0).toFixed(2) + " EUR", + cmd.lines?.length || 0, ].join(",") ), ].join("\n"); - // Create blob and download const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" }); const link = document.createElement("a"); const url = URL.createObjectURL(blob); @@ -150,12 +96,20 @@ const getStatusLabel = (status) => { const handleDelete = async (id) => { if (confirm("Êtes-vous sûr de vouloir supprimer cette commande ?")) { - commandes.value = commandes.value.filter((c) => c.id !== id); - alert("Commande supprimée avec succès"); + try { + await purchaseOrderStore.deletePurchaseOrder(id); + alert("Commande supprimée avec succès"); + } catch (err) { + alert("Erreur lors de la suppression de la commande"); + } } }; -onMounted(() => { - loading.value = false; +onMounted(async () => { + try { + await purchaseOrderStore.fetchPurchaseOrders(); + } catch (err) { + console.error("Failed to fetch purchase orders:", err); + } }); diff --git a/thanasoft-front/src/components/molecules/Commande/NewCommandeForm.vue b/thanasoft-front/src/components/molecules/Commande/NewCommandeForm.vue index d54fbb0..3d8655e 100644 --- a/thanasoft-front/src/components/molecules/Commande/NewCommandeForm.vue +++ b/thanasoft-front/src/components/molecules/Commande/NewCommandeForm.vue @@ -1,218 +1,438 @@ diff --git a/thanasoft-front/src/components/molecules/Tables/Avoirs/AvoirTable.vue b/thanasoft-front/src/components/molecules/Tables/Avoirs/AvoirTable.vue index 6aa8896..075d75b 100644 --- a/thanasoft-front/src/components/molecules/Tables/Avoirs/AvoirTable.vue +++ b/thanasoft-front/src/components/molecules/Tables/Avoirs/AvoirTable.vue @@ -20,7 +20,7 @@

- {{ avoir.number }} + {{ avoir.avoir_number || avoir.number }}

@@ -28,7 +28,7 @@ {{ - formatDate(avoir.date) + formatDate(avoir.avoir_date || avoir.date) }} @@ -60,7 +60,7 @@ circular /> {{ - avoir.clientName || "Client Inconnu" + avoir.client?.name || avoir.clientName || "Client Inconnu" }}
@@ -68,14 +68,14 @@ - {{ avoir.invoiceNumber }} + {{ avoir.invoice?.invoice_number || avoir.invoiceNumber }} {{ - formatCurrency(avoir.amount) + formatCurrency(avoir.total_ttc || avoir.amount) }} diff --git a/thanasoft-front/src/components/molecules/Tables/Fournisseurs/CommandeTable.vue b/thanasoft-front/src/components/molecules/Tables/Fournisseurs/CommandeTable.vue index 8b8e48d..d326c78 100644 --- a/thanasoft-front/src/components/molecules/Tables/Fournisseurs/CommandeTable.vue +++ b/thanasoft-front/src/components/molecules/Tables/Fournisseurs/CommandeTable.vue @@ -20,7 +20,7 @@

- {{ commande.number }} + {{ commande.po_number || commande.number }}

@@ -28,7 +28,7 @@ {{ - formatDate(commande.date) + formatDate(commande.order_date || commande.date) }} @@ -42,7 +42,7 @@ alt="supplier image" circular /> - {{ commande.supplier }} + {{ commande.fournisseur?.name || commande.supplier }}
@@ -66,13 +66,13 @@ {{ - formatCurrency(commande.amount) + formatCurrency(commande.total_ttc || commande.amount) }} - {{ commande.items_count }} + {{ commande.lines?.length || commande.items_count || 0 }}