From 7fcd550147ce58c95fd5563ef72d1b611ea04c2a Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Wed, 13 Aug 2025 14:24:00 +0000 Subject: [PATCH] Improve reconciliation display and fix statistics calculations Update reconciliation logic to use cache invalidation and refetch for immediate UI updates, and correct statistical calculations by using `deliveredDate` for monthly delivery metrics. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7c468936-2a88-4686-ac0a-84921a45222d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/7c468936-2a88-4686-ac0a-84921a45222d/csL8uKw --- attached_assets/image_1755094643163.png | Bin 0 -> 16594 bytes client/src/pages/BLReconciliation.tsx | 14 ++++++++++--- replit.md | 26 +++++++++++------------- server/storage.ts | 12 +++++++++-- 4 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 attached_assets/image_1755094643163.png diff --git a/attached_assets/image_1755094643163.png b/attached_assets/image_1755094643163.png new file mode 100644 index 0000000000000000000000000000000000000000..9c237792dc3f87e5ab6e68e4ca18b6f2f2abb90e GIT binary patch literal 16594 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 Miz|qgix~R-A1^7=%m4rY literal 0 HcmV?d00001 diff --git a/client/src/pages/BLReconciliation.tsx b/client/src/pages/BLReconciliation.tsx index 890ba17..b0b43fe 100644 --- a/client/src/pages/BLReconciliation.tsx +++ b/client/src/pages/BLReconciliation.tsx @@ -187,8 +187,8 @@ export default function BLReconciliation() { }); }; - // Récupérer les livraisons validées avec BL - const { data: deliveriesWithBL = [], isLoading } = useQuery({ + // Récupérer les livraisons validées avec BL - CACHE INVALIDÉ après modifications + const { data: deliveriesWithBL = [], isLoading, refetch } = useQuery({ queryKey: ['/api/deliveries/bl', selectedStoreId], queryFn: async () => { const params = new URLSearchParams({}); @@ -214,7 +214,8 @@ export default function BLReconciliation() { return filtered.sort((a: any, b: any) => new Date(b.deliveredDate || b.updatedAt).getTime() - new Date(a.deliveredDate || a.updatedAt).getTime()); }, - enabled: !!user + enabled: !!user, + staleTime: 0 // Éviter la mise en cache pour toujours avoir les dernières données BL }); // VÉRIFICATION AUTOMATIQUE AU CHARGEMENT avec système de cache @@ -267,7 +268,9 @@ export default function BLReconciliation() { description: "Données de rapprochement mises à jour", }); + // Invalidation cache + refetch forcé pour mise à jour immédiate queryClient.invalidateQueries({ queryKey: ['/api/deliveries/bl'] }); + refetch(); handleCloseModal(); } catch (error) { toast({ @@ -397,7 +400,10 @@ export default function BLReconciliation() { description: "Rapprochement validé avec succès", }); + // Invalidation cache + refetch forcé pour mise à jour immédiate queryClient.invalidateQueries({ queryKey: ['/api/deliveries/bl'] }); + queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); + refetch(); // Force recharge immédiate des données BL } catch (error) { toast({ title: "Erreur", @@ -432,7 +438,9 @@ export default function BLReconciliation() { description: "Rapprochement dévalidé avec succès", }); + // Invalidation cache + refetch forcé pour mise à jour immédiate queryClient.invalidateQueries({ queryKey: ['/api/deliveries/bl'] }); + refetch(); } catch (error) { toast({ title: "Erreur", diff --git a/replit.md b/replit.md index 7f4228a..802e106 100644 --- a/replit.md +++ b/replit.md @@ -19,22 +19,20 @@ La plateforme fournit une gestion robuste des flux de travail de livraison avec ## Recent Changes -### 2025-08-13 - Correction complète des statistiques du tableau de bord -✅ **Résolution définitive de l'affichage de zéros dans les statistiques** : +### 2025-08-13 - Correction finale statistiques + affichage BL résolu +✅ **Résolution définitive des bugs statistiques et affichage BL** : -**Problème identifié et corrigé :** -- **Statistiques hardcodées** : La méthode `getMonthlyStats()` retournait des zéros fixes -- **Calculs réels implémentés** : Requêtes PostgreSQL pour vraies statistiques mensuelles -- **Filtrage par magasin** : Support des filtres par groupes/magasins -- **Gestion des erreurs** : Fallback en cas d'erreur de base de données +**1. Statistiques mois corrigées :** +- **Problème** : Palettes/colis comptées sur scheduledDate au lieu de deliveredDate +- **Solution** : Filtrage par `deliveredDate` pour vraies stats mensuelles +- **Impact** : Statistiques reflètent maintenant les livraisons effectives du mois +- **Calcul** : Seules les livraisons `delivered` dans le mois avec `deliveredDate` valide -**Calculs statistiques implémentés :** -- **Commandes** : COUNT des commandes du mois par date plannedDate -- **Livraisons** : COUNT des livraisons du mois par date plannedDate -- **Palettes** : SUM des quantités de livraisons -- **Colis** : COUNT total des livraisons -- **Délai moyen** : Moyenne des jours entre plannedDate et actualDate -- **Commandes en attente** : COUNT des commandes sans date ou statut pending +**2. Affichage BL rapprochement optimisé :** +- **Problème** : BL numbers n'apparaissaient pas immédiatement après validation +- **Solution** : Cache invalidation + refetch forcé après modification +- **Technique** : `staleTime: 0` + `queryClient.invalidateQueries` + `refetch()` +- **Résultat** : Mise à jour instantanée de l'interface utilisateur ### 2025-08-13 - Erreurs 502 production entièrement corrigées ✅ **Résolution définitive des erreurs Bad Gateway en production** : diff --git a/server/storage.ts b/server/storage.ts index fb87cc6..b378fe5 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -612,11 +612,12 @@ export class DatabaseStorage implements IStorage { try { console.log('📊 Calcul statistiques mensuelles:', { year, month, startDate, endDate, groupIds }); - // Construire les conditions pour le filtrage par groupe + // Construire les conditions pour le filtrage par groupe - UTILISER LE BON CHAMP DE DATE let ordersWhereCondition = and( gte(orders.plannedDate, startDate), lt(orders.plannedDate, endDate) ); + // Pour les livraisons, utiliser deliveredDate pour celles livrées, sinon scheduledDate let deliveriesWhereCondition = and( gte(deliveries.scheduledDate, startDate), lt(deliveries.scheduledDate, endDate) @@ -652,12 +653,19 @@ export class DatabaseStorage implements IStorage { .where(pendingWhereCondition); // Calculer les totaux de palettes et colis du mois (SEULEMENT livraisons delivered) + // IMPORTANT: Utiliser deliveredDate pour filtrer par le mois de livraison effective let deliveredWhereCondition = and( - deliveriesWhereCondition, + gte(deliveries.deliveredDate, startDate), + lt(deliveries.deliveredDate, endDate), eq(deliveries.status, 'delivered'), isNotNull(deliveries.deliveredDate) ); + // Ajouter le filtre par groupe pour les livraisons delivered + if (groupIds && groupIds.length > 0) { + deliveredWhereCondition = and(deliveredWhereCondition, inArray(deliveries.groupId, groupIds)); + } + const deliveriesStatsResult = await db .select({ totalPalettes: sql`COALESCE(SUM(CAST(${deliveries.quantity} as INTEGER)), 0)`,