mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
11 files changed
+667
-54
No files matched your search
+201
@@ -0,0 +1,201 @@
|
||||
|
||||
|
||||
]
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin_local
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
❌ [PRODUCTION] User not found with username: admin_local
|
||||
|
||||
🔍 [PRODUCTION] User search result: Not found
|
||||
|
||||
🎯 [PRODUCTION] Found announcements: 4
|
||||
|
||||
GET /api/announcements 304 in 9ms
|
||||
|
||||
GET /api/user 304 in 4ms
|
||||
|
||||
📢 [SERVER] Fetching announcements for user: _1754936203292 environment: production
|
||||
|
||||
📢 [SERVER] User found: { username: 'ff292', role: 'employee' }
|
||||
|
||||
🎯 [PRODUCTION] Using PostgreSQL DASHBOARD_MESSAGES table
|
||||
|
||||
🔍 [PRODUCTION] Raw messages from DB: 4 items: [
|
||||
|
||||
{
|
||||
|
||||
id: 20,
|
||||
|
||||
title: 'DLC',
|
||||
|
||||
content: 'Attention des DLC sont en expiré bientôt ou expiré, il faut s en occuper',
|
||||
|
||||
type: 'success',
|
||||
|
||||
storeId: 2,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-09-24T11:26:13.521Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 17,
|
||||
|
||||
title: 'Module Avoir',
|
||||
|
||||
content: "Le module d'avoir est en place",
|
||||
|
||||
type: 'error',
|
||||
|
||||
storeId: 1,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-09-09T07:47:47.650Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 16,
|
||||
|
||||
title: 'Mise à jour Prix',
|
||||
|
||||
content: 'Merci de mettre vos prix a jour tous les matins, certain magasin ne le font pas.',
|
||||
|
||||
type: 'success',
|
||||
|
||||
storeId: null,
|
||||
|
||||
createdBy: 'admin',
|
||||
|
||||
createdAt: 2025-08-18T10:45:08.585Z
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
id: 8,
|
||||
|
||||
title: 'Bon de Livraison',
|
||||
|
||||
content: 'Lorsque vous rentrez un numéro de bon de livraison, faite le a l identique, même les majuscules. Pour My candy Shop, prendre le numéro de commande.',
|
||||
|
||||
type: 'info',
|
||||
|
||||
storeId: null,
|
||||
|
||||
createdBy: 'admin_local',
|
||||
|
||||
createdAt: 2025-08-07T11:04:38.123Z
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin
|
||||
|
||||
🔍 [PRODUCTION] Looking for user with username: admin_local
|
||||
|
||||
❌ [PRODUCTION] User not found with username: admin_local
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Found
|
||||
|
||||
🔍 [PRODUCTION] User search result: Not found
|
||||
|
||||
🎯 [PRODUCTION] Found announcements: 4
|
||||
|
||||
GET /api/announcements 304 in 24ms
|
||||
|
||||
GET /api/groups 304 in 5ms
|
||||
|
||||
GET /api/user 304 in 4ms
|
||||
|
||||
GET /api/suppliers 200 in 4ms
|
||||
|
||||
GET /api/dlc-products 200 in 53ms
|
||||
|
||||
📊 [EXPORT] Début de l'export Excel
|
||||
|
||||
🔍 [EXPORT] Utilisateur: admin (admin)
|
||||
|
||||
📋 [EXPORT] Paramètres: {
|
||||
|
||||
groupId: 1,
|
||||
|
||||
month: '2025-12',
|
||||
|
||||
paymentMethods: [ 'Traite Magnétique' ],
|
||||
|
||||
includeHT: true,
|
||||
|
||||
includeTTC: true
|
||||
|
||||
}
|
||||
|
||||
❌ PRODUCTION: Delivery #127 (store 2) linked to order #81 (store 1) - STORE MISMATCH DETECTED!
|
||||
|
||||
🔗 PRODUCTION: getDeliveries() récupéré 357 livraisons avec relations
|
||||
|
||||
📦 [EXPORT] Import du module xlsx...
|
||||
|
||||
❌ [EXPORT] Erreur export Excel: Error: Dynamic require of "stream" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at make_xlsx_lib (file:///app/dist/index.js:44815:22)
|
||||
|
||||
at node_modules/xlsx/xlsx.js (file:///app/dist/index.js:44819:41)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:47198:63
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||
|
||||
at async file:///app/dist/index.js:47198:20
|
||||
|
||||
❌ [EXPORT] Message: Dynamic require of "stream" is not supported
|
||||
|
||||
❌ [EXPORT] Stack: Error: Dynamic require of "stream" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at make_xlsx_lib (file:///app/dist/index.js:44815:22)
|
||||
|
||||
at node_modules/xlsx/xlsx.js (file:///app/dist/index.js:44819:41)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:47198:63
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||
|
||||
at async file:///app/dist/index.js:47198:20
|
||||
|
||||
POST /api/payment-schedule/export 500 in 910ms
|
||||
|
||||
HEAD /api/health 200 in 1ms
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
Actions
|
||||
|
||||
|
||||
|
||||
|
||||
hoursRemaining: 438287
|
||||
|
||||
}
|
||||
|
||||
🔍 [CACHE] Résultat cache: {
|
||||
|
||||
found: true,
|
||||
|
||||
isReconciled: true,
|
||||
|
||||
expired: false,
|
||||
|
||||
expiresAt: 2075-11-04T10:58:49.338Z,
|
||||
|
||||
currentTime: '2025-11-04T12:17:35.661Z'
|
||||
|
||||
}
|
||||
|
||||
🛡️ [CACHE] PERMANENT - Facture validée avec coche verte, AUCUNE vérification: {
|
||||
|
||||
invoiceReference: '22529151',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
exists: true,
|
||||
|
||||
invoiceAmount: '2653.75',
|
||||
|
||||
dueDate: null
|
||||
|
||||
}
|
||||
|
||||
✅ [INVOICE] Résultat depuis cache: {
|
||||
|
||||
exists: true,
|
||||
|
||||
matchType: 'invoice_reference',
|
||||
|
||||
errorMessage: null,
|
||||
|
||||
invoiceReference: '22529151',
|
||||
|
||||
supplierName: 'Sovacom',
|
||||
|
||||
invoiceAmount: 2653.75,
|
||||
|
||||
invoiceAmountTTC: 3184.5,
|
||||
|
||||
dueDate: null,
|
||||
|
||||
fromCache: true,
|
||||
|
||||
permanent: true
|
||||
|
||||
}
|
||||
|
||||
🔍 [INVOICE] Début vérification facture: { invoiceReference: 'FCLT035833', groupId: 1, forceRefresh: false }
|
||||
|
||||
🔍 [INVOICE] Vérification cache...
|
||||
|
||||
🔍 [CACHE] Recherche cache pour: {
|
||||
|
||||
invoiceReference: 'FCLT035833',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
cacheKey: '1_fclt035833'
|
||||
|
||||
}
|
||||
|
||||
✅ [DATABASE-CACHE] Cache hit pour: {
|
||||
|
||||
cacheKey: '1_fclt035833',
|
||||
|
||||
expires: 2075-11-04T10:58:49.353Z,
|
||||
|
||||
hoursRemaining: 438287
|
||||
|
||||
}
|
||||
|
||||
🔍 [CACHE] Résultat cache: {
|
||||
|
||||
found: true,
|
||||
|
||||
isReconciled: true,
|
||||
|
||||
expired: false,
|
||||
|
||||
expiresAt: 2075-11-04T10:58:49.353Z,
|
||||
|
||||
currentTime: '2025-11-04T12:17:35.662Z'
|
||||
|
||||
}
|
||||
|
||||
🛡️ [CACHE] PERMANENT - Facture validée avec coche verte, AUCUNE vérification: {
|
||||
|
||||
invoiceReference: 'FCLT035833',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
exists: true,
|
||||
|
||||
invoiceAmount: '1307.26',
|
||||
|
||||
dueDate: null
|
||||
|
||||
}
|
||||
|
||||
✅ [INVOICE] Résultat depuis cache: {
|
||||
|
||||
exists: true,
|
||||
|
||||
matchType: 'invoice_reference',
|
||||
|
||||
errorMessage: null,
|
||||
|
||||
invoiceReference: 'FCLT035833',
|
||||
|
||||
supplierName: 'Idvpc',
|
||||
|
||||
invoiceAmount: 1307.26,
|
||||
|
||||
invoiceAmountTTC: 1568.71,
|
||||
|
||||
dueDate: null,
|
||||
|
||||
fromCache: true,
|
||||
|
||||
permanent: true
|
||||
|
||||
}
|
||||
|
||||
💰 Livraisons nécessitant récupération TTC: 0
|
||||
|
||||
📅 Total échéances retournées: 34
|
||||
|
||||
GET /api/payment-schedule 304 in 892ms
|
||||
|
||||
📊 [EXPORT] Début de l'export Excel
|
||||
|
||||
🔍 [EXPORT] Utilisateur: admin (admin)
|
||||
|
||||
📋 [EXPORT] Paramètres: {
|
||||
|
||||
groupId: 1,
|
||||
|
||||
month: '2025-11',
|
||||
|
||||
paymentMethods: [ 'Non défini' ],
|
||||
|
||||
includeHT: true,
|
||||
|
||||
includeTTC: true
|
||||
|
||||
}
|
||||
|
||||
❌ PRODUCTION: Delivery #127 (store 2) linked to order #81 (store 1) - STORE MISMATCH DETECTED!
|
||||
|
||||
🔗 PRODUCTION: getDeliveries() récupéré 357 livraisons avec relations
|
||||
|
||||
📦 [EXPORT] Import du module xlsx...
|
||||
|
||||
❌ [EXPORT] Erreur export Excel: Error: Dynamic require of "stream" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at make_xlsx_lib (file:///app/dist/index.js:44815:22)
|
||||
|
||||
at node_modules/xlsx/xlsx.js (file:///app/dist/index.js:44819:41)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:47198:63
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||
|
||||
at async file:///app/dist/index.js:47198:20
|
||||
|
||||
❌ [EXPORT] Message: Dynamic require of "stream" is not supported
|
||||
|
||||
❌ [EXPORT] Stack: Error: Dynamic require of "stream" is not supported
|
||||
|
||||
at file:///app/dist/index.js:11:9
|
||||
|
||||
at make_xlsx_lib (file:///app/dist/index.js:44815:22)
|
||||
|
||||
at node_modules/xlsx/xlsx.js (file:///app/dist/index.js:44819:41)
|
||||
|
||||
at __require2 (file:///app/dist/index.js:17:50)
|
||||
|
||||
at file:///app/dist/index.js:47198:63
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||
|
||||
at async file:///app/dist/index.js:47198:20
|
||||
|
||||
POST /api/payment-schedule/export 500 in 936ms
|
||||
|
||||
HEAD /api/health 200 in 1ms
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
Actions
|
||||
|
||||
|
||||
|
||||
|
||||
isReconciled: true,
|
||||
|
||||
expired: false,
|
||||
|
||||
expiresAt: 2075-11-04T10:58:49.326Z,
|
||||
|
||||
currentTime: '2025-11-04T12:15:03.672Z'
|
||||
|
||||
}
|
||||
|
||||
🛡️ [CACHE] PERMANENT - Facture validée avec coche verte, AUCUNE vérification: {
|
||||
|
||||
invoiceReference: '000752796',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
exists: true,
|
||||
|
||||
invoiceAmount: '1203.12',
|
||||
|
||||
dueDate: null
|
||||
|
||||
}
|
||||
|
||||
✅ [INVOICE] Résultat depuis cache: {
|
||||
|
||||
exists: true,
|
||||
|
||||
matchType: 'invoice_reference',
|
||||
|
||||
errorMessage: null,
|
||||
|
||||
invoiceReference: '000752796',
|
||||
|
||||
supplierName: 'CMP',
|
||||
|
||||
invoiceAmount: 1203.12,
|
||||
|
||||
invoiceAmountTTC: 1443.74,
|
||||
|
||||
dueDate: null,
|
||||
|
||||
fromCache: true,
|
||||
|
||||
permanent: true
|
||||
|
||||
}
|
||||
|
||||
🔍 [INVOICE] Début vérification facture: { invoiceReference: '22529151', groupId: 1, forceRefresh: false }
|
||||
|
||||
🔍 [INVOICE] Vérification cache...
|
||||
|
||||
🔍 [CACHE] Recherche cache pour: { invoiceReference: '22529151', groupId: 1, cacheKey: '1_22529151' }
|
||||
|
||||
✅ [DATABASE-CACHE] Cache hit pour: {
|
||||
|
||||
cacheKey: '1_22529151',
|
||||
|
||||
expires: 2075-11-04T10:58:49.338Z,
|
||||
|
||||
hoursRemaining: 438287
|
||||
|
||||
}
|
||||
|
||||
🔍 [CACHE] Résultat cache: {
|
||||
|
||||
found: true,
|
||||
|
||||
isReconciled: true,
|
||||
|
||||
expired: false,
|
||||
|
||||
expiresAt: 2075-11-04T10:58:49.338Z,
|
||||
|
||||
currentTime: '2025-11-04T12:15:03.675Z'
|
||||
|
||||
}
|
||||
|
||||
🛡️ [CACHE] PERMANENT - Facture validée avec coche verte, AUCUNE vérification: {
|
||||
|
||||
invoiceReference: '22529151',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
exists: true,
|
||||
|
||||
invoiceAmount: '2653.75',
|
||||
|
||||
dueDate: null
|
||||
|
||||
}
|
||||
|
||||
✅ [INVOICE] Résultat depuis cache: {
|
||||
|
||||
exists: true,
|
||||
|
||||
matchType: 'invoice_reference',
|
||||
|
||||
errorMessage: null,
|
||||
|
||||
invoiceReference: '22529151',
|
||||
|
||||
supplierName: 'Sovacom',
|
||||
|
||||
invoiceAmount: 2653.75,
|
||||
|
||||
invoiceAmountTTC: 3184.5,
|
||||
|
||||
dueDate: null,
|
||||
|
||||
fromCache: true,
|
||||
|
||||
permanent: true
|
||||
|
||||
}
|
||||
|
||||
🔍 [INVOICE] Début vérification facture: { invoiceReference: 'FCLT035833', groupId: 1, forceRefresh: false }
|
||||
|
||||
🔍 [INVOICE] Vérification cache...
|
||||
|
||||
🔍 [CACHE] Recherche cache pour: {
|
||||
|
||||
invoiceReference: 'FCLT035833',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
cacheKey: '1_fclt035833'
|
||||
|
||||
}
|
||||
|
||||
✅ [DATABASE-CACHE] Cache hit pour: {
|
||||
|
||||
cacheKey: '1_fclt035833',
|
||||
|
||||
expires: 2075-11-04T10:58:49.353Z,
|
||||
|
||||
hoursRemaining: 438287
|
||||
|
||||
}
|
||||
|
||||
🔍 [CACHE] Résultat cache: {
|
||||
|
||||
found: true,
|
||||
|
||||
isReconciled: true,
|
||||
|
||||
expired: false,
|
||||
|
||||
expiresAt: 2075-11-04T10:58:49.353Z,
|
||||
|
||||
currentTime: '2025-11-04T12:15:03.677Z'
|
||||
|
||||
}
|
||||
|
||||
🛡️ [CACHE] PERMANENT - Facture validée avec coche verte, AUCUNE vérification: {
|
||||
|
||||
invoiceReference: 'FCLT035833',
|
||||
|
||||
groupId: 1,
|
||||
|
||||
exists: true,
|
||||
|
||||
invoiceAmount: '1307.26',
|
||||
|
||||
dueDate: null
|
||||
|
||||
}
|
||||
|
||||
✅ [INVOICE] Résultat depuis cache: {
|
||||
|
||||
exists: true,
|
||||
|
||||
matchType: 'invoice_reference',
|
||||
|
||||
errorMessage: null,
|
||||
|
||||
invoiceReference: 'FCLT035833',
|
||||
|
||||
supplierName: 'Idvpc',
|
||||
|
||||
invoiceAmount: 1307.26,
|
||||
|
||||
invoiceAmountTTC: 1568.71,
|
||||
|
||||
dueDate: null,
|
||||
|
||||
fromCache: true,
|
||||
|
||||
permanent: true
|
||||
|
||||
}
|
||||
|
||||
💰 Livraisons nécessitant récupération TTC: 0
|
||||
|
||||
📅 Total échéances retournées: 34
|
||||
|
||||
GET /api/payment-schedule 304 in 17159ms
|
||||
|
||||
HEAD /api/health 200 in 1ms
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 139 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 253 KiB |
@@ -212,7 +212,7 @@ export default function PaymentSchedulePage() {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `echeancier_${selectedMonth}.xlsx`;
|
||||
a.download = `echeancier_${selectedMonth}.csv`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
@@ -221,7 +221,7 @@ export default function PaymentSchedulePage() {
|
||||
setShowExportModal(false);
|
||||
toast({
|
||||
title: "Export réussi",
|
||||
description: "Le fichier Excel a été téléchargé avec succès.",
|
||||
description: "Le fichier CSV a été téléchargé avec succès. Ouvrez-le dans Excel.",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Erreur export:', error);
|
||||
@@ -303,10 +303,10 @@ export default function PaymentSchedulePage() {
|
||||
variant="outline"
|
||||
className="gap-2"
|
||||
disabled={filteredSchedules.length === 0}
|
||||
data-testid="button-export-excel"
|
||||
data-testid="button-export-csv"
|
||||
>
|
||||
<FileSpreadsheet className="h-4 w-4" />
|
||||
Exporter Excel
|
||||
Exporter CSV
|
||||
</Button>
|
||||
<div className="w-64">
|
||||
<Select value={selectedMonth} onValueChange={setSelectedMonth}>
|
||||
@@ -459,16 +459,16 @@ export default function PaymentSchedulePage() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Modale d'export Excel */}
|
||||
{/* Modale d'export CSV */}
|
||||
<Dialog open={showExportModal} onOpenChange={setShowExportModal}>
|
||||
<DialogContent className="sm:max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<FileSpreadsheet className="h-5 w-5 text-green-600" />
|
||||
Exporter vers Excel
|
||||
Exporter vers CSV
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
Sélectionnez les modes de paiement et les colonnes à inclure dans l'export
|
||||
Sélectionnez les modes de paiement et les colonnes à inclure dans l'export (ouvrez le fichier dans Excel)
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
|
||||
+31
-47
@@ -589,28 +589,31 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
.filter((schedule: any) => validatedPaymentMethods.includes(schedule.paymentMethod))
|
||||
.sort((a: any, b: any) => a.dueDate.getTime() - b.dueDate.getTime());
|
||||
|
||||
// Générer le fichier Excel
|
||||
console.log('📦 [EXPORT] Import du module xlsx...');
|
||||
const XLSX = await import('xlsx');
|
||||
console.log('✅ [EXPORT] Module xlsx importé avec succès');
|
||||
const workbook = XLSX.utils.book_new();
|
||||
console.log('📄 [EXPORT] Workbook créé');
|
||||
// Générer le fichier CSV avec tabulations
|
||||
console.log('📄 [EXPORT] Génération du fichier CSV avec tabulations...');
|
||||
|
||||
// Préparer les données pour Excel
|
||||
// Préparer les en-têtes
|
||||
const headers = ['Date d\'échéance', 'Fournisseur', 'Facture', 'Mode de paiement'];
|
||||
if (includeHT) headers.push('Montant HT');
|
||||
if (includeTTC) headers.push('Montant TTC');
|
||||
|
||||
const data = schedules.map((schedule: any) => {
|
||||
const row: any = {
|
||||
'Date d\'échéance': format(schedule.dueDate, 'dd/MM/yyyy', { locale: fr }),
|
||||
'Fournisseur': schedule.supplierName,
|
||||
'Facture': schedule.invoiceReference,
|
||||
'Mode de paiement': schedule.paymentMethod,
|
||||
};
|
||||
if (includeHT) row['Montant HT'] = schedule.amountHT;
|
||||
if (includeTTC) row['Montant TTC'] = schedule.amountTTC;
|
||||
return row;
|
||||
// Créer les lignes de données
|
||||
const csvLines: string[] = [];
|
||||
|
||||
// Ajouter la ligne d'en-tête
|
||||
csvLines.push(headers.join('\t'));
|
||||
|
||||
// Ajouter les données
|
||||
schedules.forEach((schedule: any) => {
|
||||
const row: string[] = [
|
||||
format(schedule.dueDate, 'dd/MM/yyyy', { locale: fr }),
|
||||
schedule.supplierName,
|
||||
schedule.invoiceReference,
|
||||
schedule.paymentMethod,
|
||||
];
|
||||
if (includeHT) row.push(schedule.amountHT.toFixed(2));
|
||||
if (includeTTC) row.push(schedule.amountTTC.toFixed(2));
|
||||
csvLines.push(row.join('\t'));
|
||||
});
|
||||
|
||||
// Calculer les totaux
|
||||
@@ -618,40 +621,21 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
const totalTTC = schedules.reduce((sum: number, s: any) => sum + s.amountTTC, 0);
|
||||
|
||||
// Ajouter une ligne de total
|
||||
const totalRow: any = {
|
||||
'Date d\'échéance': '',
|
||||
'Fournisseur': '',
|
||||
'Facture': '',
|
||||
'Mode de paiement': 'TOTAL',
|
||||
};
|
||||
if (includeHT) totalRow['Montant HT'] = totalHT;
|
||||
if (includeTTC) totalRow['Montant TTC'] = totalTTC;
|
||||
data.push(totalRow);
|
||||
const totalRow: string[] = ['', '', '', 'TOTAL'];
|
||||
if (includeHT) totalRow.push(totalHT.toFixed(2));
|
||||
if (includeTTC) totalRow.push(totalTTC.toFixed(2));
|
||||
csvLines.push(totalRow.join('\t'));
|
||||
|
||||
// Créer la feuille Excel
|
||||
const worksheet = XLSX.utils.json_to_sheet(data, { header: headers });
|
||||
|
||||
// Définir la largeur des colonnes
|
||||
worksheet['!cols'] = [
|
||||
{ wch: 15 }, // Date
|
||||
{ wch: 25 }, // Fournisseur
|
||||
{ wch: 15 }, // Facture
|
||||
{ wch: 18 }, // Mode de paiement
|
||||
{ wch: 12 }, // Montant HT
|
||||
{ wch: 12 }, // Montant TTC
|
||||
];
|
||||
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, 'Échéancier');
|
||||
|
||||
// Générer le buffer Excel
|
||||
const excelBuffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });
|
||||
// Générer le contenu CSV avec BOM UTF-8 pour Excel
|
||||
const BOM = '\uFEFF';
|
||||
const csvContent = BOM + csvLines.join('\n');
|
||||
|
||||
// Envoyer le fichier
|
||||
res.setHeader('Content-Disposition', `attachment; filename="echeancier_${validatedMonth}.xlsx"`);
|
||||
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
res.send(excelBuffer);
|
||||
res.setHeader('Content-Disposition', `attachment; filename="echeancier_${validatedMonth}.csv"`);
|
||||
res.setHeader('Content-Type', 'text/csv; charset=utf-8');
|
||||
res.send(csvContent);
|
||||
|
||||
console.log(`📊 Export Excel généré: ${schedules.length} échéances pour ${group.name}`);
|
||||
console.log(`📊 [EXPORT] CSV généré: ${schedules.length} échéances pour ${group.name}`);
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('❌ [EXPORT] Erreur export Excel:', error);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"target": "ES2022",
|
||||
"outDir": "./dist/server",
|
||||
"rootDir": "./server",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["server/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Reference in new issue
Block a user