mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Improve date handling for improved data accuracy
Add a date normalization function to server/routes.ts to handle various date formats from NocoDB and standardize them to YYYY-MM-DD, also refactor delivery retrieval logic to separate dated and undated deliveries. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 1e4433b5-47ab-464c-b663-fea2e53367dd Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 4d0fa35d-6e0d-44c6-b7e9-f78186630c41 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/1e4433b5-47ab-464c-b663-fea2e53367dd/G9gVBac
This commit is contained in:
1 parent
09c873eb06
commit
972286e22e
1 file changed
+116
-8
+116
-8
@@ -7,6 +7,79 @@ import { db, pool } from "./db";
|
||||
|
||||
console.log('🔍 Using development storage and authentication');
|
||||
|
||||
// Fonction de normalisation des dates pour gérer différents formats de NocoDB
|
||||
function normalizeDateString(dateString: string | null | undefined): string | null {
|
||||
if (!dateString || typeof dateString !== 'string') return null;
|
||||
|
||||
const trimmed = dateString.trim();
|
||||
if (!trimmed) return null;
|
||||
|
||||
try {
|
||||
// Si déjà au format ISO (YYYY-MM-DD), le retourner tel quel
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
// Format slash ou tiret : DD/MM/YYYY, MM/DD/YYYY, DD-MM-YYYY, MM-DD-YYYY
|
||||
const slashMatch = trimmed.match(/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})$/);
|
||||
if (slashMatch) {
|
||||
const [, first, second, year] = slashMatch;
|
||||
const firstNum = parseInt(first);
|
||||
const secondNum = parseInt(second);
|
||||
|
||||
// Validation basique des valeurs
|
||||
if (firstNum > 31 || secondNum > 31 || firstNum === 0 || secondNum === 0) {
|
||||
console.warn(`⚠️ Date invalide (valeurs hors limites): ${trimmed}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Déterminer le format en fonction des valeurs
|
||||
let day: string, month: string;
|
||||
|
||||
if (firstNum > 12) {
|
||||
// first > 12 → forcément DD/MM (format français/européen)
|
||||
day = first.padStart(2, '0');
|
||||
month = second.padStart(2, '0');
|
||||
} else if (secondNum > 12) {
|
||||
// second > 12 → forcément MM/DD (format américain)
|
||||
day = second.padStart(2, '0');
|
||||
month = first.padStart(2, '0');
|
||||
} else {
|
||||
// Ambiguïté (les deux < 12) → on assume format français DD/MM par défaut
|
||||
// Pour être plus sûr, on pourrait vérifier la configuration du groupe/locale
|
||||
day = first.padStart(2, '0');
|
||||
month = second.padStart(2, '0');
|
||||
}
|
||||
|
||||
// Validation finale : mois entre 1-12, jour entre 1-31
|
||||
const monthNum = parseInt(month);
|
||||
const dayNum = parseInt(day);
|
||||
if (monthNum < 1 || monthNum > 12 || dayNum < 1 || dayNum > 31) {
|
||||
console.warn(`⚠️ Date invalide après parsing: ${trimmed} → month=${month}, day=${day}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// Essayer de parser avec Date (format ISO complet avec heures)
|
||||
const date = new Date(trimmed);
|
||||
if (!isNaN(date.getTime())) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// Si aucun format reconnu, retourner null (ne pas persister une date invalide)
|
||||
console.warn(`⚠️ Format de date non reconnu: ${trimmed}`);
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur normalisation date:', error);
|
||||
return null; // Retourner null en cas d'erreur pour éviter de persister des données invalides
|
||||
}
|
||||
}
|
||||
|
||||
// Simple hash password function using crypto
|
||||
async function hashPasswordSimple(password: string) {
|
||||
const crypto = await import('crypto');
|
||||
@@ -317,20 +390,53 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
|
||||
console.log('📅 Récupération échéances depuis deliveries:', { groupId, groupName: group.name });
|
||||
|
||||
// Récupérer toutes les livraisons du groupe avec échéance
|
||||
// Récupérer toutes les livraisons du groupe
|
||||
const allDeliveries = await storage.getDeliveries();
|
||||
const deliveriesWithDueDate = allDeliveries.filter(
|
||||
(d: any) => d.groupId === groupId && d.dueDate && d.invoiceReference
|
||||
);
|
||||
const groupDeliveries = allDeliveries.filter((d: any) => d.groupId === groupId && d.invoiceReference);
|
||||
|
||||
console.log(`📅 Trouvé ${deliveriesWithDueDate.length} livraisons avec échéance pour le groupe ${groupId}`);
|
||||
// Séparer les livraisons avec et sans dueDate
|
||||
const deliveriesWithDueDate = groupDeliveries.filter((d: any) => d.dueDate);
|
||||
const deliveriesWithoutDueDate = groupDeliveries.filter((d: any) => !d.dueDate);
|
||||
|
||||
console.log(`📅 Livraisons avec échéance: ${deliveriesWithDueDate.length}, sans échéance: ${deliveriesWithoutDueDate.length}`);
|
||||
|
||||
// FALLBACK : Pour les livraisons sans dueDate, interroger NocoDB
|
||||
const { InvoiceVerificationService } = await import('./invoiceVerification.js');
|
||||
const verificationService = new InvoiceVerificationService();
|
||||
|
||||
for (const delivery of deliveriesWithoutDueDate) {
|
||||
try {
|
||||
const result = await verificationService.verifyInvoice(
|
||||
delivery.invoiceReference!,
|
||||
delivery.groupId,
|
||||
false, // Ne pas forcer le refresh, utiliser cache si disponible
|
||||
delivery.reconciled || false
|
||||
);
|
||||
|
||||
if (result.exists && result.dueDate) {
|
||||
// Normaliser la date avant de la stocker
|
||||
const normalizedDate = normalizeDateString(result.dueDate);
|
||||
if (normalizedDate) {
|
||||
// Mettre à jour deliveries avec la date normalisée (caching)
|
||||
await storage.updateDelivery(delivery.id, { dueDate: normalizedDate });
|
||||
delivery.dueDate = normalizedDate;
|
||||
console.log(`📅 Fallback: échéance récupérée et normalisée pour livraison #${delivery.id}`);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ Fallback échéance échoué pour livraison #${delivery.id}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Combiner toutes les livraisons qui ont maintenant une dueDate
|
||||
const allDeliveriesWithDueDate = [...deliveriesWithDueDate, ...deliveriesWithoutDueDate.filter((d: any) => d.dueDate)];
|
||||
|
||||
// Récupérer tous les fournisseurs pour le mapping du mode de paiement
|
||||
const allSuppliers = await storage.getSuppliers();
|
||||
const supplierMap = new Map(allSuppliers.map((s: any) => [s.id, s]));
|
||||
|
||||
// Formatter les échéances
|
||||
const schedules = deliveriesWithDueDate.map((delivery: any) => {
|
||||
const schedules = allDeliveriesWithDueDate.map((delivery: any) => {
|
||||
const supplier = supplierMap.get(delivery.supplierId);
|
||||
|
||||
return {
|
||||
@@ -345,6 +451,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
};
|
||||
});
|
||||
|
||||
console.log(`📅 Total échéances retournées: ${schedules.length}`);
|
||||
res.json({ schedules });
|
||||
|
||||
} catch (error: any) {
|
||||
@@ -1338,8 +1445,9 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
);
|
||||
|
||||
if (result.exists && result.dueDate) {
|
||||
data.dueDate = result.dueDate;
|
||||
console.log(`📅 Date d'échéance récupérée depuis NocoDB: ${result.dueDate}`);
|
||||
// Normaliser la date avant de la stocker
|
||||
data.dueDate = normalizeDateString(result.dueDate);
|
||||
console.log(`📅 Date d'échéance récupérée et normalisée: ${data.dueDate} (original: ${result.dueDate})`);
|
||||
} else {
|
||||
data.dueDate = null;
|
||||
console.log(`📅 Aucune date d'échéance trouvée dans NocoDB`);
|
||||
|
||||
Reference in new issue
Block a user