Bilder fix Datenblatt

This commit is contained in:
Moritz Utcke
2025-04-01 09:35:15 -03:00
parent c8b41458e1
commit 14e1d89024
41 changed files with 272 additions and 320 deletions

View File

@@ -12,7 +12,7 @@ export class Checkbox extends PDFElement {
throw new Error('Method not supported.');
}
draw(page: PDFPage, x: number, y: number): void {
async draw(page: PDFPage, x: number, y: number) {
page.drawRectangle({
x: x + this.borderWidth,
// NOTE: Keine Ahnung warum * 1.5 aber dann passt es...

View File

@@ -103,15 +103,15 @@ export class Flex extends PDFElement {
return currentWidth;
}
draw(page: PDFPage, x: number = this.x, y: number = this.y): void {
async draw(page: PDFPage, x: number = this.x, y: number = this.y) {
const childPositions = this.calculateChildPositions(x + this.margin.left + this.padding.left, y - this.margin.top - this.padding.top);
// Draw each child
this.children.forEach((child, i) => {
const pos = childPositions[i];
for (let i = 0; i < this.children.length; i++) {
const child = this.children[i];
const pos = childPositions[i];
child.draw(page, pos.x, pos.y);
});
await child.draw(page, pos.x, pos.y);
}
}
private calculateChildPositions(x: number, y: number): { x: number; y: number }[] {

View File

@@ -50,9 +50,9 @@ export class Image extends PDFElement {
return;
}
if (this.options.src.split(".").pop() === "png") {
try {
embed = await page.doc.embedPng(img)
} else {
} catch(e) {
embed = await page.doc.embedJpg(img)
}
} else if (this.options.data) {
@@ -73,8 +73,6 @@ export class Image extends PDFElement {
}
}
page.drawImage(embed, {
x: x + this.margin.left + this.padding.left,
y: y - this.height - this.margin.top - this.padding.top,

View File

@@ -59,11 +59,11 @@ export class Layout extends PDFElement {
this._height = value;
}
draw(page: PDFPage, x: number, y: number): void {
async draw(page: PDFPage, x: number, y: number) {
let currentY = y - this.margin.top - this.padding.top;
for (const child of this.children) {
child.draw(page, x + this.margin.left + this.padding.left, currentY);
await child.draw(page, x + this.margin.left + this.padding.left, currentY);
currentY -= child.height + child.margin.top + child.margin.bottom;
}

View File

@@ -32,7 +32,9 @@ export abstract class PDFElement {
return this._height === "auto" ? 0 : this._height;
}
abstract draw(page: PDFPage, x: number, y: number): void;
async draw(page: PDFPage, x: number, y: number): Promise<void> {
throw new Error("Method is not implemented.")
}
abstract addChild(...children: PDFElement[]): void;
}

View File

@@ -49,7 +49,7 @@ export class Text extends PDFElement {
return this._width + this.padding.left + this.padding.right;
}
draw(page: PDFPage, x: number, y: number): void {
async draw(page: PDFPage, x: number, y: number): Promise<void> {
page.drawText(this.content, {
x: x + this.margin.left + this.padding.left,
y: y - this.height - this.margin.top - this.padding.top,

View File

@@ -51,7 +51,7 @@ export function xml2pdf(xml: string, fonts: Record<string, PDFFont> & { "default
color = rgb(...colorValue.map((x) => parseInt(x) / 255) as [number, number, number]);
}
const text = new Text(child.children[0] || "", { font: child.attributes.hasOwnProperty("font") ? fonts[child.attributes["font"]] : fonts["default"], lineHeight: parseFloat(child.attributes.lineHeight), fontSize: parseFloat(child.attributes.size) || 10, color, margin: {
const text = new Text(child.children[0] as string || "", { font: child.attributes.hasOwnProperty("font") ? fonts[child.attributes["font"]] : fonts["default"], lineHeight: parseFloat(child.attributes.lineHeight), fontSize: parseFloat(child.attributes.size) || 10, color, margin: {
bottom: parseFloat(child.attributes.marginBottom) || 0,
left: parseFloat(child.attributes.marginLeft) || 0,
right: parseFloat(child.attributes.marginRight) || 0,
@@ -114,43 +114,4 @@ export function xml2pdf(xml: string, fonts: Record<string, PDFFont> & { "default
iterateChildren(tree, layout)
return layout
}
// const pdf = await PDFDocument.create()
// const page = pdf.addPage()
// const font = await pdf.embedFont(StandardFonts.Helvetica)
// const bold = await pdf.embedFont(StandardFonts.HelveticaBold)
// console.log(page.getWidth(), "WIDTH");
// const layout = xml2pdf(`
// <flex direction="column" justify="end" width="${page.getWidth()}" height="${page.getHeight()}">
// <flex direction="row" gap="5" align="center">
// <checkbox width="8" height="8"></checkbox>
// <text size="12">awd1</text>
// </flex>
// <flex direction="row" gap="5" align="center">
// <checkbox width="8" height="8"></checkbox>
// <text size="12">awd2</text>
// </flex>
// <flex direction="row" gap="5" align="center">
// <checkbox width="8" height="8"></checkbox>
// <text size="12">awd3</text>
// </flex>
// <flex direction="row" gap="5" align="center">
// <checkbox width="8" height="8"></checkbox>
// <text size="12">awd4</text>
// </flex>
// </flex>`, {
// "default": font
// })
// layout.draw(page, 0, page.getHeight())
// import { writeFileSync } from "fs"
// import { FixedLengthArray } from "#lib/Berechnungen/BedarfsausweisWohnen/types.js"
// writeFileSync("./test-pdf.pdf", await pdf.save())
}

View File

@@ -382,78 +382,9 @@ export async function pdfDatenblattVerbrauchsausweisGewerbe(ausweis: Verbrauchsa
${images.map(badge => `<flex direction="row" justify="space-between" width="${pages[2].getWidth() - 120}" height="${(pages[2].getHeight() - marginY * 2) / 4}" marginTop="15">${badge.join("")}</flex>`).join("")}
</layout>`, { "default": font })
layout.draw(pages[0], 0, pages[0].getHeight())
layoutPage2.draw(pages[1], 0, pages[1].getHeight())
layoutPage3.draw(pages[2], 0, pages[2].getHeight())
// const containerWidth = width - marginX;
// const layout = flex([
// flex([
// checkbox(8, 8), text("Neubau", {
// color: rgb(0,0,0),
// font,
// fontSize: 12
// })
// ], {
// align: "center",
// justify: "center",
// gap: 5,
// height: 12,
// page: pages[0]
// }),
// flex([
// checkbox(8, 8), text("Vermietung/Verkauf", {
// color: rgb(0,0,0),
// font,
// fontSize: 12
// })
// ], {
// align: "center",
// justify: "center",
// gap: 5,
// height: 12,
// page: pages[0]
// }),
// flex([
// checkbox(8, 8), text("Modernisierung", {
// color: rgb(0,0,0),
// font,
// fontSize: 12
// })
// ], {
// align: "center",
// justify: "center",
// gap: 5,
// height: 12,
// page: pages[0]
// }),
// flex([
// checkbox(8, 8), text("Sonstiges", {
// color: rgb(0,0,0),
// font,
// fontSize: 12
// })
// ], {
// align: "center",
// justify: "center",
// gap: 5,
// height: 12,
// page: pages[0]
// })
// ], {
// align: "center",
// justify: "space-between",
// gap: 15,
// x: marginX,
// y: height - marginY - 165,
// height: 12,
// width: containerWidth
// })
// layout.draw(pages[0])
// pdf.getForm().flatten()
await layout.draw(pages[0], 0, pages[0].getHeight())
await layoutPage2.draw(pages[1], 0, pages[1].getHeight())
await layoutPage3.draw(pages[2], 0, pages[2].getHeight())
return pdf.save();
}

View File

@@ -298,7 +298,7 @@ export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: Verbrauchsau
const images: string[][] = []
for (const bild of bilder) {
let badge: string[];
let batch: string[];
let image: string = "";
if (bild.kategorie === Enums.BilderKategorie.Gebaeude) {
@@ -310,26 +310,30 @@ export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: Verbrauchsau
}
if (images.length > 0) {
let badge = images[images.length - 1]
if (badge.length == 3) {
badge = [image]
images.push(badge)
let batch = images[images.length - 1]
if (batch.length == 3) {
batch = [image]
images.push(batch)
} else {
badge.push(image)
batch.push(image)
}
} else {
badge = [image]
images.push(badge)
batch = [image]
images.push(batch)
}
}
const layoutPage3 = xml2pdf(`<layout height="${pages[2].getHeight()}" width="${pages[2].getWidth()}" marginTop="150" marginLeft="60" marginRight="60">
${images.map(badge => `<flex direction="row" justify="space-between" width="${pages[2].getWidth() - 120}" height="${(pages[2].getHeight() - marginY * 2) / 4}" marginTop="15">${badge.join("")}</flex>`).join("")}
${images.map(batch => `<flex direction="row" justify="space-between" width="${pages[2].getWidth() - 120}" height="${(pages[2].getHeight() - marginY * 2) / 4}" marginTop="15">${batch.join("")}</flex>`).join("")}
</layout>`, { "default": font })
layout.draw(pages[0], 0, pages[0].getHeight())
layoutPage2.draw(pages[1], 0, pages[1].getHeight())
layoutPage3.draw(pages[2], 0, pages[2].getHeight())
await layout.draw(pages[0], 0, pages[0].getHeight())
await layoutPage2.draw(pages[1], 0, pages[1].getHeight())
await layoutPage3.draw(pages[2], 0, pages[2].getHeight())
console.log("DONE");
return pdf.save();
}

View File

@@ -1,5 +1,6 @@
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
import * as fs from "fs";
import { tryCatch } from "./tryCatch.js";
export const s3Client = new S3Client({
region: "eu-central-1",
@@ -17,21 +18,18 @@ export async function getS3File(
bucket: string,
key: string
): Promise<Buffer | null> {
try {
let command = new GetObjectCommand({ Bucket: bucket, Key: key });
let response = await s3Client.send(command);
let command = new GetObjectCommand({ Bucket: bucket, Key: key });
const body = response.Body;
let [response, error] = await tryCatch(s3Client.send(command));
if (!body) {
return null;
}
let buffer = await streamToBuffer(body as unknown as fs.ReadStream);
return buffer;
} catch (e) {
if (error || response === null) {
return null;
}
const body = response.Body;
let buffer = await streamToBuffer(body as unknown as fs.ReadStream);
return buffer;
}
async function streamToBuffer(stream: fs.ReadStream): Promise<Buffer> {

View File

@@ -1,4 +1,4 @@
import { AufnahmeClient, BedarfsausweisWohnenClient, BenutzerClient, BildClient, getAusweisartFromUUID, ObjektClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { AufnahmeClient, BedarfsausweisWohnenClient, BenutzerClient, BildClient, getAusweisartFromId, ObjektClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { pdfDatenblattVerbrauchsausweisGewerbe } from "#lib/pdf/pdfDatenblattVerbrauchsausweisGewerbe.js";
import { pdfDatenblattVerbrauchsausweisWohnen } from "#lib/pdf/pdfDatenblattVerbrauchsausweisWohnen.js";
import { pdfVerbrauchsausweisGewerbe } from "#lib/pdf/pdfVerbrauchsausweisGewerbe.js";
@@ -10,7 +10,7 @@ import { Enums, prisma } from "#lib/server/prisma.js";
* @param id Die Ausweis UID
*/
export function getPrismaAusweisAdapter(id: string) {
const ausweisart = getAusweisartFromUUID(id);
const ausweisart = getAusweisartFromId(id);
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
return prisma.verbrauchsausweisWohnen
@@ -25,7 +25,7 @@ export function getPrismaAusweisAdapter(id: string) {
* Gibt den richtigen Ansichtsausweis basierend auf der Ausweisart zurück.
* @param ausweis
*/
export async function getAnsichtsausweis(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, ausweisart = getAusweisartFromUUID(ausweis.uid)) {
export async function getAnsichtsausweis(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, ausweisart = getAusweisartFromId(ausweis.uid)) {
if (!ausweisart) {
return null
}
@@ -43,7 +43,7 @@ export async function getAnsichtsausweis(ausweis: VerbrauchsausweisWohnenClient
* Gibt das richtige Datenblatt basierend auf der Ausweisart zurück.
* @param ausweis
*/
export async function getDatenblatt(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, ausweisart = getAusweisartFromUUID(ausweis.uid)) {
export async function getDatenblatt(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, ausweisart = getAusweisartFromId(ausweis.uid)) {
if (!ausweisart) {
return null
}

View File

@@ -1,4 +1,4 @@
import { Aufnahme, Bild, Objekt, prisma, VerbrauchsausweisWohnen } from "./prisma.js";
import { Aufnahme, BedarfsausweisGewerbe, Bild, Objekt, prisma, Unterlage, VerbrauchsausweisWohnen } from "./prisma.js";
export async function getVerbrauchsausweisWohnen(id: string): Promise<VerbrauchsausweisWohnen | null> {
return await prisma.verbrauchsausweisWohnen.findUnique({
@@ -8,6 +8,14 @@ export async function getVerbrauchsausweisWohnen(id: string): Promise<Verbrauchs
})
}
export async function getBedarfsausweisGewerbe(id: string): Promise<BedarfsausweisGewerbe | null> {
return await prisma.bedarfsausweisGewerbe.findUnique({
where: {
id
}
})
}
export async function getAufnahme(id: string): Promise<Aufnahme | null> {
return await prisma.aufnahme.findUnique({
where: {
@@ -30,4 +38,12 @@ export async function getBilder(aufnahme_id: string): Promise<Bild[]> {
aufnahme_id
}
})
}
export async function getUnterlagen(aufnahme_id: string): Promise<Unterlage[]> {
return await prisma.unterlage.findMany({
where: {
aufnahme_id
}
})
}

View File

@@ -1,4 +1,4 @@
import { getAusweisartFromUUID } from "#components/Ausweis/types.js";
import { getAusweisartFromId } from "#components/Ausweis/types.js";
import { BASE_URI } from "#lib/constants.js";
import { transport } from "#lib/mail.js";
import {
@@ -32,7 +32,7 @@ export async function sendInvoiceMail(
return;
}
const ausweisart = getAusweisartFromUUID(ausweis.id);
const ausweisart = getAusweisartFromId(ausweis.id);
if (!ausweisart) {
return

View File

@@ -1,4 +1,4 @@
import { getAusweisartFromUUID } from "#components/Ausweis/types.js";
import { getAusweisartFromId } from "#components/Ausweis/types.js";
import { transport } from "#lib/mail.js";
import {
Benutzer,
@@ -32,7 +32,7 @@ export async function sendPaymentSuccessMail(
}
let info: string = "";
const ausweisart = getAusweisartFromUUID(ausweis.id);
const ausweisart = getAusweisartFromId(ausweis.id);
if (!ausweisart) {
return;