From 9d71f1e34ad0b7c3048a61250495cb991cd41c1a Mon Sep 17 00:00:00 2001 From: Manus Date: Sun, 12 Apr 2026 10:05:02 -0400 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Ajout=20du=20bouton=20de=20t?= =?UTF-8?q?=C3=A9l=C3=A9chargement=20direct=20du=20PDF=20annot=C3=A9=20BAP?= =?UTF-8?q?=20:=20route=20Express=20/api/download-bap/:filename=20avec=20C?= =?UTF-8?q?ontent-Disposition=20attachment,=20bouton=20T=C3=A9l=C3=A9charg?= =?UTF-8?q?er=20dans=20InvoicesBAP=20(appara=C3=AEt=20apr=C3=A8s=20validat?= =?UTF-8?q?ion),=20boutons=20Voir=20+=20T=C3=A9l=C3=A9charger=20dans=20l'H?= =?UTF-8?q?istorique=20BAP.=20Correction=20du=20layout=20PDF=20(2=20colonn?= =?UTF-8?q?es)=20=C3=A9galement=20incluse.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/BapHistory.tsx | 43 +++++++++++++++++++++++++------- client/src/pages/InvoicesBAP.tsx | 43 +++++++++++++++++++++++++++----- server/_core/index.ts | 15 +++++++++++ server/routers.ts | 1 + 4 files changed, 87 insertions(+), 15 deletions(-) diff --git a/client/src/pages/BapHistory.tsx b/client/src/pages/BapHistory.tsx index 9556686..28d663d 100644 --- a/client/src/pages/BapHistory.tsx +++ b/client/src/pages/BapHistory.tsx @@ -19,8 +19,21 @@ import { Building2, User, FileText, + Download, } from "lucide-react"; +// Helper : télécharge un PDF annoté BAP depuis son URL de stockage +function downloadBapPdf(pdfUrl: string, supplierName?: string | null) { + const filename = pdfUrl.split('/').pop() || 'BAP.pdf'; + const downloadUrl = `/api/download-bap/${filename}`; + const a = document.createElement('a'); + a.href = downloadUrl; + a.download = supplierName ? `BAP_${supplierName.replace(/[^a-zA-Z0-9]/g, '_')}.pdf` : filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); +} + export default function BapHistory() { const { data: entries, isLoading, refetch } = trpc.bapHistory.getAll.useQuery(); const deleteMutation = trpc.bapHistory.delete.useMutation(); @@ -236,15 +249,27 @@ export default function BapHistory() { {entry.exportMode === "browser" && entry.pdfUrl ? ( - +
+ + +
) : entry.exportMode === "folder" && entry.exportPath ? (
diff --git a/client/src/pages/InvoicesBAP.tsx b/client/src/pages/InvoicesBAP.tsx index 2370756..8038ade 100644 --- a/client/src/pages/InvoicesBAP.tsx +++ b/client/src/pages/InvoicesBAP.tsx @@ -33,6 +33,18 @@ import { } from "@/components/ui/table"; 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 +function downloadBapPdf(pdfUrl: string, supplierName?: string) { + const filename = pdfUrl.split('/').pop() || 'BAP.pdf'; + const downloadUrl = `/api/download-bap/${filename}`; + const a = document.createElement('a'); + a.href = downloadUrl; + a.download = supplierName ? `BAP_${supplierName.replace(/[^a-zA-Z0-9]/g, '_')}.pdf` : filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); +} import * as XLSX from 'xlsx'; import { toast } from "sonner"; import { useLocation } from "wouter"; @@ -65,6 +77,8 @@ export default function InvoicesBAP() { const [addDialogType, setAddDialogType] = useState<"service" | "ventilation" | null>(null); const [newItemName, setNewItemName] = useState(""); const [pendingInvoiceId, setPendingInvoiceId] = useState(null); + // Map invoiceId -> pdfUrl après validation BAP (pour bouton téléchargement) + const [bapPdfUrls, setBapPdfUrls] = useState>({}); const [textDialogOpen, setTextDialogOpen] = useState(false); const [selectedInvoiceText, setSelectedInvoiceText] = useState(null); const { data: allInvoices, isLoading } = trpc.invoices.list.useQuery(); @@ -151,6 +165,10 @@ export default function InvoicesBAP() { const validateBAPMutation = trpc.invoices.validateBAP.useMutation({ onSuccess: (data) => { + // Stocker le pdfUrl pour le bouton téléchargement + if (data.invoiceId && data.pdfUrl) { + setBapPdfUrls(prev => ({ ...prev, [data.invoiceId as number]: data.pdfUrl as string })); + } if (data.exportMode === 'browser' && data.pdfUrl) { toast.success("Facture validée BAP ! Ouverture du PDF annoté...", { duration: 3000 }); window.open(data.pdfUrl, '_blank'); @@ -679,12 +697,25 @@ export default function InvoicesBAP() { {invoice.bapValidated === 1 ? ( -
- - Validé +
+
+ + Validé +
+ {bapPdfUrls[invoice.id] && ( + + )}
) : (