diff --git a/src/model/key-handover.dto.ts b/src/model/key-handover.dto.ts new file mode 100644 index 0000000..7361c40 --- /dev/null +++ b/src/model/key-handover.dto.ts @@ -0,0 +1,17 @@ +export class KeyHandoverDto { + handoverId!: string; + handoverDate!: Date; + place!: string; + + giverName!: string; + giverAddress?: string; + + receiverName!: string; + receiverAddress?: string; + + keyType!: string; + keyNumber?: string; + quantity!: number; + objectDescription?: string; + notes?: string; +} \ No newline at end of file diff --git a/src/pdf/pdf.controller.ts b/src/pdf/pdf.controller.ts index f4fd612..ce5d374 100644 --- a/src/pdf/pdf.controller.ts +++ b/src/pdf/pdf.controller.ts @@ -1,6 +1,7 @@ -import { Controller, Get, Header, Res } from "@nestjs/common"; +import { Body, Controller, Get, Header, Res } from "@nestjs/common"; import { PdfService } from "./pdf.service"; import { Response } from 'express'; +import { KeyHandoverDto } from "src/model/key-handover.dto"; @Controller('pdf') export class PdfController { @@ -14,4 +15,14 @@ export class PdfController { res.setHeader('Content-Disposition', 'inline; filename="test.pdf"'); res.send(pdfBuffer); } + + @Get('keyhandover') + @Header('Content-Type', 'application/pdf') + async generatePdf(@Res() res: Response, @Body() dto: KeyHandoverDto): Promise { + const pdfBuffer = await this.pdfService.generatePdf(dto); + + res.setHeader('Content-Disposition', 'inline; filename="test.pdf"'); + res.send(pdfBuffer); + } + } \ No newline at end of file diff --git a/src/pdf/pdf.service.ts b/src/pdf/pdf.service.ts index bc1548a..9ba3d61 100644 --- a/src/pdf/pdf.service.ts +++ b/src/pdf/pdf.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; import puppeteer from 'puppeteer-core'; +import { KeyHandoverDto } from 'src/model/key-handover.dto'; @Injectable() export class PdfService { @@ -66,4 +67,230 @@ export class PdfService { await browser.close(); } } + + async generatePdf(dto: KeyHandoverDto): Promise { + const browser = await puppeteer.launch({ + executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || '/usr/bin/chromium', + headless: true, + args: ['--no-sandbox', '--disable-setuid-sandbox'], + }); + + + try { + const page = await browser.newPage(); + + const html = this.buildHtml(dto); + + await page.setContent(html, { + waitUntil: 'networkidle0', + }); + + const pdf = await page.pdf({ + format: 'A4', + printBackground: true, + margin: { + top: '20mm', + right: '15mm', + bottom: '20mm', + left: '15mm', + }, + displayHeaderFooter: true, + headerTemplate: `
`, + footerTemplate: ` +
+ Übergabeprotokoll + ${new Date().toLocaleString()} +
+ `, + }); + + const buffer = Buffer.from(pdf); + return buffer; + } finally { + await browser.close(); + } + } + + private buildHtml(dto: KeyHandoverDto): string { + return ` + + + + + Übergabeprotokoll + + + +

Übergabeprotokoll

+ +
+
Übergabedaten
+
+ Datum der Übergabe: + ${this.escapeHtml(new Date(dto.handoverDate).toLocaleDateString())} +
+ +
+ +
+
Übergeber
+
+ Name: + ${this.escapeHtml(dto.giverName)} +
+
+ Adresse: + ${this.escapeHtml(dto.giverAddress ?? '-')} +
+
+ +
+
Empfänger
+
+ Name: + ${this.escapeHtml(dto.receiverName)} +
+
+ Adresse: + ${this.escapeHtml(dto.receiverAddress ?? '-')} +
+
+ +
+
Schlüsselangaben
+ +
+ Schlüsselnummer: + ${this.escapeHtml(dto.keyNumber ?? '-')} +
+ +
+ Objekt / Raum: + ${this.escapeHtml(dto.objectDescription ?? '-')} +
+
+ Bemerkungen: +
+
${this.escapeHtml(dto.notes ?? '-')}
+ +
+ +
+ Hiermit bestätigt der Empfänger den Erhalt der oben aufgeführten Schlüssel. +
+ Mit ihrer Unterschrift bestätigen beide Parteien die ordnungsgemäße Übergabe. +
+ +
+
+
Unterschrift Übergeber
+
+
+
Unterschrift Empfänger
+
+
+ + + `; + } + + private escapeHtml(value: string): string { + if (!value) { return ""; } + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } } \ No newline at end of file