diff --git a/client/src/App.tsx b/client/src/App.tsx index 8227c19..912130c 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -9,6 +9,7 @@ import Login from "./pages/Login"; import Dashboard from "./pages/Dashboard"; import Upload from "./pages/Upload"; import Invoices from "./pages/Invoices"; +import InvoicesBAP from "./pages/InvoicesBAP"; import InvoiceDetail from "./pages/InvoiceDetail"; import Settings from "./pages/Settings"; import ImportSettings from "./pages/ImportSettings"; @@ -24,6 +25,7 @@ function Router() { + diff --git a/client/src/components/DashboardLayout.tsx b/client/src/components/DashboardLayout.tsx index 281a8e7..8d85cd9 100644 --- a/client/src/components/DashboardLayout.tsx +++ b/client/src/components/DashboardLayout.tsx @@ -31,6 +31,7 @@ const menuItems = [ { icon: LayoutDashboard, label: "Tableau de bord", path: "/dashboard" }, { icon: Upload, label: "Importer", path: "/upload" }, { icon: FileText, label: "Factures", path: "/invoices" }, + { icon: FileText, label: "Factures BAP", path: "/invoices-bap" }, { icon: History, label: "Historique", path: "/history" }, { icon: Settings, label: "Paramètres", path: "/settings" }, { icon: Download, label: "Paramètres de réception", path: "/import-settings" }, diff --git a/client/src/pages/Invoices.tsx b/client/src/pages/Invoices.tsx index 0458f01..8dad30c 100644 --- a/client/src/pages/Invoices.tsx +++ b/client/src/pages/Invoices.tsx @@ -407,8 +407,6 @@ export default function Invoices() { Date Montant Service - Type achat - Ventilation Abonnement Score Statut @@ -469,47 +467,6 @@ export default function Invoices() { - - - - - - setSearchQuery(e.target.value)} + className="pl-10" + /> + + + + {/* Status Filters */} +
+ + + + +
+ + {/* Table */} + {isLoading ? ( +
Chargement...
+ ) : filteredInvoices && filteredInvoices.length > 0 ? ( +
+ + + + + + + Fournisseur + N° Facture + Date + Montant + Service + Type achat + Ventilation + Abonnement + Score + Statut + Actions + + + + {filteredInvoices.map((invoice) => { + return ( + + + handleSelectOne(invoice.id, checked as boolean)} + /> + + + + + {invoice.invoiceNumber || "-"} + + {invoice.invoiceDate + ? new Date(invoice.invoiceDate).toLocaleDateString("fr-FR") + : "-"} + + + {invoice.totalAmount + ? `${parseFloat(invoice.totalAmount as string).toFixed(2)} €` + : "-"} + + + + + + + + + + + + + + {getQualityBadge(invoice.qualityScore)} + {getExportStatusBadge(invoice.exportStatus || "not_exported")} + +
+ + + +
+
+
+ ); + })} +
+
+
+ ) : ( +
+ +

Aucune facture trouvée

+

+ {searchQuery ? "Essayez une autre recherche" : "Commencez par importer un fichier PDF"} +

+
+ )} + + + + {/* Info message */} + {filteredInvoices && filteredInvoices.some(inv => (inv.qualityScore || 0) < 100) && ( +
+

+ Note : Seules les factures avec un score de qualité de 100% peuvent être exportées. + Les factures avec un score inférieur sont grisées et ne peuvent pas être sélectionnées. +

+
+ )} + + + {/* Delete Confirmation Dialog */} + + + + Êtes-vous sûr de vouloir supprimer cette facture ? + + Cette action est irréversible. La facture sera définitivement supprimée de la base de données. + + + + setInvoiceToDelete(null)}>Annuler + { + if (invoiceToDelete) { + deleteMutation.mutate({ id: invoiceToDelete }); + } + }} + className="bg-red-600 hover:bg-red-700" + > + Supprimer + + + + + + {/* Add New Item Dialog */} + + + + + Ajouter {addDialogType === "service" ? "un nouveau service" : "une nouvelle ventilation"} + + + Entrez le nom {addDialogType === "service" ? "du service" : "de la ventilation comptable"} à ajouter. + + +
+ setNewItemName(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") { + handleAddNewItem(); + } + }} + autoFocus + /> +
+ + + + +
+
+ + {/* Extracted Text Dialog */} + + + + Texte extrait de la facture + + Texte complet extrait du PDF lors de l'import + + +
+
{selectedInvoiceText}
+
+ + + +
+
+ + ); +} diff --git a/todo.md b/todo.md index 673dce4..fec98d0 100644 --- a/todo.md +++ b/todo.md @@ -266,3 +266,20 @@ - [x] Corriger le prompt pour utiliser UNIQUEMENT les mots-clés configurés dans subscriptionKeywords - [x] Ajouter logique: si subscriptionKeywords est vide, isSubscription = false par défaut - [ ] Tester avec une nouvelle facture importée et le mot-clé "BLOB" (ne devrait pas détecter) + +## Nouvelle page Factures BAP +- [ ] Créer une nouvelle page InvoicesBAP.tsx affichant uniquement les factures avec Abonnement = NON +- [ ] Inclure les colonnes Type d'achat et Ventilation dans la page Factures BAP +- [ ] Ajouter la route /invoices-bap dans App.tsx +- [ ] Ajouter le lien "Factures BAP" dans le menu de navigation +- [ ] Supprimer les colonnes Type d'achat et Ventilation de la page Factures principale +- [ ] Tester le filtrage et l'affichage des factures BAP + +## Page Factures BAP +- [x] Créer nouvelle page InvoicesBAP.tsx basée sur Invoices.tsx +- [x] Filtrer uniquement les factures avec Abonnement = NON (isSubscription = 0) +- [x] Inclure les colonnes Type d'achat et Ventilation dans Factures BAP +- [x] Supprimer les colonnes Type d'achat et Ventilation de la page Factures principale +- [x] Ajouter la route /invoices-bap dans App.tsx +- [x] Ajouter le menu "Factures BAP" dans DashboardLayout +- [ ] Tester le filtrage et l'édition directe dans la nouvelle page