Extend document title levels
This commit is contained in:
@@ -399,6 +399,12 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
|
||||
let pageIndex = 0
|
||||
|
||||
const getTitleKey = (row) => `${row.pos} - ${row.text}`
|
||||
const getTransferSumText = (row) => {
|
||||
const transferSum = invoiceData.total.titleSumsTransfer[getTitleKey(row)]
|
||||
|
||||
return transferSum ? `Übertrag: ${transferSum}` : null
|
||||
}
|
||||
|
||||
invoiceData.rows.forEach((row, index) => {
|
||||
|
||||
@@ -579,8 +585,9 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
|
||||
console.log(invoiceData.rows[index + 1])
|
||||
|
||||
if (invoiceData.rows[index + 1].mode === 'title') {
|
||||
let transferSumText = `Übertrag: ${invoiceData.total.titleSumsTransfer[Object.keys(invoiceData.total.titleSums)[invoiceData.rows[index + 1].pos - 2]]}`
|
||||
if (invoiceData.rows[index + 1]?.mode === 'title') {
|
||||
const transferSumText = getTransferSumText(invoiceData.rows[index + 1])
|
||||
if (transferSumText) {
|
||||
pages[pageCounter - 1].drawText(transferSumText, {
|
||||
y: getCoordinatesForPDFLib(21, rowHeight - 2, page1).y,
|
||||
x: getCoordinatesForPDFLib(21, rowHeight - 2, page1).x + 500 - fontBold.widthOfTextAtSize(transferSumText, 10),
|
||||
@@ -592,6 +599,7 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
font: fontBold
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const page = pdfDoc.addPage()
|
||||
@@ -713,7 +721,8 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
if (index === 0 || pageIndex === 0) {
|
||||
rowHeight += 3
|
||||
} else {
|
||||
let transferSumText = `Übertrag: ${invoiceData.total.titleSumsTransfer[Object.keys(invoiceData.total.titleSums)[row.pos - 2]]}`
|
||||
const transferSumText = getTransferSumText(row)
|
||||
if (transferSumText) {
|
||||
pages[pageCounter - 1].drawText(transferSumText, {
|
||||
y: getCoordinatesForPDFLib(21, rowHeight - 2, page1).y,
|
||||
x: getCoordinatesForPDFLib(21, rowHeight - 2, page1).x + 500 - fontBold.widthOfTextAtSize(transferSumText, 10),
|
||||
@@ -724,6 +733,7 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
maxWidth: 240,
|
||||
font: fontBold
|
||||
})
|
||||
}
|
||||
|
||||
pages[pageCounter - 1].drawLine({
|
||||
start: getCoordinatesForPDFLib(20, rowHeight, page1),
|
||||
@@ -735,6 +745,10 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
rowHeight += 5
|
||||
}
|
||||
|
||||
const titleLevel = Math.min(Math.max(Number(row.titleLevel) || 1, 1), 3)
|
||||
const titleTextSize = titleLevel === 1 ? 12 : titleLevel === 2 ? 11 : 10
|
||||
const titleTextX = 35 + ((titleLevel - 1) * 7)
|
||||
|
||||
pages[pageCounter - 1].drawText(String(row.pos), {
|
||||
...getCoordinatesForPDFLib(21, rowHeight, page1),
|
||||
size: 10,
|
||||
@@ -746,16 +760,16 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
|
||||
})
|
||||
|
||||
pages[pageCounter - 1].drawText(splitStringBySpace(row.text, 60).join("\n"), {
|
||||
...getCoordinatesForPDFLib(35, rowHeight, page1),
|
||||
size: 12,
|
||||
...getCoordinatesForPDFLib(titleTextX, rowHeight, page1),
|
||||
size: titleTextSize,
|
||||
color: rgb(0, 0, 0),
|
||||
lineHeight: 12,
|
||||
lineHeight: titleTextSize,
|
||||
opacity: 1,
|
||||
maxWidth: 500,
|
||||
font: fontBold
|
||||
})
|
||||
|
||||
rowHeight += splitStringBySpace(row.text, 60).length * 4.5
|
||||
rowHeight += splitStringBySpace(row.text, 60).length * (titleLevel === 1 ? 4.5 : 4)
|
||||
} else if (row.mode === 'text') {
|
||||
if (index === 0 || pageIndex === 0) {
|
||||
rowHeight += 3
|
||||
|
||||
@@ -108,6 +108,11 @@ const taxTypeItems = [
|
||||
{ key: '19 UStG', label: '19 UStG Kleinunternehmer' },
|
||||
{ key: '12.3 UStG', label: '12.3 UStG' }
|
||||
]
|
||||
const titleLevelItems = [
|
||||
{ label: 'Titel Ebene 1', value: 1 },
|
||||
{ label: 'Untertitel Ebene 2', value: 2 },
|
||||
{ label: 'Untertitel Ebene 3', value: 3 }
|
||||
]
|
||||
const deliveryDateTypeItems = ['Lieferdatum', 'Lieferzeitraum', 'Leistungsdatum', 'Leistungszeitraum', 'Kein Lieferdatum anzeigen']
|
||||
const paymentTypeItems = [
|
||||
{ key: 'transfer', label: 'Überweisung' },
|
||||
@@ -832,6 +837,7 @@ const positionAddOptions = [
|
||||
{ mode: 'free', label: 'Freie Position', icon: 'i-heroicons-pencil-square' },
|
||||
{ mode: 'pagebreak', label: 'Seitenumbruch', icon: 'i-heroicons-document-minus' },
|
||||
{ mode: 'title', label: 'Titel', icon: 'i-heroicons-bars-3-bottom-left' },
|
||||
{ mode: 'subtitle', label: 'Untertitel', icon: 'i-heroicons-list-bullet' },
|
||||
{ mode: 'text', label: 'Text', icon: 'i-heroicons-document-text' }
|
||||
]
|
||||
|
||||
@@ -895,10 +901,11 @@ const createPositionRow = (mode, taxPercentage) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (mode === "title") {
|
||||
if (mode === "title" || mode === "subtitle") {
|
||||
return {
|
||||
id: uuidv4(),
|
||||
mode: "title",
|
||||
titleLevel: mode === "subtitle" ? 2 : 1,
|
||||
linkedEntitys: []
|
||||
}
|
||||
}
|
||||
@@ -1152,12 +1159,10 @@ const documentTotal = computed(() => {
|
||||
if (row.mode === 'title') {
|
||||
let title = `${row.pos} - ${row.text}`
|
||||
titleSums[title] = 0
|
||||
if (lastTitle) {
|
||||
titleSumsTransfer[title] = transferCounter
|
||||
}
|
||||
lastTitle = title
|
||||
|
||||
//Übertrag berechnen
|
||||
titleSumsTransfer[Object.keys(titleSums)[row.pos - 2]] = transferCounter
|
||||
|
||||
|
||||
} else if (!['pagebreak', 'text'].includes(row.mode) && lastTitle !== "" && !row.optional && !row.alternative) {
|
||||
titleSums[lastTitle] = Number(titleSums[lastTitle]) + Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) / 100))
|
||||
transferCounter += Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) / 100))
|
||||
@@ -1610,16 +1615,33 @@ const onChangeTab = (index) => {
|
||||
}
|
||||
|
||||
const setPosNumbers = () => {
|
||||
let mainIndex = 1
|
||||
let subIndex = 1
|
||||
let titleCounters = [0, 0, 0]
|
||||
let positionIndex = 1
|
||||
let currentTitlePath = []
|
||||
const hasTitles = itemInfo.value.rows.some(row => row.mode === "title")
|
||||
|
||||
let rows = itemInfo.value.rows.map(row => {
|
||||
if (row.mode === 'title') {
|
||||
row.pos = mainIndex
|
||||
mainIndex += 1
|
||||
subIndex = 1
|
||||
const titleLevel = Math.min(Math.max(Number(row.titleLevel) || 1, 1), titleCounters.length)
|
||||
row.titleLevel = titleLevel
|
||||
|
||||
for (let index = 0; index < titleLevel - 1; index += 1) {
|
||||
if (titleCounters[index] === 0) {
|
||||
titleCounters[index] = 1
|
||||
}
|
||||
}
|
||||
|
||||
titleCounters[titleLevel - 1] += 1
|
||||
for (let index = titleLevel; index < titleCounters.length; index += 1) {
|
||||
titleCounters[index] = 0
|
||||
}
|
||||
|
||||
currentTitlePath = titleCounters.slice(0, titleLevel)
|
||||
row.pos = currentTitlePath.join(".")
|
||||
positionIndex = 1
|
||||
} else if (!['pagebreak', 'title', 'text'].includes(row.mode)) {
|
||||
row.pos = itemInfo.value.rows.filter(i => i.mode === "title").length === 0 ? `${subIndex}` : `${mainIndex - 1}.${subIndex}`
|
||||
subIndex += 1
|
||||
row.pos = hasTitles && currentTitlePath.length > 0 ? `${currentTitlePath.join(".")}.${positionIndex}` : `${positionIndex}`
|
||||
positionIndex += 1
|
||||
}
|
||||
|
||||
if (!row.id) {
|
||||
@@ -3471,12 +3493,22 @@ const setRowData = async (row, service = {sellingPriceComposed: {}}, product = {
|
||||
v-if="row.mode === 'title'"
|
||||
:colspan="getTitlePositionColspan()"
|
||||
>
|
||||
<InputGroup class="w-full">
|
||||
<USelect
|
||||
:disabled="itemInfo.type === 'cancellationInvoices'"
|
||||
v-model="row.titleLevel"
|
||||
:items="titleLevelItems"
|
||||
value-key="value"
|
||||
class="w-44 shrink-0"
|
||||
@update:model-value="setPosNumbers"
|
||||
/>
|
||||
<UInput
|
||||
:disabled="itemInfo.type === 'cancellationInvoices'"
|
||||
v-model="row.text"
|
||||
placeholder="Titel"
|
||||
class="w-full"
|
||||
class="w-full min-w-0"
|
||||
/>
|
||||
</InputGroup>
|
||||
</td>
|
||||
<td>
|
||||
<UDropdownMenu
|
||||
|
||||
Reference in New Issue
Block a user