Functions Time Eval and PDF

This commit is contained in:
2025-11-08 18:59:47 +01:00
parent 6d0b764ee2
commit 29bebe6149
3 changed files with 444 additions and 186 deletions

View File

@@ -0,0 +1,128 @@
import {FastifyInstance} from "fastify";
export async function generateTimesEvaluation(
server: FastifyInstance,
user_id: string,
tenant_id: number,
startDateInput: string,
endDateInput: string
) {
const startDate = server.dayjs(startDateInput)
const endDate = server.dayjs(endDateInput)
// 🧾 Profil laden (Arbeitszeiten + Bundesland)
const { data: profile, error: profileError } = await server.supabase
.from("auth_profiles")
.select("*")
.eq("user_id", user_id)
.eq("tenant_id", tenant_id)
.maybeSingle()
if (profileError || !profile) throw new Error("Profil konnte nicht geladen werden.")
// 🕒 Arbeitszeiten abrufen
const { data: times, error: timeError } = await server.supabase
.from("staff_time_entries")
.select("*")
.eq("tenant_id", tenant_id)
.eq("user_id", user_id)
.gte("started_at", startDate.toISOString())
.lte("started_at", endDate.toISOString())
.order("started_at", { ascending: true })
if (timeError) throw new Error("Fehler beim Laden der Arbeitszeiten: " + timeError.message)
// 📅 Feiertage aus Tabelle für Bundesland + DE
const { data: holidays, error: holidaysError } = await server.supabase
.from("holidays")
.select("date")
.in("state_code", [profile.state_code, "DE"])
.gte("date", startDate.format("YYYY-MM-DD"))
.lte("date", endDate.format("YYYY-MM-DD"))
if (holidaysError) throw new Error("Fehler beim Laden der Feiertage: " + holidaysError.message)
// 🗓️ Sollzeit berechnen
let timeSpanWorkingMinutes = 0
const totalDays = endDate.add(1, "day").diff(startDate, "days")
for (let i = 0; i < totalDays; i++) {
const date = startDate.add(i, "days")
const weekday = date.day()
timeSpanWorkingMinutes += (profile.weekly_regular_working_hours?.[weekday] || 0) * 60
}
// 🧮 Eingereicht & genehmigt
const calcMinutes = (start: string, end: string | null) =>
server.dayjs(end || new Date()).diff(server.dayjs(start), "minutes")
let sumWorkingMinutesEingereicht = 0
let sumWorkingMinutesApproved = 0
for (const t of times) {
const minutes = calcMinutes(t.started_at, t.stopped_at)
if(["submitted","approved"].includes(t.state))sumWorkingMinutesEingereicht += minutes
if (t.state === "approved") sumWorkingMinutesApproved += minutes
}
// 🎉 Feiertagsausgleich
let sumWorkingMinutesRecreationDays = 0
let sumRecreationDays = 0
if (profile.recreationDaysCompensation && holidays?.length) {
holidays.forEach(({ date }) => {
const weekday = server.dayjs(date).day()
const hours = profile.weekly_regular_working_hours?.[weekday] || 0
sumWorkingMinutesRecreationDays += hours * 60
sumRecreationDays++
})
}
// 🏖️ Urlaub & Krankheit (über Typ)
const sumWorkingMinutesVacationDays = times
.filter((t) => t.type === "vacation")
.reduce((sum, t) => sum + calcMinutes(t.started_at, t.stopped_at), 0)
const sumWorkingMinutesSickDays = times
.filter((t) => t.type === "sick")
.reduce((sum, t) => sum + calcMinutes(t.started_at, t.stopped_at), 0)
const sumVacationDays = times.filter((t) => t.type === "vacation").length
const sumSickDays = times.filter((t) => t.type === "sick").length
// 💰 Salden
const saldo =
sumWorkingMinutesApproved +
sumWorkingMinutesRecreationDays +
sumWorkingMinutesVacationDays +
sumWorkingMinutesSickDays -
timeSpanWorkingMinutes
const saldoInOfficial =
sumWorkingMinutesEingereicht +
sumWorkingMinutesRecreationDays +
sumWorkingMinutesVacationDays +
sumWorkingMinutesSickDays -
timeSpanWorkingMinutes
// 📦 Rückgabe (kompatibel zur alten Struktur)
return {
user_id,
tenant_id,
from: startDate.format("YYYY-MM-DD"),
to: endDate.format("YYYY-MM-DD"),
timeSpanWorkingMinutes,
sumWorkingMinutesEingereicht,
sumWorkingMinutesApproved,
sumWorkingMinutesRecreationDays,
sumRecreationDays,
sumWorkingMinutesVacationDays,
sumVacationDays,
sumWorkingMinutesSickDays,
sumSickDays,
saldo,
saldoInOfficial,
times
}
}

View File

@@ -1,5 +1,5 @@
import { FastifyInstance } from "fastify";
import {createInvoicePDF} from "../utils/pdf";
import {createInvoicePDF, createTimeSheetPDF} from "../utils/pdf";
import {useNextNumberRangeNumber} from "../utils/functions";
import dayjs from "dayjs";
@@ -10,6 +10,7 @@ import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js"
import isSameOrBefore from "dayjs/plugin/isSameOrBefore.js"
import duration from "dayjs/plugin/duration.js";
import timezone from "dayjs/plugin/timezone.js";
import {generateTimesEvaluation} from "../modules/time/evaluation.service";
dayjs.extend(customParseFormat)
dayjs.extend(isoWeek)
dayjs.extend(isBetween)
@@ -19,19 +20,35 @@ dayjs.extend(duration)
dayjs.extend(timezone)
export default async function functionRoutes(server: FastifyInstance) {
server.post("/functions/createinvoicepdf", async (req, reply) => {
server.post("/functions/pdf/:type", async (req, reply) => {
const body = req.body as {
invoiceData: any
data: any
backgroundPath?: string
}
const {type} = req.params as {type:string}
try {
const pdf = await createInvoicePDF(
let pdf = null
if(type === "createdDocument") {
pdf = await createInvoicePDF(
server,
"base64",
body.invoiceData,
body.data,
body.backgroundPath
)
} else if(type === "timesheet") {
pdf = await createTimeSheetPDF(
server,
"base64",
body.data,
body.backgroundPath
)
}
console.log(pdf)
reply.send(pdf) // Fastify wandelt automatisch in JSON
} catch (err) {
@@ -53,186 +70,83 @@ export default async function functionRoutes(server: FastifyInstance) {
}
})
server.get("/functions/workingtimeevaluation/:profile_id", async (req, reply) => {
/**
* @route GET /functions/workingtimeevaluation/:user_id
* @query start_date=YYYY-MM-DD
* @query end_date=YYYY-MM-DD
*/
server.get("/functions/timeevaluation/:user_id", async (req, reply) => {
const { user_id } = req.params as { user_id: string }
const { start_date, end_date } = req.query as { start_date: string; end_date: string }
const { tenant_id } = req.user
const { profile_id } = req.params as { profile_id: string };
const { start_date, end_date } = req.query as { start_date: string, end_date: string };
async function generateWorkingTimesEvaluationValues(profile_id,startDateInput,endDateInput) {
console.log(dayjs(startDateInput))
console.log(dayjs(endDateInput))
let startDate = dayjs(startDateInput)
let endDate = dayjs(endDateInput)
//console.log(startDate)
//console.log(endDate)
const {data:profile} = await server.supabase.from("auth_profiles").select().eq("old_profile_id",profile_id).single()
console.log(profile)
let {data:times,error:timesError} = await server.supabase.from("workingtimes").select().eq("profile", profile.old_profile_id).order("startDate",{ascending: false})
const {data:absencerequests, error: timesAbsenceRequestsError} = await server.supabase.from("absencerequests").select().eq("profile",profile.old_profile_id).order("startDate",{ascending: false})
times = times.filter(i => dayjs(i.startDate).isSameOrAfter(startDate) && dayjs(i.endDate).subtract(1,"day").isSameOrBefore(endDate))
console.log(times)
let weekFactor = 4.33
//let monthlyWorkingMinutes = profile.weeklyWorkingHours * weekFactor * 60
//Get Every Day to Calc
let days = []
let minuteSum = 0
let dayCount = dayjs(endDate).add(1,"day").diff(startDate,"days")
for (let count = 0; count < dayCount; count++) {
let date = dayjs(startDate).add(count,"days")
minuteSum += (profile.weekly_regular_working_hours[date.day()] || 0)*60
// 🔒 Sicherheitscheck: andere User nur bei Berechtigung
if (user_id !== req.user.user_id && !req.hasPermission("staff.time.read_all")) {
return reply.code(403).send({ error: "Not allowed to view other users." })
}
let timeSpanWorkingMinutes = minuteSum
let workingMinutesTarget = Math.ceil(Number((Number(dayjs(endDate).add(1,"days").diff(dayjs(startDate),'month',true).toFixed(2)) * 4.33 * profile.weeklyWorkingHours * 60).toFixed(2)))
//Eingreicht
let sumWorkingMinutesEingereicht = 0
times.forEach(time => {
const minutes = dayjs(time.endDate).diff(dayjs(time.startDate),'minutes')
sumWorkingMinutesEingereicht = sumWorkingMinutesEingereicht + minutes
})
//Bestätigt
let sumWorkingMinutesApproved = 0
times.filter(i => i.approved).forEach(time => {
const minutes = dayjs(time.endDate).diff(dayjs(time.startDate),'minutes')
sumWorkingMinutesApproved = sumWorkingMinutesApproved + minutes
})
let recreationDays = ["2025-01-01","2025-04-18","2025-04-21","2025-05-01","2025-05-29","2025-06-09","2024-10-03","2024-10-31","2024-12-25","2024-12-26"]
//Feiertagsausgleich
let sumWorkingMinutesRecreationDays = 0
let sumRecreationDays = 0
if(profile.recreationDaysCompensation) {
recreationDays.filter(i => dayjs(i).isSameOrAfter(startDate) && dayjs(i).isSameOrBefore(endDate)).forEach(day => {
let compensationTime = profile.weekly_regular_working_hours[dayjs(day).day()] || 0
sumWorkingMinutesRecreationDays += compensationTime * 60
sumRecreationDays++
})
}
let isBetween = (date,start,end) => {
return dayjs(date).isSameOrAfter(start) && dayjs(date).isSameOrBefore(end)
}
//Urlaubsausgleich
let sumWorkingMinutesVacationDays = 0
let sumVacationDays = 0
absencerequests.filter(i => (dayjs(i.startDate).isBetween(dayjs(startDate),dayjs(endDate),"day","[]") || dayjs(i.endDate).isBetween(dayjs(startDate),dayjs(endDate),"day","[]")) && (i.reason === "Urlaub" || i.reason === "Berufsschule") && i.approved === "Genehmigt").forEach(absenceRequest => {
let durationInDays = 0
let durationStartDate = null
if(isBetween(absenceRequest.startDate,startDate,endDate) && isBetween(absenceRequest.endDate,startDate,endDate)) {
//Full in Range
durationInDays = dayjs(absenceRequest.endDate).diff(absenceRequest.startDate, "days") + 1
durationStartDate = absenceRequest.startDate
} else if(isBetween(absenceRequest.startDate,startDate,endDate) && !isBetween(absenceRequest.endDate,startDate,endDate)) {
//Start in Range
durationInDays = dayjs(endDate).diff(absenceRequest.startDate, "days") + 1
durationStartDate = absenceRequest.startDate
} else if(!isBetween(absenceRequest.startDate,startDate,endDate) && isBetween(absenceRequest.endDate,startDate,endDate)) {
//End in Range
durationInDays = dayjs(absenceRequest.endDate).diff(startDate, "days") + 1
durationStartDate = startDate
}
let minuteSum = 0
for (let count = 0; count < durationInDays; count++) {
let date = dayjs(durationStartDate).add(count,"days")
minuteSum += (profile.weekly_regular_working_hours[date.day()] || 0)*60
}
sumVacationDays += durationInDays
sumWorkingMinutesVacationDays += minuteSum
})
//Krankheitsausgleich
let sumWorkingMinutesSickDays = 0
let sumSickDays = 0
absencerequests.filter(i => (dayjs(i.startDate).isBetween(dayjs(startDate),dayjs(endDate)) || dayjs(i.endDate).isBetween(dayjs(startDate),dayjs(endDate)) ) && (i.reason === "Krankheit" || i.reason === "Krankheit ab 1 Tag (mit Attest)" || i.reason === "Krankheit ab 2. Tag (mit Attest)") && i.approved === "Genehmigt").forEach(absenceRequest => {
let durationInDays = 0
let durationStartDate = null
if(isBetween(absenceRequest.startDate,startDate,endDate) && isBetween(absenceRequest.endDate,startDate,endDate)) {
//Full in Range
console.log("FULL")
durationInDays = dayjs(absenceRequest.endDate).diff(absenceRequest.startDate, "days") + 1
durationStartDate = absenceRequest.startDate
} else if(isBetween(absenceRequest.startDate,startDate,endDate) && !isBetween(absenceRequest.endDate,startDate,endDate)) {
//Start in Range
console.log("Start")
durationInDays = dayjs(endDate).diff(absenceRequest.startDate, "days") + 1
durationStartDate = absenceRequest.startDate
} else if(!isBetween(absenceRequest.startDate,startDate,endDate) && isBetween(absenceRequest.endDate,startDate,endDate)) {
//End in Range
console.log("End")
durationInDays = dayjs(absenceRequest.endDate).diff(startDate, "days") + 1
durationStartDate = startDate
}
let minuteSum = 0
for (let count = 0; count < durationInDays; count++) {
let date = dayjs(durationStartDate).add(count,"days")
minuteSum += (profile.weekly_regular_working_hours[date.day()] || 0)*60
}
sumSickDays += durationInDays
sumWorkingMinutesSickDays += minuteSum
})
//Saldo
let saldo = (sumWorkingMinutesApproved + sumWorkingMinutesRecreationDays + sumWorkingMinutesVacationDays + sumWorkingMinutesSickDays - timeSpanWorkingMinutes).toFixed(2)
let saldoInOfficial = (sumWorkingMinutesEingereicht + sumWorkingMinutesRecreationDays + sumWorkingMinutesVacationDays + sumWorkingMinutesSickDays - timeSpanWorkingMinutes).toFixed(2)
return {
timeSpanWorkingMinutes,
workingMinutesTarget,
sumWorkingMinutesEingereicht,
sumWorkingMinutesApproved,
sumWorkingMinutesRecreationDays,
sumRecreationDays,
sumWorkingMinutesVacationDays,
sumVacationDays,
sumWorkingMinutesSickDays,
sumSickDays,
saldo,
saldoInOfficial,
times
}
}
try {
reply.send(await generateWorkingTimesEvaluationValues(profile_id,start_date,end_date))
} catch(error) {
console.log(error)
const result = await generateTimesEvaluation(server, user_id, tenant_id, start_date, end_date)
reply.send(result)
} catch (error) {
console.error(error)
reply.code(500).send({ error: error.message })
}
})
server.get('/functions/check-zip/:zip', async (req, reply) => {
const { zip } = req.params as { zip: string }
if (!zip) {
return reply.code(400).send({ error: 'ZIP is required' })
}
try {
const { data, error } = await server.supabase
.from('citys')
.select()
.eq('zip', zip)
.maybeSingle()
if (error) {
console.log(error)
return reply.code(500).send({ error: 'Database error' })
}
if (!data) {
return reply.code(404).send({ error: 'ZIP not found' })
}
//districtMap
const bundeslaender = [
{ code: 'DE-BW', name: 'Baden-Württemberg' },
{ code: 'DE-BY', name: 'Bayern' },
{ code: 'DE-BE', name: 'Berlin' },
{ code: 'DE-BB', name: 'Brandenburg' },
{ code: 'DE-HB', name: 'Bremen' },
{ code: 'DE-HH', name: 'Hamburg' },
{ code: 'DE-HE', name: 'Hessen' },
{ code: 'DE-MV', name: 'Mecklenburg-Vorpommern' },
{ code: 'DE-NI', name: 'Niedersachsen' },
{ code: 'DE-NW', name: 'Nordrhein-Westfalen' },
{ code: 'DE-RP', name: 'Rheinland-Pfalz' },
{ code: 'DE-SL', name: 'Saarland' },
{ code: 'DE-SN', name: 'Sachsen' },
{ code: 'DE-ST', name: 'Sachsen-Anhalt' },
{ code: 'DE-SH', name: 'Schleswig-Holstein' },
{ code: 'DE-TH', name: 'Thüringen' }
]
return reply.send({
...data,
state_code: bundeslaender.find(i => i.name === data.countryName)
})
} catch (err) {
console.log(err)
return reply.code(500).send({ error: 'Internal server error' })
}
})
}

View File

@@ -23,13 +23,27 @@ const getCoordinatesForPDFLib = (x:number ,y:number, page:any) => {
}
const getBackgroundSourceBuffer = async (server:FastifyInstance, path:string) => {
const {data:backgroundPDFData,error:backgroundPDFError} = await server.supabase.storage.from("files").download(path)
return backgroundPDFData.arrayBuffer()
}
const getDuration = (time) => {
const minutes = Math.floor(dayjs(time.stopped_at).diff(dayjs(time.started_at),'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 createInvoicePDF = async (server:FastifyInstance, returnMode, invoiceData, backgroundPath:string) => {
console.log(returnMode, invoiceData, backgroundPath)
const genPDF = async (invoiceData, backgroundSourceBuffer) => {
const pdfDoc = await PDFDocument.create()
@@ -841,14 +855,216 @@ export const createInvoicePDF = async (server:FastifyInstance, returnMode, invoi
}
const {data:backgroundPDFData,error:backgroundPDFError} = await server.supabase.storage.from("files").download(backgroundPath)
const pdfBytes = await genPDF(invoiceData, await backgroundPDFData.arrayBuffer())
const pdfBytes = await genPDF(invoiceData, await getBackgroundSourceBuffer(server,backgroundPath))
if(returnMode === "base64"){
return {
mimeType: 'application/pdf',
base64: pdfBytes
}
} else {
return null
}
}
export const createTimeSheetPDF = async (server: FastifyInstance, returnMode, data, backgroundPath: string) => {
const genPDF = async (input, backgroundSourceBuffer) => {
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.full_name}`,{
x: getCoordinatesForPDFLib(20,55,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,55,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,60,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,60,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,65,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,65,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,70,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,70,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,75,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,75,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,80,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,80,pages[pageCounter -1]).y,
size: 10,
})
pages[pageCounter - 1].drawText(`Soll Stunden: ${Math.floor(input.timeSpanWorkingMinutes/60)}:${Math.floor(Number(String(input.timeSpanWorkingMinutes % 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(`Inoffizielles Saldo: ${Math.sign(input.saldoInOfficial) === 1 ? "+" : "-"} ${Math.floor(Math.abs(input.saldoInOfficial/60))}:${Math.floor(Number(String(Math.abs(input.saldoInOfficial) % 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(`Saldo: ${Math.sign(input.saldo) === 1 ? "+" : "-"} ${Math.floor(Math.abs(input.saldo/60))}:${Math.floor(Number(String(Math.abs(input.saldo) % 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(`Start:`,{
x: getCoordinatesForPDFLib(20,100,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(20,100,pages[pageCounter -1]).y,
size: 10,
})
pages[pageCounter - 1].drawText(`Ende:`,{
x: getCoordinatesForPDFLib(60,100,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(60,100,pages[pageCounter -1]).y,
size: 10,
})
pages[pageCounter - 1].drawText(`Dauer:`,{
x: getCoordinatesForPDFLib(100,100,pages[pageCounter -1]).x,
y: getCoordinatesForPDFLib(100,100,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.started_at).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.stopped_at).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
})
})
return await pdfDoc.saveAsBase64()
}
try {
const pdfBytes = await genPDF(data, await getBackgroundSourceBuffer(server,backgroundPath))
if(returnMode === "base64"){
return {
mimeType: 'application/pdf',
base64: pdfBytes
}
} else {
return "test"
}
} catch(error) {
console.log(error)
}
}