unit/#102-base-management #121
7 changed files with 97 additions and 24 deletions
|
@ -16,6 +16,8 @@ import { InspectionPointEnum } from "../../../enums/inspectionEnum";
|
||||||
import multer from "multer";
|
import multer from "multer";
|
||||||
import { FileSystemHelper } from "../../../helpers/fileSystemHelper";
|
import { FileSystemHelper } from "../../../helpers/fileSystemHelper";
|
||||||
import { PdfExport } from "../../../helpers/pdfExport";
|
import { PdfExport } from "../../../helpers/pdfExport";
|
||||||
|
import { PDFDocument } from "pdf-lib";
|
||||||
|
import sharp from "sharp";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description get all inspections sorted by id not having newer inspection
|
* @description get all inspections sorted by id not having newer inspection
|
||||||
|
@ -240,13 +242,37 @@ export async function finishInspection(req: Request, res: Response): Promise<any
|
||||||
formattedInspection.inspectionPlan.title
|
formattedInspection.inspectionPlan.title
|
||||||
}_${new Date(formattedInspection.finished ?? "").toLocaleDateString("de-de")}`;
|
}_${new Date(formattedInspection.finished ?? "").toLocaleDateString("de-de")}`;
|
||||||
|
|
||||||
await PdfExport.renderFile({
|
let inspectionPoints = [];
|
||||||
|
for (const ip of formattedInspection.inspectionVersionedPlan.inspectionPoints.sort(
|
||||||
|
(a, b) => (a.sort ?? 0) - (b.sort ?? 0)
|
||||||
|
)) {
|
||||||
|
let value = formattedInspection.checks.find((c) => c.inspectionPointId == ip.id).value;
|
||||||
|
let image = "";
|
||||||
|
if (ip.type == InspectionPointEnum.file && ip.others == "img") {
|
||||||
|
const imagePath = FileSystemHelper.formatPath("inspection", inspection.id, value);
|
||||||
|
let pngImageBytes = await sharp(imagePath).png().toBuffer();
|
||||||
|
image = `data:image/png;base64,${pngImageBytes.toString("base64")}`;
|
||||||
|
} else if (ip.type == InspectionPointEnum.oknok) {
|
||||||
|
value = value ? "OK" : "Nicht OK";
|
||||||
|
}
|
||||||
|
inspectionPoints.push({
|
||||||
|
title: ip.title,
|
||||||
|
description: ip.description,
|
||||||
|
type: ip.type,
|
||||||
|
min: ip.min,
|
||||||
|
max: ip.max,
|
||||||
|
others: ip.others,
|
||||||
|
value: value,
|
||||||
|
image: image,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let pdf = await PdfExport.renderFile({
|
||||||
template: "inspection",
|
template: "inspection",
|
||||||
title,
|
title,
|
||||||
filename: "printout",
|
saveToDisk: false,
|
||||||
folder: `inspection/${inspection.id}`,
|
|
||||||
data: {
|
data: {
|
||||||
inspector: `${req.userId}`,
|
inspector: `${req.lastname}, ${req.firstname}`,
|
||||||
context: formattedInspection.context || "---",
|
context: formattedInspection.context || "---",
|
||||||
createdAt: formattedInspection.created,
|
createdAt: formattedInspection.created,
|
||||||
finishedAt: formattedInspection.finished ?? new Date(),
|
finishedAt: formattedInspection.finished ?? new Date(),
|
||||||
|
@ -255,23 +281,55 @@ export async function finishInspection(req: Request, res: Response): Promise<any
|
||||||
plan: formattedInspection.inspectionPlan,
|
plan: formattedInspection.inspectionPlan,
|
||||||
planVersion: formattedInspection.inspectionVersionedPlan.version,
|
planVersion: formattedInspection.inspectionVersionedPlan.version,
|
||||||
planTitle: formattedInspection.inspectionPlan.title,
|
planTitle: formattedInspection.inspectionPlan.title,
|
||||||
checks: formattedInspection.inspectionVersionedPlan.inspectionPoints
|
checks: inspectionPoints,
|
||||||
.sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0))
|
|
||||||
.map((ip) => ({
|
|
||||||
title: ip.title,
|
|
||||||
description: ip.description,
|
|
||||||
type: ip.type,
|
|
||||||
min: ip.min,
|
|
||||||
max: ip.max,
|
|
||||||
value:
|
|
||||||
ip.type == InspectionPointEnum.file
|
|
||||||
? "siehe Anhang"
|
|
||||||
: formattedInspection.checks.find((c) => c.inspectionPointId == ip.id).value,
|
|
||||||
})),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Anhang hinzufügen
|
const finalDocument = await PDFDocument.create();
|
||||||
|
const printout = await PDFDocument.load(pdf);
|
||||||
|
const copiedPages = await finalDocument.copyPages(printout, printout.getPageIndices());
|
||||||
|
copiedPages.forEach((page) => finalDocument.addPage(page));
|
||||||
|
|
||||||
|
let resultsForAppend = inspectionPoints.filter((ip) => ip.type == InspectionPointEnum.file && ip.others == "pdf");
|
||||||
|
|
||||||
|
if (resultsForAppend.length !== 0) {
|
||||||
|
const appendixPage = finalDocument.addPage();
|
||||||
|
const { width, height } = appendixPage.getSize();
|
||||||
|
appendixPage.drawText("Anhang:", {
|
||||||
|
x: 50,
|
||||||
|
y: height - 50,
|
||||||
|
size: 24,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const appendix of resultsForAppend) {
|
||||||
|
const appendixPdfBytes = FileSystemHelper.readFileAsBase64("inspection", inspection.id, appendix.value);
|
||||||
|
const appendixPdf = await PDFDocument.load(appendixPdfBytes);
|
||||||
|
const appendixPages = await finalDocument.copyPages(appendixPdf, appendixPdf.getPageIndices());
|
||||||
|
appendixPages.forEach((page) => finalDocument.addPage(page));
|
||||||
|
|
||||||
|
/** print image
|
||||||
|
const imagePath = FileSystemHelper.formatPath("inspection", inspection.id, checkValue);
|
||||||
|
let pngImageBytes = await sharp(imagePath).png().toBuffer();
|
||||||
|
let image = await finalDocument.embedPng(pngImageBytes);
|
||||||
|
let dims = image.scale(1);
|
||||||
|
if (image) {
|
||||||
|
const page = finalDocument.addPage();
|
||||||
|
const { width, height } = page.getSize();
|
||||||
|
const x = (width - dims.width) / 2;
|
||||||
|
const y = (height - dims.height) / 2;
|
||||||
|
page.drawImage(image, {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width: dims.width,
|
||||||
|
height: dims.height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergedPdfBytes = await finalDocument.save();
|
||||||
|
FileSystemHelper.writeFile(`inspection/${inspection.id}`, `printout.pdf`, mergedPdfBytes);
|
||||||
|
|
||||||
let finish: FinishInspectionCommand = {
|
let finish: FinishInspectionCommand = {
|
||||||
id: inspectionId,
|
id: inspectionId,
|
||||||
|
|
|
@ -59,3 +59,7 @@ Handlebars.registerHelper("longdatetimeWithWeekday", function (aString) {
|
||||||
Handlebars.registerHelper("json", function (context) {
|
Handlebars.registerHelper("json", function (context) {
|
||||||
return JSON.stringify(context);
|
return JSON.stringify(context);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper("eq", function (p, q, options) {
|
||||||
|
return p == q ? options.fn(this) : options.inverse(this);
|
||||||
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@ export abstract class FileSystemHelper {
|
||||||
return readFileSync(this.formatPath(...filePath), "utf8");
|
return readFileSync(this.formatPath(...filePath), "utf8");
|
||||||
}
|
}
|
||||||
|
|
||||||
static readFileasBase64(...filePath: string[]) {
|
static readFileAsBase64(...filePath: string[]) {
|
||||||
this.createFolder(...filePath);
|
this.createFolder(...filePath);
|
||||||
return readFileSync(this.formatPath(...filePath), "base64");
|
return readFileSync(this.formatPath(...filePath), "base64");
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ export abstract class PdfExport {
|
||||||
const mergedPdf = await PDFDocument.create();
|
const mergedPdf = await PDFDocument.create();
|
||||||
|
|
||||||
for (const pdfPath of pdfFilePaths) {
|
for (const pdfPath of pdfFilePaths) {
|
||||||
const pdfBytes = FileSystemHelper.readFileasBase64(inputFolder, pdfPath);
|
const pdfBytes = FileSystemHelper.readFileAsBase64(inputFolder, pdfPath);
|
||||||
const pdf = await PDFDocument.load(pdfBytes);
|
const pdf = await PDFDocument.load(pdfBytes);
|
||||||
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
||||||
copiedPages.forEach((page) => mergedPdf.addPage(page));
|
copiedPages.forEach((page) => mergedPdf.addPage(page));
|
||||||
|
|
|
@ -11,6 +11,8 @@ declare global {
|
||||||
export interface Request {
|
export interface Request {
|
||||||
userId: string;
|
userId: string;
|
||||||
username: string;
|
username: string;
|
||||||
|
firstname: string;
|
||||||
|
lastname: string;
|
||||||
isOwner: boolean;
|
isOwner: boolean;
|
||||||
permissions: PermissionObject;
|
permissions: PermissionObject;
|
||||||
isPWA: boolean;
|
isPWA: boolean;
|
||||||
|
|
|
@ -35,6 +35,8 @@ export default async function authenticate(req: Request, res: Response, next: Ne
|
||||||
|
|
||||||
req.userId = decoded.userId;
|
req.userId = decoded.userId;
|
||||||
req.username = decoded.username;
|
req.username = decoded.username;
|
||||||
|
req.firstname = decoded.firstname;
|
||||||
|
req.lastname = decoded.lastname;
|
||||||
req.isOwner = decoded.isOwner;
|
req.isOwner = decoded.isOwner;
|
||||||
req.permissions = decoded.permissions;
|
req.permissions = decoded.permissions;
|
||||||
req.isWebApiRequest = decoded?.sub == "webapi_access_token";
|
req.isWebApiRequest = decoded?.sub == "webapi_access_token";
|
||||||
|
|
|
@ -17,16 +17,23 @@
|
||||||
<p>Kontext: {{context}}</p>
|
<p>Kontext: {{context}}</p>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<p>Prüfpunkte:</p>
|
<h3>Prüfpunkte:</h3>
|
||||||
<table style="width: 100%">
|
<table style="width: 100%">
|
||||||
{{#each checks}}
|
{{#each checks}}
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width: 50%; padding: 10px 5px">
|
<td style="width: 30%; padding: 10px 5px; word-break: break-word">
|
||||||
{{this.title}}
|
{{this.title}}
|
||||||
<br />
|
<br />
|
||||||
{{this.description}}
|
{{#if this.description}} > {{this.description}}
|
||||||
|
<br />
|
||||||
|
{{/if}}
|
||||||
|
<small>(Typ: {{this.type}})</small>
|
||||||
|
</td>
|
||||||
|
<td style="max-width: 70%; width: 70%; padding: 10px 5px; word-break: break-word">
|
||||||
|
{{#eq this.type "file"}} {{#eq this.others "img"}}
|
||||||
|
<img style="width: 100%; height: auto" src="{{ this.image }}" />
|
||||||
|
{{else}} siehe Anhang {{/eq}} {{else}} {{this.value}} {{/eq}}
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 50%; padding: 10px 5px">{{this.value}}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</table>
|
</table>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue