fix(pdf): hide transfer amounts on packing slips and delivery notes
This commit is contained in:
@@ -488,6 +488,8 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
|||||||
|
|
||||||
const getTitleKey = (row) => `${row.pos} - ${row.text}`
|
const getTitleKey = (row) => `${row.pos} - ${row.text}`
|
||||||
const getTransferSumText = (row) => {
|
const getTransferSumText = (row) => {
|
||||||
|
if (deliveryNoteLikeDocumentTypes.includes(invoiceData.type)) return null
|
||||||
|
|
||||||
const transferSum = invoiceData.total.titleSumsTransfer[getTitleKey(row)]
|
const transferSum = invoiceData.total.titleSumsTransfer[getTitleKey(row)]
|
||||||
|
|
||||||
return transferSum ? `Übertrag: ${transferSum}` : null
|
return transferSum ? `Übertrag: ${transferSum}` : null
|
||||||
|
|||||||
88
backend/tests/pdfTransferSums.test.ts
Normal file
88
backend/tests/pdfTransferSums.test.ts
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import assert from "node:assert/strict"
|
||||||
|
import { Readable } from "node:stream"
|
||||||
|
import test from "node:test"
|
||||||
|
import { PDFDocument, PDFPage } from "pdf-lib"
|
||||||
|
import { createInvoicePDF } from "../src/utils/pdf"
|
||||||
|
import { initS3, s3 } from "../src/utils/s3"
|
||||||
|
|
||||||
|
const createDocumentData = (type: string) => {
|
||||||
|
const item = (pos: string) => ({
|
||||||
|
mode: "normal",
|
||||||
|
pos,
|
||||||
|
text: `Artikel ${pos}`,
|
||||||
|
quantity: "1",
|
||||||
|
unit: "Stk",
|
||||||
|
taxPercent: 19,
|
||||||
|
price: "25,00 €",
|
||||||
|
rowAmount: "25,00 €",
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
adressLine: "Musterfirma, Musterweg 1, 12345 Musterstadt",
|
||||||
|
recipient: ["Musterkunde"],
|
||||||
|
info: [],
|
||||||
|
title: type === "packingSlips" ? "Packschein" : type === "deliveryNotes" ? "Lieferschein" : "Rechnung",
|
||||||
|
description: "Abschnitte mit Seitenumbruch",
|
||||||
|
startText: "Ihre Artikel:",
|
||||||
|
endText: "Vielen Dank.",
|
||||||
|
rows: [
|
||||||
|
{ mode: "title", pos: "1", text: "Abschnitt A" },
|
||||||
|
item("1.1"),
|
||||||
|
{ mode: "title", pos: "2", text: "Abschnitt B" },
|
||||||
|
item("2.1"),
|
||||||
|
{ mode: "pagebreak" },
|
||||||
|
{ mode: "title", pos: "3", text: "Abschnitt C" },
|
||||||
|
item("3.1"),
|
||||||
|
],
|
||||||
|
total: {
|
||||||
|
titleSums: {
|
||||||
|
"1 - Abschnitt A": "25,00 €",
|
||||||
|
"2 - Abschnitt B": "25,00 €",
|
||||||
|
"3 - Abschnitt C": "25,00 €",
|
||||||
|
},
|
||||||
|
titleSumsTransfer: {
|
||||||
|
"2 - Abschnitt B": "25,00 €",
|
||||||
|
"3 - Abschnitt C": "50,00 €",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
totalArray: [{ label: "Nettobetrag", content: "75,00 €" }],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const type of ["packingSlips", "deliveryNotes", "invoices"]) {
|
||||||
|
test(`${type}: renders transfers only for priced documents, including before page breaks`, async t => {
|
||||||
|
const background = await PDFDocument.create()
|
||||||
|
background.addPage().drawText("Musterfirma", { x: 60, y: 800, size: 12 })
|
||||||
|
const backgroundBytes = await background.save()
|
||||||
|
|
||||||
|
await initS3()
|
||||||
|
t.mock.method(s3, "send", async () => ({ Body: Readable.from([backgroundBytes]) }))
|
||||||
|
const drawText = t.mock.method(PDFPage.prototype, "drawText")
|
||||||
|
|
||||||
|
const result = await createInvoicePDF(null, "base64", createDocumentData(type), "test-letterhead.pdf")
|
||||||
|
assert.equal(result?.mimeType, "application/pdf")
|
||||||
|
const pdf = await PDFDocument.load(Buffer.from(result!.base64, "base64"))
|
||||||
|
assert.equal(pdf.getPageCount(), 2)
|
||||||
|
|
||||||
|
const texts = drawText.mock.calls.map(call => call.arguments[0])
|
||||||
|
for (const text of ["Abschnitt A", "Abschnitt B", "Abschnitt C", "Artikel 1.1", "Artikel 2.1", "Artikel 3.1"]) {
|
||||||
|
assert.ok(texts.includes(text), `Missing document content: ${text}`)
|
||||||
|
}
|
||||||
|
assert.equal(texts.filter(text => text === "1 Stk").length, 3)
|
||||||
|
assert.equal(texts.filter(text => text === "Check").length, type === "packingSlips" ? 2 : 0)
|
||||||
|
|
||||||
|
const transfers = texts.filter(text => text.startsWith("Übertrag:"))
|
||||||
|
if (type === "invoices") {
|
||||||
|
assert.deepEqual(transfers, ["Übertrag: 25,00 €", "Übertrag: 50,00 €"])
|
||||||
|
assert.ok(texts.includes("75,00 €"))
|
||||||
|
assert.equal(texts.filter(text => text === "Einheitspreis").length, 2)
|
||||||
|
} else {
|
||||||
|
assert.deepEqual(transfers, [])
|
||||||
|
assert.ok(texts.every(text => !text.includes("€")), "Delivery documents must not display monetary amounts")
|
||||||
|
for (const label of ["Steuer", "Einheitspreis", "Gesamt", "Nettobetrag"]) {
|
||||||
|
assert.ok(!texts.includes(label), `Unexpected price label: ${label}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user