From 8b12f4fdcb7a0f2777efaf4f0b94e87dd061a1a1 Mon Sep 17 00:00:00 2001 From: Manus Date: Sun, 12 Apr 2026 12:23:48 -0400 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Modification=20du=20nommage=20des?= =?UTF-8?q?=20PDFs=20BAP=20t=C3=A9l=C3=A9charg=C3=A9s=20:=20format=20"AAAA?= =?UTF-8?q?-MM-JJ=20-=20Fournisseur=20-=20N=C2=B0Facture.pdf"=20dans=20Bap?= =?UTF-8?q?History.tsx=20et=20InvoicesBAP.tsx.=20Les=20param=C3=A8tres=20i?= =?UTF-8?q?nvoiceNumber=20et=20validatedAt=20sont=20pass=C3=A9s=20=C3=A0?= =?UTF-8?q?=20la=20fonction=20downloadBapPdf.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/BapHistory.tsx | 23 ++++++++++++++++++----- client/src/pages/InvoicesBAP.tsx | 23 +++++++++++++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/client/src/pages/BapHistory.tsx b/client/src/pages/BapHistory.tsx index e037840..367e894 100644 --- a/client/src/pages/BapHistory.tsx +++ b/client/src/pages/BapHistory.tsx @@ -24,13 +24,26 @@ import { // Helper : télécharge un PDF annoté BAP depuis son URL de stockage // pdfUrl peut être : '/storage/2026-04/BAP_xxx.pdf' ou '/storage/BAP_xxx.pdf' -function downloadBapPdf(pdfUrl: string, supplierName?: string | null) { - const filename = pdfUrl.split('/').pop() || 'BAP.pdf'; - // Utiliser le query param pdfPath pour passer le chemin complet au serveur +// Nommage : AAAA-MM-JJ - Fournisseur - N°Facture.pdf +function downloadBapPdf( + pdfUrl: string, + supplierName?: string | null, + invoiceNumber?: string | null, + validatedAt?: Date | string | null +) { + const fallback = pdfUrl.split('/').pop() || 'BAP.pdf'; const downloadUrl = `/api/download-bap?pdfPath=${encodeURIComponent(pdfUrl)}`; + // Construire le nom de fichier : date - fournisseur - numero.pdf + const datePart = validatedAt + ? new Date(validatedAt).toLocaleDateString('fr-CA') // format AAAA-MM-JJ + : ''; + const supplierPart = (supplierName || '').replace(/[^a-zA-Z0-9à-ÿ \-]/g, '').trim(); + const numberPart = (invoiceNumber || '').replace(/[^a-zA-Z0-9\-]/g, '').trim(); + const parts = [datePart, supplierPart, numberPart].filter(Boolean); + const filename = parts.length > 0 ? `${parts.join(' - ')}.pdf` : fallback; const a = document.createElement('a'); a.href = downloadUrl; - a.download = supplierName ? `BAP_${supplierName.replace(/[^a-zA-Z0-9]/g, '_')}.pdf` : filename; + a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); @@ -266,7 +279,7 @@ export default function BapHistory() { variant="ghost" size="sm" className="h-7 px-2 text-emerald-600 hover:text-emerald-700 hover:bg-emerald-50" - onClick={() => downloadBapPdf(entry.pdfUrl!, entry.supplierName)} + onClick={() => downloadBapPdf(entry.pdfUrl!, entry.supplierName, entry.invoiceNumber, entry.validatedAt)} title="Télécharger le PDF annoté" > diff --git a/client/src/pages/InvoicesBAP.tsx b/client/src/pages/InvoicesBAP.tsx index 9f767d7..e8fc37d 100644 --- a/client/src/pages/InvoicesBAP.tsx +++ b/client/src/pages/InvoicesBAP.tsx @@ -35,14 +35,25 @@ import { trpc } from "@/lib/trpc"; import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash, CheckCircle, CheckCircle2, ShieldCheck } from "lucide-react"; // Helper : télécharge un PDF annoté BAP depuis son URL de stockage -// pdfUrl peut être : '/storage/2026-04/BAP_xxx.pdf' ou '/storage/BAP_xxx.pdf' -function downloadBapPdf(pdfUrl: string, supplierName?: string) { - const filename = pdfUrl.split('/').pop() || 'BAP.pdf'; - // Utiliser le query param pdfPath pour passer le chemin complet au serveur +// Nommage : AAAA-MM-JJ - Fournisseur - N°Facture.pdf +function downloadBapPdf( + pdfUrl: string, + supplierName?: string, + invoiceNumber?: string | null, + validatedAt?: Date | string | null +) { + const fallback = pdfUrl.split('/').pop() || 'BAP.pdf'; const downloadUrl = `/api/download-bap?pdfPath=${encodeURIComponent(pdfUrl)}`; + const datePart = validatedAt + ? new Date(validatedAt).toLocaleDateString('fr-CA') // AAAA-MM-JJ + : new Date().toLocaleDateString('fr-CA'); + const supplierPart = (supplierName || '').replace(/[^a-zA-Z0-9à-ÿ \-]/g, '').trim(); + const numberPart = (invoiceNumber || '').replace(/[^a-zA-Z0-9\-]/g, '').trim(); + const parts = [datePart, supplierPart, numberPart].filter(Boolean); + const filename = parts.length > 0 ? `${parts.join(' - ')}.pdf` : fallback; const a = document.createElement('a'); a.href = downloadUrl; - a.download = supplierName ? `BAP_${supplierName.replace(/[^a-zA-Z0-9]/g, '_')}.pdf` : filename; + a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); @@ -713,7 +724,7 @@ export default function InvoicesBAP() { variant="outline" className="h-8 px-2 text-blue-600 border-blue-300 hover:bg-blue-50" title="Télécharger le PDF annoté BAP" - onClick={() => downloadBapPdf(bapPdfUrls[invoice.id], invoice.supplierName || undefined)} + onClick={() => downloadBapPdf(bapPdfUrls[invoice.id], invoice.supplierName || undefined, invoice.invoiceNumber, invoice.bapValidatedAt)} >