diff --git a/server/invoiceVerification.ts b/server/invoiceVerification.ts index 35a3c1e..e091480 100644 --- a/server/invoiceVerification.ts +++ b/server/invoiceVerification.ts @@ -146,6 +146,88 @@ export class InvoiceVerificationService { } } + /** + * Met à jour le cache pour marquer une facture comme réconciliée (cache permanent) + */ + async updateCacheAsReconciled(invoiceReference: string, groupId: number): Promise { + try { + const cacheKey = this.generateCacheKey(invoiceReference, groupId); + console.log('🔄 [CACHE] Mise à jour cache comme réconcilié:', { invoiceReference, groupId, cacheKey }); + + // Récupérer le cache existant + const cached = await storage.getInvoiceVerificationCache(cacheKey); + if (!cached) { + console.log('❌ [CACHE] Aucun cache trouvé à mettre à jour'); + return; + } + + // Si déjà réconcilié, ne rien faire + if (cached.isReconciled) { + console.log('✅ [CACHE] Cache déjà marqué comme réconcilié'); + return; + } + + // Mettre à jour avec cache permanent (50 ans) + const expiresAt = new Date(); + expiresAt.setFullYear(expiresAt.getFullYear() + 50); + + const updatedCacheData = { + ...cached, + isReconciled: true, + expiresAt + }; + + await storage.saveInvoiceVerificationCache(updatedCacheData); + + console.log('✅ [CACHE] Cache mis à jour comme PERMANENT:', { + invoiceReference, + groupId, + cacheKey, + newExpiresAt: expiresAt.toISOString() + }); + } catch (error) { + console.error('❌ [CACHE] Erreur mise à jour cache réconcilié:', error); + } + } + + /** + * Met à jour tous les caches des livraisons déjà validées pour les marquer comme permanents + */ + async updateExistingReconciledCaches(): Promise { + try { + console.log('🔄 [CACHE] Mise à jour en lot des caches pour livraisons validées...'); + + // Récupérer toutes les livraisons validées (reconciled = true) + const deliveries = await storage.getDeliveries(); + const reconciledDeliveries = deliveries.filter(d => d.reconciled); + + console.log(`📊 [CACHE] ${reconciledDeliveries.length} livraisons validées trouvées`); + + let updatedCount = 0; + for (const delivery of reconciledDeliveries) { + try { + // Mettre à jour le cache pour la référence de facture + if (delivery.invoiceReference && delivery.invoiceReference.trim()) { + await this.updateCacheAsReconciled(delivery.invoiceReference, delivery.groupId); + updatedCount++; + } + + // Mettre à jour le cache pour le numéro BL + if (delivery.blNumber && delivery.blNumber.trim()) { + await this.updateCacheAsReconciled(delivery.blNumber, delivery.groupId); + updatedCount++; + } + } catch (error) { + console.error(`❌ [CACHE] Erreur mise à jour cache pour livraison ${delivery.id}:`, error); + } + } + + console.log(`✅ [CACHE] Mise à jour terminée: ${updatedCount} caches mis à jour comme permanents`); + } catch (error) { + console.error('❌ [CACHE] Erreur lors de la mise à jour en lot:', error); + } + } + /** * Vérifie une référence de facture pour un groupe donné */ @@ -217,7 +299,7 @@ export class InvoiceVerificationService { if (invoiceReference.toLowerCase().includes('test')) { const result = { exists: true, - matchType: 'invoice_reference', + matchType: 'invoice_reference' as const, invoiceReference: invoiceReference, invoiceAmount: 123.45, supplierName: 'Fournisseur Test' @@ -231,7 +313,7 @@ export class InvoiceVerificationService { if (invoiceReference.toLowerCase().includes('bl')) { const result = { exists: true, - matchType: 'bl_number', + matchType: 'bl_number' as const, invoiceReference: `FACT_${invoiceReference}`, invoiceAmount: 67.89, supplierName: 'Fournisseur BL' @@ -244,7 +326,7 @@ export class InvoiceVerificationService { const result = { exists: false, - matchType: 'none', + matchType: 'none' as const, errorMessage: 'Facture non trouvée (mode développement)' }; diff --git a/server/routes.ts b/server/routes.ts index 407c96b..531edad 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -1124,6 +1124,20 @@ export async function registerRoutes(app: Express): Promise { await storage.validateDelivery(id, blData); + // MISE À JOUR DU CACHE : Marquer le cache comme permanent pour cette livraison validée + try { + if (delivery.invoiceReference && delivery.invoiceReference.trim()) { + console.log('🔄 [CACHE] Mise à jour cache permanent après validation livraison'); + await invoiceVerificationService.updateCacheAsReconciled(delivery.invoiceReference, delivery.groupId); + } + if (delivery.blNumber && delivery.blNumber.trim()) { + console.log('🔄 [CACHE] Mise à jour cache permanent BL après validation livraison'); + await invoiceVerificationService.updateCacheAsReconciled(delivery.blNumber, delivery.groupId); + } + } catch (error) { + console.error('❌ Erreur mise à jour cache après validation:', error); + } + // SYNCHRONISATION AUTOMATIQUE : Quand validation, marquer la commande associée comme "delivered" if (delivery.orderId) { try { @@ -1142,6 +1156,35 @@ export async function registerRoutes(app: Express): Promise { } }); + // Route pour mettre à jour les caches existants des livraisons validées + app.post('/api/cache/update-reconciled', isAuthenticated, async (req: any, res) => { + try { + const user = await storage.getUserWithGroups(req.user.claims ? req.user.claims.sub : req.user.id); + if (!user) { + return res.status(404).json({ message: "User not found" }); + } + + // Vérifier que c'est un admin + if (user.role !== 'admin') { + return res.status(403).json({ message: "Seuls les admins peuvent exécuter cette opération" }); + } + + console.log('🔧 [ADMIN] Exécution mise à jour des caches permanents...'); + await invoiceVerificationService.updateExistingReconciledCaches(); + + res.json({ + message: "Mise à jour des caches permanents terminée avec succès", + success: true + }); + } catch (error) { + console.error("Erreur mise à jour caches:", error); + res.status(500).json({ + message: "Erreur lors de la mise à jour des caches", + error: error instanceof Error ? error.message : 'Unknown error' + }); + } + }); + // DLC Products routes app.get('/api/dlc-products', isAuthenticated, async (req: any, res) => { try {