From 76a6d4c8aef42aae14da9968b11917ec1c24d495 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Wed, 13 Aug 2025 09:50:16 +0000 Subject: [PATCH] Add invoice verification functionality to track invoice checks Implement database operations for managing invoice verification records and their cache, including creation and retrieval. Replit-Commit-Author: Agent Replit-Commit-Session-Id: c52a701b-4841-4d00-b8cf-5a41c12abdf3 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/c52a701b-4841-4d00-b8cf-5a41c12abdf3/3uCfEKb --- server/storage.ts | 58 +++++++++++++++++++++++++++++++++++++++++++++++ shared/schema.ts | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/server/storage.ts b/server/storage.ts index 20d7c46..e7ba710 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -10,6 +10,8 @@ import { customerOrders, dlcProducts, tasks, + invoiceVerificationCache, + invoiceVerifications, type User, type UpsertUser, type Group, @@ -41,6 +43,10 @@ import { type DlcProductFrontend, type InsertDlcProductFrontend, type DlcProductWithRelations, + type InvoiceVerificationCache, + type InsertInvoiceVerificationCache, + type InvoiceVerification, + type InsertInvoiceVerification, type Task, type InsertTask, } from "@shared/schema"; @@ -152,6 +158,12 @@ export interface IStorage { updateTask(id: number, task: Partial): Promise; deleteTask(id: number): Promise; completeTask(id: number, completedBy?: string): Promise; + + // Invoice Verification operations - Tables existantes en production + getInvoiceVerifications(deliveryId?: number): Promise; + createInvoiceVerification(verification: InsertInvoiceVerification): Promise; + getInvoiceVerificationCache(cacheKey: string): Promise; + createInvoiceVerificationCache(cache: InsertInvoiceVerificationCache): Promise; } export class DatabaseStorage implements IStorage { @@ -2026,6 +2038,52 @@ export class DatabaseStorage implements IStorage { }) .where(eq(tasks.id, id)); } + + // Invoice Verification operations - Utilise les tables existantes en production + async getInvoiceVerifications(deliveryId?: number): Promise { + const query = db.select().from(invoiceVerifications); + if (deliveryId) { + return await query.where(eq(invoiceVerifications.deliveryId, deliveryId)); + } + return await query.orderBy(desc(invoiceVerifications.verifiedAt)); + } + + async createInvoiceVerification(verification: InsertInvoiceVerification): Promise { + const [newVerification] = await db + .insert(invoiceVerifications) + .values({ + ...verification, + verifiedAt: new Date(), + lastCheckedAt: new Date(), + }) + .returning(); + return newVerification; + } + + async getInvoiceVerificationCache(cacheKey: string): Promise { + const [cache] = await db + .select() + .from(invoiceVerificationCache) + .where( + and( + eq(invoiceVerificationCache.cacheKey, cacheKey), + sql`expires_at > NOW()` + ) + ); + return cache; + } + + async createInvoiceVerificationCache(cache: InsertInvoiceVerificationCache): Promise { + const [newCache] = await db + .insert(invoiceVerificationCache) + .values({ + ...cache, + createdAt: new Date(), + updatedAt: new Date(), + }) + .returning(); + return newCache; + } } // Simple in-memory storage for development diff --git a/shared/schema.ts b/shared/schema.ts index a2dd0f6..a2a98e3 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -217,6 +217,37 @@ export const dlcProducts = pgTable("dlc_products", { updatedAt: timestamp("updated_at").defaultNow(), // Date de mise à jour }); +// Invoice Verification Cache - Table existante en production +export const invoiceVerificationCache = pgTable("invoice_verification_cache", { + id: serial("id").primaryKey(), + cacheKey: varchar("cache_key", { length: 255 }).notNull(), + groupId: integer("group_id").notNull(), + invoiceReference: varchar("invoice_reference", { length: 255 }).notNull(), + supplierName: varchar("supplier_name", { length: 255 }), + exists: boolean("exists").notNull(), + matchType: varchar("match_type", { length: 50 }).notNull(), + errorMessage: text("error_message"), + cacheHit: boolean("cache_hit").default(false), + apiCallTime: integer("api_call_time"), + expiresAt: timestamp("expires_at").notNull(), + createdAt: timestamp("created_at").defaultNow(), + updatedAt: timestamp("updated_at").defaultNow(), +}); + +// Invoice Verifications - Table existante en production +export const invoiceVerifications = pgTable("invoice_verifications", { + id: serial("id").primaryKey(), + deliveryId: integer("delivery_id").notNull(), + groupId: integer("group_id").notNull(), + invoiceReference: varchar("invoice_reference", { length: 255 }).notNull(), + supplierName: varchar("supplier_name", { length: 255 }), + exists: boolean("exists").notNull(), + matchType: varchar("match_type", { length: 50 }), + verifiedAt: timestamp("verified_at").defaultNow(), + isValid: boolean("is_valid").default(true), + lastCheckedAt: timestamp("last_checked_at").defaultNow(), +}); + // Tasks table export const tasks = pgTable("tasks", { id: serial("id").primaryKey(), @@ -481,6 +512,18 @@ export const insertDlcProductFrontendSchema = insertDlcProductSchema .omit({ expiryDate: true }) .extend({ dlcDate: z.coerce.date() }); +export const insertInvoiceVerificationCacheSchema = createInsertSchema(invoiceVerificationCache).omit({ + id: true, + createdAt: true, + updatedAt: true, +}); + +export const insertInvoiceVerificationsSchema = createInsertSchema(invoiceVerifications).omit({ + id: true, + verifiedAt: true, + lastCheckedAt: true, +}); + export const insertTaskSchema = createInsertSchema(tasks).omit({ id: true, createdAt: true, @@ -516,6 +559,10 @@ export type DlcProduct = typeof dlcProducts.$inferSelect; export type InsertDlcProduct = z.infer; export type DlcProductFrontend = Omit & { dlcDate: Date }; export type InsertDlcProductFrontend = z.infer; +export type InvoiceVerificationCache = typeof invoiceVerificationCache.$inferSelect; +export type InsertInvoiceVerificationCache = z.infer; +export type InvoiceVerification = typeof invoiceVerifications.$inferSelect; +export type InsertInvoiceVerification = z.infer; export type Task = typeof tasks.$inferSelect; export type InsertTask = z.infer;