fix: require BAP before original PDF exports

This commit is contained in:
Manus
2026-10-09 08:44:02 +00:00
parent e402233120
commit 939dddd1d8
6 changed files with 157 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
import { z } from "zod";
import { COOKIE_NAME } from "@shared/const";
import { BAP_MIN_QUALITY_SCORE, meetsBapQualityThreshold } from "@shared/bapEligibility";
import { requiresBapBeforeOriginalPdfExport } from "@shared/bapExportGuard";
import { calculateInvoiceQualityScore, withCalculatedInvoiceQuality } from "@shared/invoiceQuality";
import { webPortalUrlSchema } from "./webPortalUrl";
@@ -1407,6 +1408,19 @@ export const appRouter = router({
message: "Toutes les factures doivent avoir un score de qualité de 100% pour être exportées"
});
}
// Un PDF hors abonnement doit suivre le circuit BAP. Sans ce contrôle
// serveur, l'export manuel contournait la validation BAP puis rendait
// l'état métier incohérent dans la liste des factures.
const invoicesAwaitingBap = invoices.filter(
(invoice) => invoice && requiresBapBeforeOriginalPdfExport(invoice),
);
if (invoicesAwaitingBap.length > 0) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "La validation BAP est requise avant l'export PDF des factures hors abonnement.",
});
}
// La destination est résolue facture par facture : une sélection peut
// contenir plusieurs abonnements avec des règles de priorité distinctes.
@@ -1649,6 +1663,19 @@ export const appRouter = router({
throw new TRPCError({ code: "BAD_REQUEST", message: "SFTP not configured" });
}
const selectedInvoices = await Promise.all(input.invoiceIds.map(id => getInvoiceById(id)));
const invoicesAwaitingBap = selectedInvoices.filter(
(invoice) => invoice
&& (ctx.user.role === "admin" || invoice.userId === ctx.user.id)
&& requiresBapBeforeOriginalPdfExport(invoice),
);
if (invoicesAwaitingBap.length > 0) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "La validation BAP est requise avant l'export SFTP des factures hors abonnement.",
});
}
// Load user settings to check recipient filter
const userSettings = await getUserSettings(ctx.user.id);
const recipientFilter = (userSettings as any)?.sftpRecipientFilter?.trim() || "";