Merge pull request #504 from R0m1k3/1.1

1.1
This commit is contained in:
LogiFlow authored and GitHub committed 2025-11-04 13:33:26 +01:00
commit 7eb6d957dd
11 files changed
+667 -54

No files matched your search

@@ -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
@@ -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
@@ -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

+7 -7
View File
@@ -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
View File
@@ -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);
+18
View File
@@ -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"]
}