Checkpoint: Ajout du bouton "Valider tout en BAP" sur la fenêtre Factures BAP : route validateBAPBulk côté serveur (traitement de toutes les factures éligibles en une passe), mutation côté client avec ouverture des PDFs générés, bouton vert dans le header de la page.

This commit is contained in:
Manus
2026-04-12 09:40:33 -04:00
parent d07ff1b34d
commit 76554214b2
3 changed files with 211 additions and 6 deletions

View File

@@ -32,7 +32,7 @@ import {
TableRow,
} from "@/components/ui/table";
import { trpc } from "@/lib/trpc";
import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash, CheckCircle, CheckCircle2 } from "lucide-react";
import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash, CheckCircle, CheckCircle2, ShieldCheck } from "lucide-react";
import * as XLSX from 'xlsx';
import { toast } from "sonner";
import { useLocation } from "wouter";
@@ -131,6 +131,24 @@ export default function InvoicesBAP() {
},
});
const validateBAPBulkMutation = trpc.invoices.validateBAPBulk.useMutation({
onSuccess: (data) => {
if (data.processed === 0) {
toast.info("Aucune facture éligible à valider en BAP.");
} else {
toast.success(`${data.processed} facture(s) validée(s) BAP avec succès !`, { duration: 4000 });
const pdfUrls = (data.results as any[]).filter(r => r.pdfUrl).map(r => r.pdfUrl as string);
if (pdfUrls.length > 0) {
pdfUrls.forEach(url => window.open(url, '_blank'));
}
}
utils.invoices.list.invalidate();
},
onError: (error) => {
toast.error(error.message || "Erreur lors de la validation BAP en masse");
},
});
const validateBAPMutation = trpc.invoices.validateBAP.useMutation({
onSuccess: (data) => {
if (data.exportMode === 'browser' && data.pdfUrl) {
@@ -403,6 +421,18 @@ export default function InvoicesBAP() {
<Trash2 className="w-4 h-4 mr-2" />
Supprimer ({selectedIds.length})
</Button>
<Button
onClick={() => {
if (confirm("Valider en BAP toutes les factures éligibles (score 100%, champs remplis, non abonnement) ? Les PDFs annotés seront générés automatiquement.")) {
validateBAPBulkMutation.mutate();
}
}}
disabled={validateBAPBulkMutation.isPending}
className="bg-green-700 hover:bg-green-800 text-white"
>
<ShieldCheck className="w-4 h-4 mr-2" />
{validateBAPBulkMutation.isPending ? "Validation en cours..." : "Valider tout en BAP"}
</Button>
<Button onClick={() => setLocation("/upload")}>
<FileText className="w-4 h-4 mr-2" />
Importer