Sortieungsoptionen in Verwaltung, Umstellung der PDF generation auf generierung bei abgabe und ablage auf dem Sateisystem um einen Festen Stand zu garantieren

This commit is contained in:
2026-03-17 16:20:36 +01:00
parent 2aa4e6f037
commit a92694f693
8 changed files with 386 additions and 14 deletions

55
helpers/pdf-paths.js Normal file
View File

@@ -0,0 +1,55 @@
const path = require('path');
const { getCalendarWeek } = require('./utils');
function getPdfBaseDir() {
const configured = process.env.PDF_BASE_DIR && String(process.env.PDF_BASE_DIR).trim();
if (configured) return path.resolve(configured);
return path.resolve(path.join(__dirname, '..', 'pdf-cache'));
}
function asciiSafe(value) {
const s = String(value || '')
.normalize('NFKD')
.replace(/[\u0300-\u036f]/g, '');
return s.replace(/[^A-Za-z0-9_-]+/g, '_').replace(/_+/g, '_').replace(/^_+|_+$/g, '');
}
function getYearFromDate(dateStr) {
const d = new Date(dateStr);
const year = d.getFullYear();
return Number.isFinite(year) ? String(year) : 'unknown-year';
}
function buildTimesheetPdfLocation(timesheetRow) {
if (!timesheetRow) throw new Error('timesheetRow is required');
const baseDir = getPdfBaseDir();
const userId = timesheetRow.user_id;
const year = getYearFromDate(timesheetRow.week_start);
const kw = getCalendarWeek(timesheetRow.week_start);
const version = timesheetRow.version || 1;
const first = asciiSafe(timesheetRow.firstname || '');
const last = asciiSafe(timesheetRow.lastname || '');
const namePart = [last, first].filter(Boolean).join('_') || `user_${userId}`;
const filename = `${namePart}_timesheet_${timesheetRow.id}_v${version}_KW${String(kw).padStart(2, '0')}_${year}.pdf`;
const relativePath = path.join(year, String(userId), filename);
const absolutePath = path.join(baseDir, relativePath);
return {
baseDir,
year,
kw,
filename,
relativePath,
absolutePath,
directory: path.dirname(absolutePath),
};
}
module.exports = {
getPdfBaseDir,
buildTimesheetPdfLocation,
};