Checkpoint: La route /api/download-bap accepte maintenant un param filename et le met dans Content-Disposition (RFC 5987). Les fonctions downloadBapPdf dans InvoicesBAP.tsx et BapHistory.tsx passent le filename formaté dans l'URL.
This commit is contained in:
@@ -30,15 +30,16 @@ function downloadBapPdf(
|
||||
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 supplierPart = (supplierName || '').replace(/[^a-zA-Z0-9\u00e0-\u00ff \-]/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;
|
||||
// Passer le filename au serveur pour qu'il soit dans Content-Disposition
|
||||
const downloadUrl = `/api/download-bap?pdfPath=${encodeURIComponent(pdfUrl)}&filename=${encodeURIComponent(filename)}`;
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl;
|
||||
a.download = filename;
|
||||
|
||||
@@ -43,14 +43,15 @@ function downloadBapPdf(
|
||||
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 supplierPart = (supplierName || '').replace(/[^a-zA-Z0-9\u00e0-\u00ff \-]/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;
|
||||
// Passer le filename au serveur pour qu'il soit dans Content-Disposition
|
||||
const downloadUrl = `/api/download-bap?pdfPath=${encodeURIComponent(pdfUrl)}&filename=${encodeURIComponent(filename)}`;
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl;
|
||||
a.download = filename;
|
||||
|
||||
@@ -61,8 +61,13 @@ async function startServer() {
|
||||
res.status(404).json({ error: "Fichier introuvable" });
|
||||
return;
|
||||
}
|
||||
const filename = path.basename(storagePath);
|
||||
res.setHeader("Content-Disposition", `attachment; filename="${encodeURIComponent(filename)}"`);
|
||||
// Utiliser le nom de fichier fourni par le client (format Date - Fournisseur - N°Facture.pdf)
|
||||
const customFilename = req.query.filename as string | undefined;
|
||||
const fallbackFilename = path.basename(storagePath);
|
||||
const finalFilename = customFilename ? customFilename : fallbackFilename;
|
||||
// RFC 5987 : utiliser filename* pour les caractères non-ASCII
|
||||
const encodedFilename = encodeURIComponent(finalFilename);
|
||||
res.setHeader("Content-Disposition", `attachment; filename="${encodedFilename}"; filename*=UTF-8''${encodedFilename}`);
|
||||
res.setHeader("Content-Type", "application/pdf");
|
||||
res.sendFile(storagePath);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user