From cf31d4370223d4f359e83ec3a724e29f591407e8 Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Sat, 8 Nov 2025 18:49:21 +0100 Subject: [PATCH] Redone Times --- components/StaffTimeEntryModal.vue | 116 +++ composables/useFormat.ts | 8 + composables/usePDFGenerator.js | 1046 --------------------- composables/useWorkingTimePDFGenerator.js | 232 ----- composables/useZipCheck.js | 8 - pages/{export.vue => export/index.vue} | 6 +- pages/staff/time/[id]/evaluate.vue | 234 +++++ pages/staff/time/index.vue | 173 ++++ pages/workingtimes/[mode]/[[id]].vue | 150 --- pages/workingtimes/evaluate/[id].vue | 291 ------ pages/workingtimes/index.vue | 327 ------- 11 files changed, 536 insertions(+), 2055 deletions(-) create mode 100644 components/StaffTimeEntryModal.vue create mode 100644 composables/useFormat.ts delete mode 100644 composables/usePDFGenerator.js delete mode 100644 composables/useWorkingTimePDFGenerator.js delete mode 100644 composables/useZipCheck.js rename pages/{export.vue => export/index.vue} (96%) create mode 100644 pages/staff/time/[id]/evaluate.vue create mode 100644 pages/staff/time/index.vue delete mode 100644 pages/workingtimes/[mode]/[[id]].vue delete mode 100644 pages/workingtimes/evaluate/[id].vue delete mode 100644 pages/workingtimes/index.vue diff --git a/components/StaffTimeEntryModal.vue b/components/StaffTimeEntryModal.vue new file mode 100644 index 0000000..f1f5c33 --- /dev/null +++ b/components/StaffTimeEntryModal.vue @@ -0,0 +1,116 @@ + + + diff --git a/composables/useFormat.ts b/composables/useFormat.ts new file mode 100644 index 0000000..c908968 --- /dev/null +++ b/composables/useFormat.ts @@ -0,0 +1,8 @@ +export const useFormatDuration = (durationInMinutes:number,) => { + if (!durationInMinutes || durationInMinutes <= 0) return "00:00" + + const hrs = Math.floor(durationInMinutes / 60) + const mins = Math.floor(durationInMinutes % 60) + + return `${String(hrs).padStart(2, "0")}:${String(mins).padStart(2, "0")}` +} \ No newline at end of file diff --git a/composables/usePDFGenerator.js b/composables/usePDFGenerator.js deleted file mode 100644 index 046f66e..0000000 --- a/composables/usePDFGenerator.js +++ /dev/null @@ -1,1046 +0,0 @@ -import {PDFDocument, StandardFonts, rgb} from "pdf-lib" - - - -const getCoordinatesForPDFLib = (x ,y, page) => { - /* - * @param x the wanted X Parameter in Millimeters from Top Left - * @param y the wanted Y Parameter in Millimeters from Top Left - * @param page the page Object - * - * @returns x,y object - * */ - - - let retX = x * 2.83 - let retY = page.getHeight()-(y*2.83) - - return { - x: retX, - y: retY - } - -} - - - - -export const useCreatePdf = async (invoiceData,backgroundSourceBuffer) => { - - const uri = ref("test") - const genPDF = async () => { - const pdfDoc = await PDFDocument.create() - - const font = await pdfDoc.embedFont(StandardFonts.Helvetica) - const fontBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold) - - let pages = [] - let pageCounter = 1 - - - - //const backgroundPdfSourceBuffer = await fetch("/Briefpapier.pdf").then((res) => res.arrayBuffer()) - const backgroudPdf = await PDFDocument.load(backgroundSourceBuffer) - - const firstPageBackground = await pdfDoc.embedPage(backgroudPdf.getPages()[0]) - const secondPageBackground = await pdfDoc.embedPage(backgroudPdf.getPages()[backgroudPdf.getPages().length > 1 ? 1 : 0]) - - //console.log("TEST") - const page1 = pdfDoc.addPage() - - //console.log(page1.getSize().width/2.83) - - page1.drawPage(firstPageBackground, { - x: 0, - y: 0, - }) - //console.log(page1.getSize()) - pages.push(page1) - //console.log(pages) - - - //Falzmarke 1 - pages[pageCounter - 1].drawLine({ - start: getCoordinatesForPDFLib(0,105,page1), - end: getCoordinatesForPDFLib(7,105,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - }) - - //Lochmarke - pages[pageCounter - 1].drawLine({ - start: getCoordinatesForPDFLib(0,148.5,page1), - end: getCoordinatesForPDFLib(7,148.5,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - }) - - //Falzmarke 2 - pages[pageCounter - 1].drawLine({ - start: getCoordinatesForPDFLib(0,210,page1), - end: getCoordinatesForPDFLib(7,210,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - }) - - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(20,45,page1), - end: getCoordinatesForPDFLib(105,45,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - pages[pageCounter - 1].drawText(invoiceData.adressLine, { - ...getCoordinatesForPDFLib(21,48, page1), - size:6, - color:rgb(0,0,0), - lineHeight:6, - opacity: 1, - maxWidth: 240 - }) - - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(20,50,page1), - end: getCoordinatesForPDFLib(105,50,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - - - - pages[pageCounter - 1].drawText(invoiceData.recipient.name, { - ...getCoordinatesForPDFLib(21,55, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - if(invoiceData.recipient.contact && !invoiceData.recipient.special) { - pages[pageCounter - 1].drawText(invoiceData.recipient.contact, { - ...getCoordinatesForPDFLib(21,60, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(invoiceData.recipient.street, { - ...getCoordinatesForPDFLib(21,65, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(`${invoiceData.recipient.zip} ${invoiceData.recipient.city}`, { - ...getCoordinatesForPDFLib(21,70, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } else if(invoiceData.recipient.contact && invoiceData.recipient.special) { - pages[pageCounter - 1].drawText(invoiceData.recipient.contact, { - ...getCoordinatesForPDFLib(21,60, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(invoiceData.recipient.special, { - ...getCoordinatesForPDFLib(21,65, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - - pages[pageCounter - 1].drawText(invoiceData.recipient.street, { - ...getCoordinatesForPDFLib(21,70, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(`${invoiceData.recipient.zip} ${invoiceData.recipient.city}`, { - ...getCoordinatesForPDFLib(21,75, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } else if(!invoiceData.recipient.contact && !invoiceData.recipient.special) { - - pages[pageCounter - 1].drawText(invoiceData.recipient.street, { - ...getCoordinatesForPDFLib(21,60, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(`${invoiceData.recipient.zip} ${invoiceData.recipient.city}`, { - ...getCoordinatesForPDFLib(21,65, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } else { - pages[pageCounter - 1].drawText(invoiceData.recipient.contact, { - ...getCoordinatesForPDFLib(21,60, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(invoiceData.recipient.special, { - ...getCoordinatesForPDFLib(21,65, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - - pages[pageCounter - 1].drawText(invoiceData.recipient.street, { - ...getCoordinatesForPDFLib(21,70, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText(`${invoiceData.recipient.zip} ${invoiceData.recipient.city}`, { - ...getCoordinatesForPDFLib(21,75, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } - - - - - - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(20,90,page1), - end: getCoordinatesForPDFLib(105,90,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - - //Rechts - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(125,50,page1), - end: getCoordinatesForPDFLib(200,50,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - pages[pageCounter - 1].drawText(invoiceData.info.documentNumberTitle, { - ...getCoordinatesForPDFLib(126,55, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.documentNumber ? invoiceData.info.documentNumber : "XXXX", { - y: getCoordinatesForPDFLib(126,55, page1).y, - x: getCoordinatesForPDFLib(126,55,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.documentNumber ? invoiceData.info.documentNumber : "XXXX",10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - pages[pageCounter - 1].drawText("Kundennummer", { - ...getCoordinatesForPDFLib(126,60, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.customerNumber, { - y: getCoordinatesForPDFLib(126,60, page1).y, - x: getCoordinatesForPDFLib(126,60,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.customerNumber,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText("Belegdatum", { - ...getCoordinatesForPDFLib(126,65, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.documentDate, { - y: getCoordinatesForPDFLib(126,65, page1).y, - x: getCoordinatesForPDFLib(126,65,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.documentDate,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - if(invoiceData.info.deliveryDateType !== "Kein Lieferdatum anzeigen") { - pages[pageCounter - 1].drawText(invoiceData.info.deliveryDateType, { - ...getCoordinatesForPDFLib(126,70, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.deliveryDate, { - y: getCoordinatesForPDFLib(126,70, page1).y, - x: getCoordinatesForPDFLib(126,70,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.deliveryDate,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } - - - - pages[pageCounter - 1].drawText("Ansprechpartner", { - ...getCoordinatesForPDFLib(126,75, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.contactPerson, { - y: getCoordinatesForPDFLib(126,75, page1).y, - x: getCoordinatesForPDFLib(126,75,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.contactPerson,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - if(invoiceData.info.contactTel && invoiceData.info.contactEMail) { - pages[pageCounter - 1].drawText("Telefon", { - ...getCoordinatesForPDFLib(126,80, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.contactTel, { - y: getCoordinatesForPDFLib(126,80, page1).y, - x: getCoordinatesForPDFLib(126,80,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.contactTel,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText("E-Mail", { - ...getCoordinatesForPDFLib(126,85, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.contactEMail, { - y: getCoordinatesForPDFLib(126,85, page1).y, - x: getCoordinatesForPDFLib(126,85,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.contactEMail,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } else if(invoiceData.info.contactTel && !invoiceData.info.contactEMail) { - pages[pageCounter - 1].drawText("Telefon", { - ...getCoordinatesForPDFLib(126,80, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.contactTel, { - y: getCoordinatesForPDFLib(126,80, page1).y, - x: getCoordinatesForPDFLib(126,80,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.contactTel,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } else if(!invoiceData.info.contactTel && invoiceData.info.contactEMail) { - pages[pageCounter - 1].drawText("E-Mail", { - ...getCoordinatesForPDFLib(126,80, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.contactEMail, { - y: getCoordinatesForPDFLib(126,80, page1).y, - x: getCoordinatesForPDFLib(126,80,page1).x + 210 - font.widthOfTextAtSize(invoiceData.info.contactEMail,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - } - - - - /*pages[pageCounter - 1].drawText("Projekt:", { - ...getCoordinatesForPDFLib(126,90, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(invoiceData.info.project, { - y: getCoordinatesForPDFLib(126,90, page1).y, - x: getCoordinatesForPDFLib(126,90,page1).x + 50 /!*+ 210 - font.widthOfTextAtSize(invoiceData.info.project,10)*!/, - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 150 - })*/ - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(125,90,page1), - end: getCoordinatesForPDFLib(200,90,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - //Title - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(20,95,page1), - end: getCoordinatesForPDFLib(200,95,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - pages[pageCounter - 1].drawText(invoiceData.title, { - ...getCoordinatesForPDFLib(20,100, page1), - size:13, - color:rgb(0,0,0), - lineHeight:15, - opacity: 1, - maxWidth: 500 - }) - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(20,105,page1), - end: getCoordinatesForPDFLib(200,105,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - if(invoiceData.description) { - pages[pageCounter - 1].drawText(invoiceData.description, { - ...getCoordinatesForPDFLib(20,112, page1), - size:13, - color:rgb(0,0,0), - lineHeight:15, - opacity: 1, - maxWidth: 500 - }) - } - - - pages[pageCounter - 1].drawText(invoiceData.startText,{ - ...getCoordinatesForPDFLib(20,119, page1), - size: 10, - color: rgb(0,0,0), - lineHeight: 10, - opacity: 1, - maxWidth: 500 - }) - - /*page1.drawLine({ - start: getCoordinatesForPDFLib(20,115,page1), - end: getCoordinatesForPDFLib(200,115,page1), - thickness: 0.5, - color: rgb(0,0,0), - opacity: 1 - })*/ - - pages[pageCounter - 1].drawRectangle({ - ...getCoordinatesForPDFLib(20,140, page1), - width: 180 * 2.83, - height: 8 * 2.83, - color: rgb(0,0,0), - opacity: 0.25 - }) - - //Header - - pages[pageCounter - 1].drawText("Pos", { - ...getCoordinatesForPDFLib(21,137, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - pages[pageCounter - 1].drawText("Menge", { - ...getCoordinatesForPDFLib(35,137, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - pages[pageCounter - 1].drawText("Bezeichnung", { - ...getCoordinatesForPDFLib(52,137, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - if( invoiceData.type !== "deliveryNotes") { - pages[pageCounter - 1].drawText("Einheitspreis", { - ...getCoordinatesForPDFLib(135,137, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - pages[pageCounter - 1].drawText("Gesamt", { - y: getCoordinatesForPDFLib(25,137, page1).y, - x: getCoordinatesForPDFLib(25,137,page1).x + 490 - fontBold.widthOfTextAtSize("Gesamt",12), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - } - - - - - - let rowHeight = 145.5 - - let pageIndex = 0 - - - invoiceData.rows.forEach((row,index) => { - - - - if(!["pagebreak","title","text"].includes(row.mode)){ - - console.log(row) - - pages[pageCounter - 1].drawText(String(row.pos), { - ...getCoordinatesForPDFLib(21,rowHeight, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(`${row.quantity} ${row.unit}`, { - ...getCoordinatesForPDFLib(35,rowHeight, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - console.log(row.text.match(/.{1,35}/g)) - - if(invoiceData.type !== "deliveryNotes") { - pages[pageCounter - 1].drawText(row.text.match(/.{1,35}/g).join("\n"), { - ...getCoordinatesForPDFLib(52,rowHeight, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - font: fontBold - }) - } else { - pages[pageCounter - 1].drawText(row.text.match(/.{1,80}/g).join("\n"), { - ...getCoordinatesForPDFLib(52,rowHeight, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - font: fontBold - }) - } - - - - //let textLineBreaks = (row.text.match(/\n/g) || []).length - let textAutoLines = (invoiceData.type !== "deliveryNotes" ? row.text.match(/.{1,35}/g) : row.text.match(/.{1,80}/g) || []).length - console.log(textAutoLines) - - console.log(row) - - - if(row.descriptionText) { - if(invoiceData.type !== "deliveryNotes") { - pages[pageCounter - 1].drawText(row.descriptionText.match(/.{1,70}/g).join("\n"), { - ...getCoordinatesForPDFLib(52,rowHeight + ( textAutoLines * 4), page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - }) - } else { - pages[pageCounter - 1].drawText(row.descriptionText.match(/.{1,80}/g).join("\n"), { - ...getCoordinatesForPDFLib(52,rowHeight + ( textAutoLines * 4), page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - }) - } - - - } - - - if(invoiceData.type !== "deliveryNotes") { - pages[pageCounter - 1].drawText(row.price, { - ...getCoordinatesForPDFLib(135,rowHeight, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240 - }) - - pages[pageCounter - 1].drawText(row.rowAmount, { - y: getCoordinatesForPDFLib(25,rowHeight, page1).y, - x: getCoordinatesForPDFLib(25,rowHeight,page1).x + 490 - font.widthOfTextAtSize(row.rowAmount,10), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240, - }) - - if(row.discountPercent > 0) { - pages[pageCounter - 1].drawText(row.discountText, { - y: getCoordinatesForPDFLib(25,rowHeight + 5, page1).y, - x: getCoordinatesForPDFLib(25,rowHeight + 5,page1).x + 490 - font.widthOfTextAtSize(row.discountText,8), - size:8, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240, - }) - } - } - - - - - - if(row.descriptionText) { - let lineBreaks = (row.descriptionText.match(/\n/g) || []).length - let autoLines = (row.descriptionText.match(/.{1,70}/g) || []).length - rowHeight += 12 + (lineBreaks + autoLines + textAutoLines) * 2.5 - } else { - rowHeight += 12 + textAutoLines * 2.5 - } - - - pageIndex += 1 - - - } else if(row.mode === 'pagebreak') { - - const page = pdfDoc.addPage() - - page.drawPage(secondPageBackground, { - x: 0, - y: 0, - }) - - //Falzmarke 1 - page.drawLine({ - start: getCoordinatesForPDFLib(0,105,page1), - end: getCoordinatesForPDFLib(7,105,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - }) - - //Lochmarke - page.drawLine({ - start: getCoordinatesForPDFLib(0,148.5,page1), - end: getCoordinatesForPDFLib(7,148.5,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - }) - - //Falzmarke 2 - page.drawLine({ - start: getCoordinatesForPDFLib(0,210,page1), - end: getCoordinatesForPDFLib(7,210,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - }) - - page.drawRectangle({ - ...getCoordinatesForPDFLib(20,25, page1), - width: 180 * 2.83, - height: 8 * 2.83, - color: rgb(0,0,0), - opacity: 0.25 - }) - - //Header - - page.drawText("Pos", { - ...getCoordinatesForPDFLib(21,22, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - page.drawText("Menge", { - ...getCoordinatesForPDFLib(35,22, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - page.drawText("Bezeichnung", { - ...getCoordinatesForPDFLib(52,22, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - if(invoiceData.type !== "deliveryNotes"){ - page.drawText("Einheitspreis", { - ...getCoordinatesForPDFLib(135,22, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - page.drawText("Gesamt", { - y: getCoordinatesForPDFLib(25,22, page1).y, - x: getCoordinatesForPDFLib(25,22,page1).x + 490 - fontBold.widthOfTextAtSize("Gesamt",12), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - } - - - - pageCounter += 1; - pageIndex = 0; - rowHeight = 30; - - pages.push(page) - //console.log(pages) - - - - - } else if (row.mode === 'title') { - if(index === 0 ||pageIndex === 0) { - rowHeight += 3 - } - - pages[pageCounter - 1].drawText(String(row.pos), { - ...getCoordinatesForPDFLib(21,rowHeight -3, page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - - pages[pageCounter - 1].drawRectangle({ - ...getCoordinatesForPDFLib(20,rowHeight, page1), - width: 180 * 2.83, - height: 8 * 2.83, - color: rgb(0,0,0), - opacity: 0.25 - }) - - pages[pageCounter - 1].drawText(row.text, { - ...getCoordinatesForPDFLib(35,rowHeight -3, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - maxWidth: 500, - font: fontBold - }) - - rowHeight += 8 - } else if (row.mode === 'text') { - if(index === 0 ||pageIndex === 0) { - rowHeight += 3 - } - - let textAutoLines = (row.text.match(/.{1,60}/g) || []).length - - pages[pageCounter - 1].drawRectangle({ - ...getCoordinatesForPDFLib(20,rowHeight, page1), - width: 180 * 2.83, - height: 8 * 2.83, - color: rgb(0,0,0), - opacity: 0.25 - }) - - pages[pageCounter - 1].drawText(row.text.match(/.{1,60}/g).join("\n"), { - ...getCoordinatesForPDFLib(21,rowHeight - 2.6, page1), - size:12, - color:rgb(0,0,0), - lineHeight:12, - opacity: 1, - font: fontBold - }) - - //let textLineBreaks = (row.text.match(/\n/g) || []).length - //console.log(textAutoLines) - - - if(row.descriptionText) { - pages[pageCounter - 1].drawText(row.descriptionText.match(/.{1,100}/g).join("\n"), { - ...getCoordinatesForPDFLib(21,rowHeight + ( textAutoLines * 4), page1), - size:10, - color:rgb(0,0,0), - lineHeight:10, - opacity: 1, - }) - - let addHeight = (row.descriptionText.match(/.{1,80}/g) || []).length * 4 + 10 - console.log(addHeight) - rowHeight += addHeight - } else { - rowHeight += 6 - } - - - - } - - - }) - - - //Pos 1 - - - - - - //Footer - //console.log(rowHeight) - //rowHeight += 25 - - if(invoiceData.type !== "deliveryNotes"){ - pages[pageCounter - 1].drawRectangle({ - ...getCoordinatesForPDFLib(20,rowHeight, page1), - width: 180 * 2.83, - height: 8 * 2.83, - color: rgb(0,0,0), - opacity: 0.25 - }) - - pages[pageCounter - 1].drawRectangle({ - ...getCoordinatesForPDFLib(20,rowHeight +16, page1), - width: 180 * 2.83, - height: 8 * 2.83, - color: rgb(0,0,0), - opacity: 0.25 - }) - - pages[pageCounter - 1].drawText("Nettobetrag", { - ...getCoordinatesForPDFLib(21,rowHeight-3, page1), - size:11, - color:rgb(0,0,0), - lineHeight:11, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - pages[pageCounter - 1].drawText(invoiceData.total.totalNet, { - y: getCoordinatesForPDFLib(21,rowHeight-3, page1).y, - x: getCoordinatesForPDFLib(21,rowHeight-3,page1).x + 500 - fontBold.widthOfTextAtSize(invoiceData.total.totalNet,11), - size:11, - color:rgb(0,0,0), - lineHeight:11, - opacity: 1, - maxWidth: 240, - font:fontBold - }) - - pages[pageCounter - 1].drawText("zzgl. 19% MwSt", { - ...getCoordinatesForPDFLib(21,rowHeight+5, page1), - size:11, - color:rgb(0,0,0), - lineHeight:11, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - pages[pageCounter - 1].drawText(invoiceData.total.total19, { - y: getCoordinatesForPDFLib(21,rowHeight+5, page1).y, - x: getCoordinatesForPDFLib(21,rowHeight+5,page1).x + 500 - fontBold.widthOfTextAtSize(invoiceData.total.total19,11), - size:11, - color:rgb(0,0,0), - lineHeight:11, - opacity: 1, - maxWidth: 240, - font:fontBold - }) - - pages[pageCounter - 1].drawText("Gesamtsumme", { - ...getCoordinatesForPDFLib(21,rowHeight+13, page1), - size:11, - color:rgb(0,0,0), - lineHeight:11, - opacity: 1, - maxWidth: 240, - font: fontBold - }) - - pages[pageCounter - 1].drawText(invoiceData.total.totalGross, { - y: getCoordinatesForPDFLib(21,rowHeight+13, page1).y, - x: getCoordinatesForPDFLib(21,rowHeight+13,page1).x + 500 - fontBold.widthOfTextAtSize(invoiceData.total.totalGross,11), - size:11, - color:rgb(0,0,0), - lineHeight:11, - opacity: 1, - maxWidth: 240, - font:fontBold - }) - } - - - pages[pageCounter - 1].drawText(invoiceData.endText,{ - ...getCoordinatesForPDFLib(20,rowHeight+22, page1), - size: 10, - color: rgb(0,0,0), - lineHeight: 10, - opacity: 1, - maxWidth: 500 - }) - - //console.log(await pdfDoc.saveAsBase64({dataUri: true})) - - uri.value = await pdfDoc.saveAsBase64({dataUri: true}) - //console.log(uri.value) - - } - - await genPDF() - - //const pdfBytes = await pdfDoc.save() - - //const pdfDataUri = await pdfDoc.saveAsBase64({dataUri: true}) - return uri.value - //let blob = new Blob(pdfBytes, {type: "application/pdf"}) - /*let link = document.createElement('a') - link.href = pdfDataUri//window.URL.createObjectURL(blob) - link.download = "test.pdf" - link.click()*/ - -} \ No newline at end of file diff --git a/composables/useWorkingTimePDFGenerator.js b/composables/useWorkingTimePDFGenerator.js deleted file mode 100644 index a3d2404..0000000 --- a/composables/useWorkingTimePDFGenerator.js +++ /dev/null @@ -1,232 +0,0 @@ -import {PDFDocument, StandardFonts, rgb} from "pdf-lib" -import dayjs from "dayjs" - - -const getCoordinatesForPDFLib = (x ,y, page) => { - /* - * @param x the wanted X Parameter in Millimeters from Top Left - * @param y the wanted Y Parameter in Millimeters from Top Left - * @param page the page Object - * - * @returns x,y object - * */ - - - let retX = x * 2.83 - let retY = page.getHeight()-(y*2.83) - - return { - x: retX, - y: retY - } - -} - -const getDuration = (time) => { - const minutes = Math.floor(dayjs(time.endDate).diff(dayjs(time.startDate),'minutes',true)) - const hours = Math.floor(minutes/60) - return { - //dezimal: dez, - hours: hours, - minutes: minutes, - composed: `${hours}:${String(minutes % 60).padStart(2,"0")} Std` - } -} - - - - -export const useCreateWorkingTimesPdf = async (input,backgroundSourceBuffer) => { - - const uri = ref("test") - const genPDF = async () => { - const pdfDoc = await PDFDocument.create() - - const font = await pdfDoc.embedFont(StandardFonts.Helvetica) - const fontBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold) - - let pages = [] - let pageCounter = 1 - - - - const backgroudPdf = await PDFDocument.load(backgroundSourceBuffer) - - const firstPageBackground = await pdfDoc.embedPage(backgroudPdf.getPages()[0]) - const secondPageBackground = await pdfDoc.embedPage(backgroudPdf.getPages()[backgroudPdf.getPages().length > 1 ? 1 : 0]) - - const page1 = pdfDoc.addPage() - - page1.drawPage(firstPageBackground, { - x: 0, - y: 0, - }) - - pages.push(page1) - - - //Falzmarke 1 - /*pages[pageCounter - 1].drawLine({ - start: getCoordinatesForPDFLib(0,105,page1), - end: getCoordinatesForPDFLib(7,105,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - })*/ - - //Lochmarke - /*pages[pageCounter - 1].drawLine({ - start: getCoordinatesForPDFLib(0,148.5,page1), - end: getCoordinatesForPDFLib(7,148.5,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - })*/ - - //Falzmarke 2 - /*pages[pageCounter - 1].drawLine({ - start: getCoordinatesForPDFLib(0,210,page1), - end: getCoordinatesForPDFLib(7,210,page1), - thickness: 0.25, - color: rgb(0,0,0), - opacity: 1 - })*/ - console.log(input) - pages[pageCounter - 1].drawText(`Mitarbeiter: ${input.profile}`,{ - x: getCoordinatesForPDFLib(20,65,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,65,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Eingereicht: ${Math.floor(input.sumWorkingMinutesEingereicht/60)}:${String(input.sumWorkingMinutesEingereicht % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,70,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,70,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Genehmigt: ${Math.floor(input.sumWorkingMinutesApproved/60)}:${String(input.sumWorkingMinutesApproved % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,75,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,75,pages[pageCounter -1]).y, - size: 10, - }) - - pages[pageCounter - 1].drawText(`Feiertagsausgleich: ${Math.floor(input.sumWorkingMinutesRecreationDays/60)}:${String(input.sumWorkingMinutesRecreationDays % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,80,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,80,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Urlaubsausgleich: ${Math.floor(input.sumWorkingMinutesVacationDays/60)}:${String(input.sumWorkingMinutesVacationDays % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,85,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,85,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Krankheitsausgleich: ${Math.floor(input.sumWorkingMinutesSickDays/60)}:${String(input.sumWorkingMinutesSickDays % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,90,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,90,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Soll Stunden: ${Math.floor(input.timeSpanWorkingMinutes/60)}:${String(input.timeSpanWorkingMinutes % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,95,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,95,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Inoffizielles Saldo: ${Math.sign(input.saldoInOfficial) === 1 ? "+" : "-"} ${Math.floor(Math.abs(input.saldoInOfficial/60))}:${String(Math.abs(input.saldoInOfficial) % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,100,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,100,pages[pageCounter -1]).y, - size: 10, - }) - pages[pageCounter - 1].drawText(`Saldo: ${Math.sign(input.saldo) === 1 ? "+" : "-"} ${Math.floor(Math.abs(input.saldo/60))}:${String(Math.abs(input.saldo) % 60).padStart(2,"0")} Std`,{ - x: getCoordinatesForPDFLib(20,105,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,105,pages[pageCounter -1]).y, - size: 10, - }) - - pages[pageCounter - 1].drawText(`Start:`,{ - x: getCoordinatesForPDFLib(20,110,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,110,pages[pageCounter -1]).y, - size: 10, - }) - - pages[pageCounter - 1].drawText(`Ende:`,{ - x: getCoordinatesForPDFLib(60,110,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(60,110,pages[pageCounter -1]).y, - size: 10, - }) - - pages[pageCounter - 1].drawText(`Dauer:`,{ - x: getCoordinatesForPDFLib(100,110,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(100,110,pages[pageCounter -1]).y, - size: 10, - }) - - - let rowHeight = 115 - - - let splitted = [] - - let reversedInput = input.times.slice().reverse() - - const splittedLength = Math.floor((reversedInput.length - 25) / 40) - - splitted.push(reversedInput.slice(0,25)) - - let lastIndex = 25 - for (let i = 0; i < splittedLength; ++i ) { - splitted.push(reversedInput.slice(lastIndex, lastIndex + (i + 1) * 40)) - lastIndex = lastIndex + (i + 1) * 40 + 1 - } - - splitted.push(reversedInput.slice(lastIndex, reversedInput.length)) - - - splitted.forEach((chunk,index) => { - if(index > 0) { - const page = pdfDoc.addPage() - - page.drawPage(secondPageBackground, { - x: 0, - y: 0, - }) - - pages.push(page) - pageCounter++ - rowHeight = 20 - - } - - chunk.forEach(time => { - pages[pageCounter - 1].drawText(`${dayjs(time.startDate).format("HH:mm DD.MM.YY")}`,{ - x: getCoordinatesForPDFLib(20,rowHeight,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(20,rowHeight,pages[pageCounter -1]).y, - size: 10, - }) - - pages[pageCounter - 1].drawText(`${dayjs(time.endDate).format("HH:mm DD.MM.YY")}`,{ - x: getCoordinatesForPDFLib(60,rowHeight,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(60,rowHeight,pages[pageCounter -1]).y, - size: 10, - }) - - pages[pageCounter - 1].drawText(`${getDuration(time).composed}`,{ - x: getCoordinatesForPDFLib(100,rowHeight,pages[pageCounter -1]).x, - y: getCoordinatesForPDFLib(100,rowHeight,pages[pageCounter -1]).y, - size: 10, - }) - - rowHeight += 6 - - }) - }) - - - - - uri.value = await pdfDoc.saveAsBase64({dataUri: true}) - - } - - await genPDF() - - return uri.value - - -} \ No newline at end of file diff --git a/composables/useZipCheck.js b/composables/useZipCheck.js deleted file mode 100644 index 7251659..0000000 --- a/composables/useZipCheck.js +++ /dev/null @@ -1,8 +0,0 @@ - -export const useZipCheck = async (zip) => { - const supabase = useSupabaseClient() - - const result = (await supabase.from("citys").select().eq("zip",Number(zip)).maybeSingle()).data - - return result ? result.short : null -} \ No newline at end of file diff --git a/pages/export.vue b/pages/export/index.vue similarity index 96% rename from pages/export.vue rename to pages/export/index.vue index cb1e725..b1c99e8 100644 --- a/pages/export.vue +++ b/pages/export/index.vue @@ -4,6 +4,7 @@ const exports = ref([]) const auth = useAuthStore() const toast = useToast() +const router = useRouter() const setupPage = async () => { exports.value = await useNuxtApp().$api("/api/exports",{ @@ -56,7 +57,10 @@ const createExport = async () => { +const { $dayjs } = useNuxtApp() +const router = useRouter() +const route = useRoute() +const auth = useAuthStore() + +// 🔹 State +const workingtimes = ref([]) +const absencerequests = ref([]) +const workingTimeInfo = ref(null) + +const selectedPresetRange = ref("Dieser Monat bis heute") +const selectedStartDay = ref("") +const selectedEndDay = ref("") +const openTab = ref(0) + +const showDocument = ref(false) +const uri = ref("") +const itemInfo = ref({}) + +function formatMinutesToHHMM(minutes = 0) { + const h = Math.floor(minutes / 60) + const m = Math.floor(minutes % 60) + return `${h}:${String(m).padStart(2, "0")} h` +} + +// 📅 Zeitraumumschaltung +function changeRange() { + const rangeMap = { + "Diese Woche": { selector: "isoWeek", subtract: 0 }, + "Dieser Monat": { selector: "M", subtract: 0 }, + "Dieser Monat bis heute": { selector: "M", subtract: 0 }, + "Dieses Jahr": { selector: "y", subtract: 0 }, + "Letzte Woche": { selector: "isoWeek", subtract: 1 }, + "Letzter Monat": { selector: "M", subtract: 1 }, + "Letztes Jahr": { selector: "y", subtract: 1 } + } + + const { selector, subtract } = rangeMap[selectedPresetRange.value] || { selector: "M", subtract: 0 } + + selectedStartDay.value = $dayjs() + .subtract(subtract, selector === "isoWeek" ? "week" : selector) + .startOf(selector) + .format("YYYY-MM-DD") + + selectedEndDay.value = + selectedPresetRange.value === "Dieser Monat bis heute" + ? $dayjs().format("YYYY-MM-DD") + : $dayjs() + .subtract(subtract, selector === "isoWeek" ? "week" : selector) + .endOf(selector) + .format("YYYY-MM-DD") + + loadWorkingTimeInfo() +} + +const profile = ref(null) + +// 📊 Daten laden +async function setupPage() { + await changeRange() + + profile.value = (await useNuxtApp().$api("/api/tenant/profiles")).data.find(i => i.user_id === route.params.id) + + console.log(profile.value) + +} + +async function loadWorkingTimeInfo() { + workingTimeInfo.value = await useFunctions().getWorkingTimesEvaluationData( + route.params.id, + selectedStartDay.value, + selectedEndDay.value + ) + openTab.value = 0 +} + +// 📄 PDF generieren +async function generateDocument() { + const path = (await useEntities("letterheads").select("*"))[0].path // TODO SELECT + + uri.value = await useFunctions().useCreatePDF({ + full_name: profile.value.full_name, + ...workingTimeInfo.value}, path, "timesheet") + + + showDocument.value = true +} + +async function onTabChange(index: number) { + if (index === 1) await generateDocument() +} + +// Initialisierung +await setupPage() +changeRange() + + + diff --git a/pages/staff/time/index.vue b/pages/staff/time/index.vue new file mode 100644 index 0000000..2ac58f1 --- /dev/null +++ b/pages/staff/time/index.vue @@ -0,0 +1,173 @@ + + + diff --git a/pages/workingtimes/[mode]/[[id]].vue b/pages/workingtimes/[mode]/[[id]].vue deleted file mode 100644 index 6e4946e..0000000 --- a/pages/workingtimes/[mode]/[[id]].vue +++ /dev/null @@ -1,150 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/workingtimes/evaluate/[id].vue b/pages/workingtimes/evaluate/[id].vue deleted file mode 100644 index d246c1d..0000000 --- a/pages/workingtimes/evaluate/[id].vue +++ /dev/null @@ -1,291 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/workingtimes/index.vue b/pages/workingtimes/index.vue deleted file mode 100644 index a7b64b3..0000000 --- a/pages/workingtimes/index.vue +++ /dev/null @@ -1,327 +0,0 @@ - - - - - \ No newline at end of file