From 7b20c479370f6570b52bc4a7989bd598ae721561 Mon Sep 17 00:00:00 2001 From: BOHA Date: Wed, 10 Jun 2026 13:19:08 +0200 Subject: [PATCH] feat(pdf): drop the prices-excl.-VAT notice from offer/order/PO PDFs The 'Ceny jsou uvedeny bez DPH...' explanatory line is removed at user request from all three non-tax-document PDFs - the 'Celkem bez DPH' total label carries the information by itself. Dead vat_notice keys and .vat-note CSS removed; tests now pin the notice's ABSENCE (file renamed pdf-vat-note -> pdf-no-vat). Co-Authored-By: Claude Fable 5 --- src/__tests__/issued-orders.test.ts | 16 +++++------- ...df-vat-note.test.ts => pdf-no-vat.test.ts} | 26 +++++++++---------- src/routes/admin/issued-orders-pdf.ts | 11 -------- src/routes/admin/offers-pdf.ts | 13 +--------- src/routes/admin/orders-pdf.ts | 11 -------- 5 files changed, 20 insertions(+), 57 deletions(-) rename src/__tests__/{pdf-vat-note.test.ts => pdf-no-vat.test.ts} (83%) diff --git a/src/__tests__/issued-orders.test.ts b/src/__tests__/issued-orders.test.ts index 2a5e4c3..f1ba5cc 100644 --- a/src/__tests__/issued-orders.test.ts +++ b/src/__tests__/issued-orders.test.ts @@ -532,7 +532,7 @@ describe("renderIssuedOrderHtml", () => { expect(fallback).toContain("Objednáváme si u Vás:"); }); - it("never renders VAT columns, totals NET with 'Celkem bez DPH' and the prices notice", () => { + it("never renders VAT columns or notices; totals NET with 'Celkem bez DPH'", () => { const html = renderIssuedOrderHtml(order, items, null, null, "cs", issuer); // No VAT anywhere — the PO is not a tax document. expect(html).not.toContain("%DPH"); @@ -540,21 +540,17 @@ describe("renderIssuedOrderHtml", () => { // Line total = netto (2 × 100). expect(html).toContain('200,00'); expect(html).toContain("Celkem bez DPH"); - // No Mezisoučet row (it would duplicate the grand total). + // No Mezisoučet row (it would duplicate the grand total) and no + // prices-excl.-VAT notice (user removed it — the total label suffices). expect(html).not.toContain("Mezisoučet"); - // The fixed prices-excl.-VAT notice. - expect(html).toContain( - "Ceny jsou uvedeny bez DPH. DPH bude účtováno dle platných předpisů.", - ); + expect(html).not.toContain("Ceny jsou uvedeny bez DPH"); }); - it("renders the English notice and total label for lang=en", () => { + it("renders the English total label for lang=en, no VAT columns or notice", () => { const html = renderIssuedOrderHtml(order, items, null, null, "en", issuer); expect(html).toContain("Total excl. VAT"); - expect(html).toContain( - "Prices are exclusive of VAT. VAT will be charged according to applicable regulations.", - ); expect(html).not.toContain("VAT%"); + expect(html).not.toContain("Prices are exclusive of VAT"); }); it("footer shows the logged-in user's name, no e-mail, no Schválil column", () => { diff --git a/src/__tests__/pdf-vat-note.test.ts b/src/__tests__/pdf-no-vat.test.ts similarity index 83% rename from src/__tests__/pdf-vat-note.test.ts rename to src/__tests__/pdf-no-vat.test.ts index 74707a8..dad8bd0 100644 --- a/src/__tests__/pdf-vat-note.test.ts +++ b/src/__tests__/pdf-no-vat.test.ts @@ -8,14 +8,14 @@ import offersPdfRoutes from "../routes/admin/offers-pdf"; // Offers, received orders (their confirmation PDF) and issued orders are NOT // tax documents — VAT must never appear on them. These tests pin that contract -// for the confirmation and offer PDFs: no VAT columns/rows, the grand total is -// "Celkem bez DPH" / "Total excl. VAT", and the fixed prices-excl.-VAT notice -// is printed. (The issued-order PDF is covered in issued-orders.test.ts.) +// for the confirmation and offer PDFs: no VAT columns/rows/notices, and the +// grand total is "Celkem bez DPH" / "Total excl. VAT". (The issued-order PDF +// is covered in issued-orders.test.ts.) -const CS_NOTE = - "Ceny jsou uvedeny bez DPH. DPH bude účtováno dle platných předpisů."; -const EN_NOTE = - "Prices are exclusive of VAT. VAT will be charged according to applicable regulations."; +// The explanatory prices-excl.-VAT notice was removed at user request — the +// total label alone carries the information. Pin its absence too. +const CS_NOTE = "Ceny jsou uvedeny bez DPH"; +const EN_NOTE = "Prices are exclusive of VAT"; describe("renderOrderConfirmationHtml (order confirmation PDF)", () => { const order = { @@ -36,7 +36,7 @@ describe("renderOrderConfirmationHtml (order confirmation PDF)", () => { }, ]; - it("cs: NET total labeled 'Celkem bez DPH', no VAT columns, notice present", () => { + it("cs: NET total labeled 'Celkem bez DPH', no VAT columns or notice", () => { const html = renderOrderConfirmationHtml(order, items, null, "cs", "Jan"); expect(html).not.toContain("%DPH"); expect(html).not.toContain(">DPH<"); @@ -44,14 +44,14 @@ describe("renderOrderConfirmationHtml (order confirmation PDF)", () => { // Line total = netto (2 × 100), no VAT-on-top anywhere. expect(html).toContain('200,00'); expect(html).toContain("Celkem bez DPH"); - expect(html).toContain(CS_NOTE); + expect(html).not.toContain(CS_NOTE); }); - it("en: 'Total excl. VAT' + the English notice, no VAT columns", () => { + it("en: 'Total excl. VAT', no VAT columns or notice", () => { const html = renderOrderConfirmationHtml(order, items, null, "en", "Jan"); expect(html).not.toContain("VAT%"); expect(html).toContain("Total excl. VAT"); - expect(html).toContain(EN_NOTE); + expect(html).not.toContain(EN_NOTE); }); it("excludes not-included lines from the NET total", () => { @@ -107,7 +107,7 @@ afterAll(async () => { }); describe("GET /api/admin/offers-pdf/:id (offer PDF html)", () => { - it("renders NET-only totals with 'Celkem bez DPH' and the cs notice", async () => { + it("renders NET-only totals with 'Celkem bez DPH', no notice", async () => { // Direct prisma insert (explicit number → no sequence consumed). const quotation = await prisma.quotations.create({ data: { @@ -139,7 +139,7 @@ describe("GET /api/admin/offers-pdf/:id (offer PDF html)", () => { expect(res.statusCode).toBe(200); const html = res.body; expect(html).toContain("Celkem bez DPH"); - expect(html).toContain(CS_NOTE); + expect(html).not.toContain(CS_NOTE); expect(html).not.toContain("%DPH"); expect(html).not.toContain("Mezisoučet"); expect(html).not.toContain("Celkem k úhradě"); diff --git a/src/routes/admin/issued-orders-pdf.ts b/src/routes/admin/issued-orders-pdf.ts index 13ab7df..8d75bb6 100644 --- a/src/routes/admin/issued-orders-pdf.ts +++ b/src/routes/admin/issued-orders-pdf.ts @@ -203,8 +203,6 @@ const translations: Record> = { col_total: "Celkem", total_no_vat: "Celkem bez DPH", amounts_in: "Částky jsou uvedeny v", - vat_notice: - "Ceny jsou uvedeny bez DPH. DPH bude účtováno dle platných předpisů.", notes: "Poznámky", delivery_terms: "Dodací podmínky:", payment_terms: "Platební podmínky:", @@ -227,8 +225,6 @@ const translations: Record> = { col_total: "Total", total_no_vat: "Total excl. VAT", amounts_in: "Amounts are in", - vat_notice: - "Prices are exclusive of VAT. VAT will be charged according to applicable regulations.", notes: "Notes", delivery_terms: "Delivery terms:", payment_terms: "Payment terms:", @@ -593,12 +589,6 @@ export function renderIssuedOrderHtml( color: #1a1a1a; margin-top: 2mm; } - .totals .vat-note { - text-align: right; - font-size: 8pt; - color: #646464; - margin-top: 1mm; - } /* Dodaci / platebni podminky (PO-specificke) */ .terms { @@ -751,7 +741,6 @@ ${indentCSS} ${formatNum(total)} ${escapeHtml(currency)}
${escapeHtml(t.amounts_in)} ${escapeHtml(currency)}
-
${escapeHtml(t.vat_notice)}
diff --git a/src/routes/admin/offers-pdf.ts b/src/routes/admin/offers-pdf.ts index 0dd9009..b54a644 100644 --- a/src/routes/admin/offers-pdf.ts +++ b/src/routes/admin/offers-pdf.ts @@ -204,10 +204,6 @@ const TRANSLATIONS: Record> = { included: { EN: "Included", CZ: "Zahrnuto" }, total: { EN: "Total", CZ: "Celkem" }, total_no_vat: { EN: "Total excl. VAT", CZ: "Celkem bez DPH" }, - vat_notice: { - EN: "Prices are exclusive of VAT. VAT will be charged according to applicable regulations.", - CZ: "Ceny jsou uvedeny bez DPH. DPH bude \u00FA\u010Dtov\u00E1no dle platn\u00FDch p\u0159edpis\u016F.", - }, ico: { EN: "ID", CZ: "I\u010CO" }, dic: { EN: "VAT ID", CZ: "DI\u010C" }, page: { EN: "Page", CZ: "Strana" }, @@ -321,8 +317,7 @@ export default async function offersPdfRoutes( const totalsHtml = `
${escapeHtml(t("total_no_vat"))} ${formatCurrency(total, currency)} -
-
${escapeHtml(t("vat_notice"))}
`; + `; const quotationNumber = escapeHtml(quotation.quotation_number); let scopeHtml = ""; @@ -566,12 +561,6 @@ ${indentCSS} border-bottom: 2.5pt solid #de3a3a; padding-bottom: 1mm; } - .totals .vat-note { - text-align: right; - font-size: 8pt; - color: #646464; - margin-top: 2mm; - } /* ---- Scope sections ---- */ .scope-page { diff --git a/src/routes/admin/orders-pdf.ts b/src/routes/admin/orders-pdf.ts index 52c6f7f..debcaf0 100644 --- a/src/routes/admin/orders-pdf.ts +++ b/src/routes/admin/orders-pdf.ts @@ -194,8 +194,6 @@ const translations: Record> = { col_total: "Celkem", total_no_vat: "Celkem bez DPH", amounts_in: "Částky jsou uvedeny v", - vat_notice: - "Ceny jsou uvedeny bez DPH. DPH bude účtováno dle platných předpisů.", notes: "Poznámky", issued_by: "Vystavil:", received_by: "Převzal:", @@ -219,8 +217,6 @@ const translations: Record> = { col_total: "Total", total_no_vat: "Total excl. VAT", amounts_in: "Amounts are in", - vat_notice: - "Prices are exclusive of VAT. VAT will be charged according to applicable regulations.", notes: "Notes", issued_by: "Issued by:", received_by: "Received by:", @@ -573,12 +569,6 @@ export function renderOrderConfirmationHtml( color: #1a1a1a; margin-top: 2mm; } - .totals .vat-note { - text-align: right; - font-size: 8pt; - color: #646464; - margin-top: 1mm; - } /* Vystavil */ .issued-by { @@ -736,7 +726,6 @@ ${indentCSS} ${formatNum(total)} ${escapeHtml(currency)}
${escapeHtml(t.amounts_in)} ${escapeHtml(currency)}
-
${escapeHtml(t.vat_notice)}