Checkin Seite erstellt
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// PDF-Generierung Service
|
||||
|
||||
const PDFDocument = require('pdfkit');
|
||||
const QRCode = require('qrcode');
|
||||
const { db } = require('../database');
|
||||
const { formatDate, formatDateTime } = require('../helpers/utils');
|
||||
const { getHolidaysForDateRange } = require('./feiertage-service');
|
||||
@@ -528,4 +529,72 @@ function generatePDFToBuffer(timesheetId, req) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { generatePDF, generatePDFToBuffer };
|
||||
// Check-in/Check-out URL-Basis (wie im Dashboard-Frontend)
|
||||
function getCheckinBaseUrl(req) {
|
||||
const baseUrl = `${req.protocol}://${req.get('host')}`;
|
||||
return baseUrl.replace(/:\d+$/, ':3334');
|
||||
}
|
||||
|
||||
// PDF mit Check-in- und Check-out-QR-Codes (A4)
|
||||
async function generateCheckinCheckoutQRPDF(req, res) {
|
||||
const userId = req.session.userId;
|
||||
if (!userId) {
|
||||
return res.status(401).send('Nicht angemeldet');
|
||||
}
|
||||
const checkinBaseUrl = getCheckinBaseUrl(req);
|
||||
const checkinUrl = `${checkinBaseUrl}/api/checkin/${userId}`;
|
||||
const checkoutUrl = `${checkinBaseUrl}/api/checkout/${userId}`;
|
||||
|
||||
try {
|
||||
const [checkinQRBuffer, checkoutQRBuffer] = await Promise.all([
|
||||
QRCode.toBuffer(checkinUrl, { type: 'png', width: 400, margin: 1 }),
|
||||
QRCode.toBuffer(checkoutUrl, { type: 'png', width: 400, margin: 1 })
|
||||
]);
|
||||
|
||||
const firstname = (req.session.firstname || '').replace(/\s+/g, '');
|
||||
const lastname = (req.session.lastname || '').replace(/\s+/g, '');
|
||||
const namePart = [firstname, lastname].filter(Boolean).join('_') || 'User';
|
||||
const today = new Date();
|
||||
const dateStr = today.getFullYear() + '-' +
|
||||
String(today.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(today.getDate()).padStart(2, '0');
|
||||
const filename = `Check-in_Check-out_QR_${namePart}_${dateStr}.pdf`;
|
||||
|
||||
res.setHeader('Content-Type', 'application/pdf');
|
||||
res.setHeader('X-Content-Type-Options', 'nosniff');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
||||
|
||||
const doc = new PDFDocument({ size: 'A4', margin: 50 });
|
||||
doc.pipe(res);
|
||||
|
||||
const pageWidth = 595.28 - 100;
|
||||
const qrSize = 160;
|
||||
const gap = 40;
|
||||
const left1 = 50 + (pageWidth / 2 - qrSize - gap / 2);
|
||||
const left2 = 50 + (pageWidth / 2 + gap / 2);
|
||||
|
||||
doc.fontSize(18).text('Check-in / Check-out – Zeiterfassung', { align: 'center' });
|
||||
doc.moveDown(1.5);
|
||||
|
||||
const topY = doc.y;
|
||||
doc.image(checkinQRBuffer, left1, topY, { width: qrSize, height: qrSize });
|
||||
doc.image(checkoutQRBuffer, left2, topY, { width: qrSize, height: qrSize });
|
||||
|
||||
doc.fontSize(12).font('Helvetica-Bold');
|
||||
doc.text('Check-in', left1, topY + qrSize + 8, { width: qrSize, align: 'center' });
|
||||
doc.text('Check-out', left2, topY + qrSize + 8, { width: qrSize, align: 'center' });
|
||||
|
||||
doc.moveDown(2);
|
||||
doc.font('Helvetica').fontSize(10);
|
||||
doc.text('Scannen Sie den jeweiligen QR-Code zum Erfassen von Arbeitsbeginn (Check-in) bzw. Arbeitsende (Check-out).', 50, doc.y, { width: pageWidth, align: 'center' });
|
||||
|
||||
doc.end();
|
||||
} catch (err) {
|
||||
console.error('Fehler beim Generieren des QR-PDFs:', err);
|
||||
if (!res.headersSent) {
|
||||
res.status(500).send('Fehler beim Erstellen des PDFs');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { generatePDF, generatePDFToBuffer, generateCheckinCheckoutQRPDF };
|
||||
|
||||
Reference in New Issue
Block a user