diff --git a/src/lib/server/PDFGen.ts b/src/lib/server/PDFGen.ts deleted file mode 100644 index d975e37..0000000 --- a/src/lib/server/PDFGen.ts +++ /dev/null @@ -1,115 +0,0 @@ -import b from "bun"; - -import type { RecordEntry } from "$lib/db_types"; -import { MONTHS, toInt, padInt, parseDate, calculateDuration, isoToLocalDate, month_of, weekday_of } from "$lib/util" - -import { User } from "$lib/server/database" - -const SALUTATION = { - m: "Herrn", - w: "Frau" -} - -const GENDER_END = { - m: "", - w: "in", -} - -const TEMPLATE_LISTE = "template-liste.tex"; -const TEMPLATE_LISTE_BASE = "pdfgen/" + TEMPLATE_LISTE; - -const TEMPLATE_EST = "template-schaetzung.tex"; -const TEMPLATE_EST_BASE = "pdfgen/" + TEMPLATE_EST; - -export async function generateRecordPDF(user: User, date: Date) { - - const year = date.getFullYear(); - const month = date.getMonth() + 1; - - const dir = "pdfgen/user-" + user.id + "/"; - const file_pref = "Stundenliste-" + year + "-" + padInt(month, 2, 0); - const template_path = dir + TEMPLATE_LISTE; - - const records = user.get_entries_by_month(year, month); - const estimate = user.get_estimate_by_month(year, month); - const hr_sum = (() => { let s = 0; records.forEach((r) => { s += calculateDuration(r.start, r.end) }); return s; })() - - if (records.length == 0 || estimate == null || isNaN(estimate)) { - return; - } - - let exitCode = 0; - ({ exitCode: exitCode } = await b.$`mkdir -p ${dir}`.nothrow().quiet()); - - if (exitCode != 0) { - return; - } - - if (!await Bun.file(template_path).exists()) { - let { exitCode } = await b.$`cp ${TEMPLATE_LISTE_BASE} ${template_path}`.nothrow().quiet(); - if (exitCode != 0) { - console.warn(`Failed to copy pdf template liste to ${dir} (exit code: ${exitCode})`) - } - } - - // TODO: escape semicolon in comment - - /*console.log(dir + file_pref + ".csv") - console.log(`${user.name};${month_of(date)} ${year};${hr_sum.toFixed(2)};${estimate.toFixed(2)};${padInt(hr_sum - estimate, 2, 2, ' ')}`); - records.forEach((record) => { - console.log(`${record.date};${weekday_of(parseDate(record.date))};${record.start};${record.end};${calculateDuration(record.start, record.end).toFixed(2)};${record.comment}`) - })*/ - - const csvfile = Bun.file(dir + file_pref + ".csv") - const csvfilewriter = csvfile.writer() - - csvfilewriter.write(`${user.name};${month_of(date)} ${year};${hr_sum.toFixed(2)};${estimate.toFixed(2)};${padInt(hr_sum - estimate, 2, 2, ' ')}\n`) - - records.forEach((record) => { - csvfilewriter.write(`${record.date};${weekday_of(parseDate(record.date))};${record.start};${record.end};${calculateDuration(record.start, record.end).toFixed(2)};${record.comment}\n`) - }) - - csvfilewriter.end(); - - ({ exitCode: exitCode } = await b.$`pdflatex -interaction=nonstopmode -halt-on-error -jobname=${file_pref} -output-format=pdf template-liste.tex`.cwd(dir).quiet().nothrow()); - -} - - -export async function generateEstimatePDF(user: User, year: number, quarter: number) { - - const dir = "pdfgen/user-" + user.id + "/"; - const file_pref = "Stundenschätzung-" + year + "-Q" + number; - const template_path = dir + TEMPLATE_EST; - - const estimates = user.get_estimate(year, quarter); - - console.log(estimates); - - let exitCode = 0; - ({ exitCode: exitCode } = await b.$`mkdir -p ${dir}`.nothrow().quiet()); - - if (exitCode != 0) { - return; - } - - if (!await Bun.file(template_path).exists()) { - let { exitCode } = await b.$`cp ${TEMPLATE_EST_BASE} ${template_path}`.nothrow().quiet(); - if (exitCode != 0) { - console.warn(`Failed to copy pdf template estimate to ${dir} (exit code: ${exitCode})`) - } - } - - const csvfile = Bun.file(dir + file_pref + ".csv") - const csvfilewriter = csvfile.writer() - - csvfilewriter.write(`${SALUTATION[user.gender]} ${user.name};${user.address};Arbeitnehmer${GENDER_END[user.gender]};Teilzeitmitarbeiter${GENDER_END[user.gender]};${isoToLocalDate(new Date().toISOString())}\n`) - - for (let i = 0; i < 3; ++i) { - csvfilewriter.write(`${MONTHS[(quarter - 1) * 3 + i]} ${year};${estimates[`estimate_${i}`]}\n`); - } - - csvfilewriter.end(); - - ({ exitCode: exitCode } = await b.$`pdflatex -interaction=nonstopmode -halt-on-error -jobname=${file_pref} -output-format=pdf template-liste.tex`.cwd(dir).quiet().nothrow()); -} diff --git a/src/lib/server/docstore.ts b/src/lib/server/docstore.ts index 4601d48..b9ddc7b 100644 --- a/src/lib/server/docstore.ts +++ b/src/lib/server/docstore.ts @@ -3,7 +3,7 @@ import fs from "node:fs/promises" import Logs from "$lib/server/log" import { User } from "$lib/server/database"; -import { MONTHS, toInt, padInt, parseDate, calculateDuration, isoToLocalDate, month_of, weekday_of } from "$lib/util" +import { MONTHS, padInt, parseDate, calculateDuration, isoToLocalDate, weekday_of } from "$lib/util" export class UserBusyException extends Error { @@ -68,19 +68,6 @@ const GENDER_END: Record = { w: "in", } -/* - -const SALUTATION: Map = new Map(Object.entries({ - m: "Herrn", - w: "Frau" -})) - -const GENDER_END: Map = new Map(Object.entries({ - "m": "", - "w": "in", -})) -*/ - // this may be a race condition??? // is a mutex needed in JS? let locked_users: Set = new Set(); @@ -113,7 +100,12 @@ export async function getAllFiles(user: User) { export async function getRecordFiles(user: User): Promise { const path = `${DOCUMENTS_PATH}/user-${user.id}/${RECORDS_FOLD}`; - let file_names = await fs.readdir(path).catch((err) => { console.log(err); return [] }); + let file_names = await fs.readdir(path).catch((err) => { + if (err.code !== "ENOENT") { + Logs.documents.error(`Failed to read record files: ${err.message}`) + } + return [] + }); let files: FileProperties[] = await Promise.all(file_names.map(async (v) => { return { @@ -130,7 +122,12 @@ export async function getRecordFiles(user: User): Promise { export async function getEstimateFiles(user: User): Promise { const path = `${DOCUMENTS_PATH}/user-${user.id}/${ESTIMATES_FOLD}`; - let file_names = await fs.readdir(path).catch((err) => { console.log(err); return [] }); + let file_names = await fs.readdir(path).catch((err) => { + if (err.code !== "ENOENT") { + Logs.documents.error(`Failed to read estimate files: ${err.message}`) + } + return [] + }); let files: FileProperties[] = await Promise.all(file_names.map(async (v) => { return {