mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-11 17:29:48 +02:00
Enhance PDF export to include full sales information and improve layout
Modify SalesHistory component to include complete sales data in PDF export using jsPDF. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e80fed01-7137-4997-b9af-dad57132d430 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/e80fed01-7137-4997-b9af-dad57132d430/lMVWh0V
This commit is contained in:
1 parent
933ea44342
commit
a46a0c63a4
1 file changed
+103
-40
@@ -111,7 +111,7 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
||||
doc.setFont('helvetica');
|
||||
|
||||
doc.setFontSize(16);
|
||||
doc.text('Historique des Ventes de Feux d\'Artifice', 20, 20);
|
||||
doc.text('Registre Détaillé des Ventes de Feux d\'Artifice', 20, 20);
|
||||
|
||||
doc.setFontSize(10);
|
||||
doc.text(`Généré le ${new Date().toLocaleDateString('fr-FR')} à ${new Date().toLocaleTimeString('fr-FR')}`, 20, 30);
|
||||
@@ -121,53 +121,116 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
||||
doc.text(period, 20, 35);
|
||||
}
|
||||
|
||||
// Créer une ligne pour chaque produit de chaque vente
|
||||
const tableData: string[][] = [];
|
||||
|
||||
filteredSales.forEach(sale => {
|
||||
let currentY = startDate || endDate ? 50 : 45;
|
||||
|
||||
// Pour chaque vente, créer une section complète
|
||||
filteredSales.forEach((sale, saleIndex) => {
|
||||
// Vérifier si on a assez de place, sinon nouvelle page
|
||||
if (currentY > 250) {
|
||||
doc.addPage();
|
||||
currentY = 20;
|
||||
}
|
||||
|
||||
// Titre de la vente
|
||||
doc.setFontSize(12);
|
||||
doc.setFont('helvetica', 'bold');
|
||||
doc.text(`VENTE #${sale.id} - ${new Date(sale.timestamp).toLocaleDateString('fr-FR')} ${new Date(sale.timestamp).toLocaleTimeString('fr-FR')}`, 20, currentY);
|
||||
currentY += 10;
|
||||
|
||||
// Informations vendeur
|
||||
doc.setFontSize(10);
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.text(`Vendeur: ${sale.vendeur}`, 20, currentY);
|
||||
currentY += 8;
|
||||
|
||||
// Informations client
|
||||
doc.setFont('helvetica', 'bold');
|
||||
doc.text('INFORMATIONS CLIENT:', 20, currentY);
|
||||
currentY += 6;
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.text(`Nom: ${sale.nom} ${sale.prenom}`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(`Date de naissance: ${sale.dateNaissance || 'Non spécifiée'}`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(`Lieu de naissance: ${sale.lieuNaissance || 'Non spécifié'}`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(`Mode de paiement: ${sale.modePaiement || 'Non spécifié'}`, 25, currentY);
|
||||
currentY += 8;
|
||||
|
||||
// Informations identité
|
||||
doc.setFont('helvetica', 'bold');
|
||||
doc.text('PIÈCE D\'IDENTITÉ:', 20, currentY);
|
||||
currentY += 6;
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.text(`Type: ${sale.typeIdentite || 'Non spécifié'}`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(`Numéro: ${sale.numeroIdentite || 'Non spécifié'}`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(`Autorité de délivrance: ${sale.autoriteDelivrance || 'Non spécifiée'}`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(`Date de délivrance: ${sale.dateDelivrance || 'Non spécifiée'}`, 25, currentY);
|
||||
currentY += 8;
|
||||
|
||||
// Produits
|
||||
doc.setFont('helvetica', 'bold');
|
||||
doc.text('PRODUITS VENDUS:', 20, currentY);
|
||||
currentY += 6;
|
||||
|
||||
if (sale.products && sale.products.length > 0) {
|
||||
// Pour chaque produit, créer une ligne avec les infos de la vente
|
||||
sale.products.forEach(product => {
|
||||
tableData.push([
|
||||
new Date(sale.timestamp).toLocaleDateString('fr-FR'),
|
||||
sale.vendeur,
|
||||
`${sale.nom} ${sale.prenom}`,
|
||||
product.typeArticle,
|
||||
product.categorie,
|
||||
product.quantite.toString(),
|
||||
sale.modePaiement,
|
||||
product.gencode || ''
|
||||
]);
|
||||
sale.products.forEach((product, productIndex) => {
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.text(`Produit ${productIndex + 1}:`, 25, currentY);
|
||||
currentY += 5;
|
||||
doc.text(` • Type: ${product.typeArticle}`, 30, currentY);
|
||||
currentY += 4;
|
||||
doc.text(` • Catégorie: ${product.categorie}`, 30, currentY);
|
||||
currentY += 4;
|
||||
doc.text(` • Quantité: ${product.quantite}`, 30, currentY);
|
||||
currentY += 4;
|
||||
doc.text(` • Code: ${product.gencode || 'Non spécifié'}`, 30, currentY);
|
||||
currentY += 6;
|
||||
});
|
||||
} else {
|
||||
// Fallback pour les ventes sans produits (anciennes données)
|
||||
tableData.push([
|
||||
new Date(sale.timestamp).toLocaleDateString('fr-FR'),
|
||||
sale.vendeur,
|
||||
`${sale.nom} ${sale.prenom}`,
|
||||
'N/A',
|
||||
'N/A',
|
||||
'0',
|
||||
sale.modePaiement,
|
||||
''
|
||||
]);
|
||||
doc.setFont('helvetica', 'normal');
|
||||
doc.text('Aucun produit enregistré', 25, currentY);
|
||||
currentY += 6;
|
||||
}
|
||||
|
||||
// Photos
|
||||
if (sale.photoRecto || sale.photoVerso || sale.photoTicket) {
|
||||
doc.setFont('helvetica', 'bold');
|
||||
doc.text('DOCUMENTS PHOTOGRAPHIÉS:', 20, currentY);
|
||||
currentY += 6;
|
||||
doc.setFont('helvetica', 'normal');
|
||||
|
||||
if (sale.photoRecto) {
|
||||
doc.text('✓ Photo recto pièce d\'identité', 25, currentY);
|
||||
currentY += 5;
|
||||
}
|
||||
if (sale.photoVerso) {
|
||||
doc.text('✓ Photo verso pièce d\'identité', 25, currentY);
|
||||
currentY += 5;
|
||||
}
|
||||
if (sale.photoTicket) {
|
||||
doc.text('✓ Photo ticket/reçu', 25, currentY);
|
||||
currentY += 5;
|
||||
}
|
||||
currentY += 5;
|
||||
}
|
||||
|
||||
// Ligne de séparation si pas la dernière vente
|
||||
if (saleIndex < filteredSales.length - 1) {
|
||||
doc.setLineWidth(0.5);
|
||||
doc.line(20, currentY, 190, currentY);
|
||||
currentY += 15;
|
||||
}
|
||||
});
|
||||
|
||||
autoTable(doc, {
|
||||
head: [['Date', 'Vendeur', 'Client', 'Article', 'Cat.', 'Qty', 'Paiement', 'Code']],
|
||||
body: tableData,
|
||||
startY: startDate || endDate ? 45 : 40,
|
||||
styles: { fontSize: 8 },
|
||||
headStyles: { fillColor: [64, 64, 64] },
|
||||
margin: { top: 40, left: 20, right: 20 },
|
||||
});
|
||||
|
||||
doc.save(`ventes-feux-artifice-${new Date().toISOString().split('T')[0]}.pdf`);
|
||||
doc.save(`registre-detaille-feux-artifice-${new Date().toISOString().split('T')[0]}.pdf`);
|
||||
|
||||
toast({
|
||||
title: "Export réussi",
|
||||
description: "Le fichier PDF a été téléchargé",
|
||||
description: "Le registre détaillé PDF a été téléchargé",
|
||||
variant: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -358,7 +421,7 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
||||
className="modern-button modern-button-secondary"
|
||||
>
|
||||
<FileText className="h-4 w-4" />
|
||||
Export PDF
|
||||
Registre PDF Détaillé
|
||||
</button>
|
||||
<button
|
||||
onClick={exportToCSV}
|
||||
|
||||
Reference in new issue
Block a user