From ce0b44c1fcb97313f37a50c9ca2202c62c568c18 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Mon, 13 Oct 2025 11:50:12 +0000 Subject: [PATCH] Correctly track product expiration status across the system Removes the `processedUntilExpiry` filter from DlcProducts and DlcStats queries in DatabaseStorage and MemStorage to ensure accurate expiration counts, aligning the logic between fetching products and their statistics. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 1e4433b5-47ab-464c-b663-fea2e53367dd Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/1e4433b5-47ab-464c-b663-fea2e53367dd/Z004ykL --- .replit | 4 ++++ server/storage.ts | 15 +++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.replit b/.replit index b034b4f..8c288d6 100644 --- a/.replit +++ b/.replit @@ -31,6 +31,10 @@ externalPort = 3003 localPort = 34203 externalPort = 8080 +[[ports]] +localPort = 36275 +externalPort = 8099 + [[ports]] localPort = 38343 externalPort = 3000 diff --git a/server/storage.ts b/server/storage.ts index 6becb4c..d9ca62b 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -1920,6 +1920,7 @@ export class DatabaseStorage implements IStorage { } const results = await query.orderBy(asc(dlcProducts.expiryDate)); + return results.map((row: any) => ({ ...row.dlcProduct, dlcDate: row.dlcProduct.expiryDate, // ✅ Mapping expiryDate vers dlcDate pour frontend @@ -2076,6 +2077,9 @@ export class DatabaseStorage implements IStorage { } // Version rétrocompatible - fonctionne avec ou sans les nouveaux champs + // IMPORTANT: Ne PAS filtrer sur processedUntilExpiry car cela crée une incohérence + // entre getDlcProducts (qui ne filtre pas) et getDlcStats (qui filtrait) + // Les produits expirés sont expirés, qu'ils aient été traités ou non try { // Essayer d'abord avec les nouveaux champs const [stats] = await db @@ -2084,12 +2088,10 @@ export class DatabaseStorage implements IStorage { expiringSoon: sql`COUNT(CASE WHEN ${dlcProducts.expiryDate} BETWEEN ${today.toISOString().split('T')[0]} AND ${alertDate.toISOString().split('T')[0]} AND ${dlcProducts.status} != 'valides' - AND (${dlcProducts.processedUntilExpiry} IS NULL OR ${dlcProducts.processedUntilExpiry} = false) THEN 1 END)`, expired: sql`COUNT(CASE WHEN ${dlcProducts.expiryDate} <= ${today.toISOString().split('T')[0]} AND ${dlcProducts.status} != 'valides' - AND (${dlcProducts.processedUntilExpiry} IS NULL OR ${dlcProducts.processedUntilExpiry} = false) THEN 1 END)` }) .from(dlcProducts) @@ -4240,19 +4242,20 @@ export class MemStorage implements IStorage { products = products.filter(product => groupIds.includes(product.groupId)); } + // IMPORTANT: Ne PAS filtrer sur processedUntilExpiry car cela crée une incohérence + // entre getDlcProducts (qui ne filtre pas) et getDlcStats (qui filtrait) + // Les produits expirés sont expirés, qu'ils aient été traités ou non return { active: products.filter(p => new Date(p.expiryDate) > today && p.status !== 'valides').length, expiringSoon: products.filter(p => { const expiry = new Date(p.expiryDate); const isExpiringSoon = expiry >= today && expiry <= alertDate; - const isProcessed = p.processedUntilExpiry && expiry > today; - return isExpiringSoon && !isProcessed && p.status !== 'valides'; + return isExpiringSoon && p.status !== 'valides'; }).length, expired: products.filter(p => { const expiry = new Date(p.expiryDate); const isExpired = expiry <= today; - const isProcessed = p.processedUntilExpiry && expiry > today; - return isExpired && !isProcessed && p.status !== 'valides'; + return isExpired && p.status !== 'valides'; }).length }; }