Checkpoint: Le seuil d’éligibilité et de validation BAP est centralisé à 90 % dans le serveur et l’interface. Les validations unitaires, TypeScript, build et rendu de la page Factures BAP sont réussis en sandbox.

This commit is contained in:
Manus
2026-08-27 13:02:07 +00:00
parent a88b342a0d
commit a0c440dfae
5 changed files with 42 additions and 9 deletions

View File

@@ -32,6 +32,7 @@ import {
TableRow,
} from "@/components/ui/table";
import { trpc } from "@/lib/trpc";
import { BAP_MIN_QUALITY_SCORE, meetsBapQualityThreshold } from "@shared/bapEligibility";
import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash, CheckCircle, CheckCircle2, ShieldCheck, RefreshCw, FolderDown, ChevronDown, ChevronRight, ChevronsUpDown, CalendarDays, ArrowUpDown, ArrowUp, ArrowDown } from "lucide-react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
@@ -394,7 +395,7 @@ export default function InvoicesBAP() {
// Déclarée ici (avant filteredInvoices et statusCounts) pour éviter le hoisting error
const isEligibleForBAPValidation = (invoice: any) => {
return (
(invoice.qualityScore || 0) === 100 &&
meetsBapQualityThreshold(invoice.qualityScore) &&
invoice.exportStatus !== "exported" &&
invoice.isSubscription === 0 &&
invoice.serviceConcerne &&
@@ -526,19 +527,19 @@ export default function InvoicesBAP() {
const getQualityBadge = (score: number | null) => {
if (score === null) return <Badge variant="outline">-</Badge>;
if (score === 100) return <Badge className="bg-green-100 text-green-800 hover:bg-green-100">{score}%</Badge>;
if (meetsBapQualityThreshold(score)) return <Badge className="bg-green-100 text-green-800 hover:bg-green-100">{score}%</Badge>;
if (score >= 80) return <Badge className="bg-yellow-100 text-yellow-800 hover:bg-yellow-100">{score}%</Badge>;
return <Badge className="bg-red-100 text-red-800 hover:bg-red-100">{score}%</Badge>;
};
const isEligibleForExport = (invoice: any) => {
// Une facture BAP est exportable si :
// 1. Score = 100%
// 1. Score >= 90 % (seuil BAP)
// 2. Type d'achat rempli
// 3. Service concerné rempli
// 4. Ventilation comptable remplie
return (
(invoice.qualityScore || 0) === 100 &&
meetsBapQualityThreshold(invoice.qualityScore) &&
invoice.typeAchat &&
invoice.serviceConcerne &&
invoice.ventilationComptable
@@ -549,7 +550,7 @@ export default function InvoicesBAP() {
const getBAPValidationTooltip = (invoice: any): string => {
const reasons: string[] = [];
if ((invoice.qualityScore || 0) < 100) reasons.push("Score < 100%");
if (!meetsBapQualityThreshold(invoice.qualityScore)) reasons.push(`Score < ${BAP_MIN_QUALITY_SCORE}%`);
if (invoice.exportStatus === "exported") reasons.push("Déjà exportée");
if (invoice.isSubscription !== 0) reasons.push("Marquée comme abonnement");
if (!invoice.serviceConcerne) reasons.push("Service manquant");
@@ -655,7 +656,7 @@ export default function InvoicesBAP() {
</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.")) {
if (confirm(`Valider en BAP toutes les factures éligibles (score ${BAP_MIN_QUALITY_SCORE}%, champs remplis, non abonnement) ? Les PDFs annotés seront générés automatiquement.`)) {
validateBAPBulkMutation.mutate();
}
}}