Fehler Behoben
This commit is contained in:
@@ -6,9 +6,9 @@ const app = express();
|
|||||||
const base = '/';
|
const base = '/';
|
||||||
app.use(base, express.static('dist/client/'));
|
app.use(base, express.static('dist/client/'));
|
||||||
app.use(ssrHandler);
|
app.use(ssrHandler);
|
||||||
|
app.use(express.json({ limit: "50mb" }))
|
||||||
|
app.use(express.urlencoded({ limit: "50mb" }))
|
||||||
|
|
||||||
app.listen(80, function() {
|
app.listen(80, function() {
|
||||||
console.log('Server started on http://localhost:80');
|
console.log('Server started on http://localhost:80');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ export async function ausweisSpeichern(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = await api.aufnahme._uid.bilder.PUT.fetch({
|
const response = await api.aufnahme._uid.bilder.PUT.fetch({
|
||||||
base64: bild.base64,
|
data: bild.data,
|
||||||
kategorie: bild.kategorie
|
kategorie: bild.kategorie
|
||||||
}, {
|
}, {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export async function bilderHochladen(
|
|||||||
const imagesToUpload = images.filter(
|
const imagesToUpload = images.filter(
|
||||||
(image) => !image.uid || image.update
|
(image) => !image.uid || image.update
|
||||||
) as unknown as {
|
) as unknown as {
|
||||||
base64: string;
|
data: string;
|
||||||
kategorie: string;
|
kategorie: string;
|
||||||
uid?: string;
|
uid?: string;
|
||||||
update: boolean;
|
update: boolean;
|
||||||
@@ -46,7 +46,7 @@ export async function bilderHochladen(
|
|||||||
try {
|
try {
|
||||||
if (image.update) {
|
if (image.update) {
|
||||||
await api.bilder._uid.PATCH.fetch({
|
await api.bilder._uid.PATCH.fetch({
|
||||||
base64: image.base64,
|
data: image.data,
|
||||||
kategorie: image.kategorie as Enums.BilderKategorie,
|
kategorie: image.kategorie as Enums.BilderKategorie,
|
||||||
}, {
|
}, {
|
||||||
params: {
|
params: {
|
||||||
@@ -58,7 +58,7 @@ export async function bilderHochladen(
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const response = await api.aufnahme._uid.bilder.PUT.fetch({
|
const response = await api.aufnahme._uid.bilder.PUT.fetch({
|
||||||
base64: image.base64,
|
data: image.data,
|
||||||
kategorie: image.kategorie as Enums.BilderKategorie
|
kategorie: image.kategorie as Enums.BilderKategorie
|
||||||
}, {
|
}, {
|
||||||
params: {
|
params: {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
export let ausweisart: Enums.Ausweisart
|
export let ausweisart: Enums.Ausweisart
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button class="border-2 rounded-lg bg-white text-center hover:shadow-md no-underline p-3 cursor-pointer" on:click={() => {
|
<button class="border-2 rounded-lg bg-white text-center hover:shadow-md no-underline p-3 cursor-pointer" type="button" on:click={() => {
|
||||||
openWindowWithPost("/pdf/ansichtsausweis", {
|
openWindowWithPost("/pdf/ansichtsausweis", {
|
||||||
ausweis: JSON.stringify(ausweis),
|
ausweis: JSON.stringify(ausweis),
|
||||||
aufnahme: JSON.stringify(aufnahme),
|
aufnahme: JSON.stringify(aufnahme),
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { z, ZodSchema } from "zod";
|
|||||||
export type OmitKeys<T, K extends keyof T> = Omit<T, K>;
|
export type OmitKeys<T, K extends keyof T> = Omit<T, K>;
|
||||||
|
|
||||||
export type UploadedGebaeudeBild = OmitKeys<Bild, "id" | "objekt_id"> & {
|
export type UploadedGebaeudeBild = OmitKeys<Bild, "id" | "objekt_id"> & {
|
||||||
base64: string
|
data: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<button class="border-2 rounded-lg bg-white text-center hover:shadow-md no-underline p-3 cursor-pointer" on:click={() => {
|
<button class="border-2 rounded-lg bg-white text-center hover:shadow-md no-underline p-3 cursor-pointer" type="button" on:click={() => {
|
||||||
openWindowWithPost("/pdf/datenblatt", {
|
openWindowWithPost("/pdf/datenblatt", {
|
||||||
ausweis: JSON.stringify(ausweis),
|
ausweis: JSON.stringify(ausweis),
|
||||||
aufnahme: JSON.stringify(aufnahme),
|
aufnahme: JSON.stringify(aufnahme),
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
async function rotateImage(image: UploadedGebaeudeBild): Promise<UploadedGebaeudeBild> {
|
async function rotateImage(image: UploadedGebaeudeBild): Promise<UploadedGebaeudeBild> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = image.base64 ? image.base64 : `/bilder/${image.uid}.webp`;
|
img.src = image.data ? image.data : `/bilder/${image.uid}.webp`;
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
let canvas = document.createElement("canvas");
|
let canvas = document.createElement("canvas");
|
||||||
let ctx = canvas.getContext("2d");
|
let ctx = canvas.getContext("2d");
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
ctx?.rotate((-90 * Math.PI) / 180);
|
ctx?.rotate((-90 * Math.PI) / 180);
|
||||||
ctx?.drawImage(img, -img.width / 2, -img.height / 2);
|
ctx?.drawImage(img, -img.width / 2, -img.height / 2);
|
||||||
const clone = Object.assign({}, image)
|
const clone = Object.assign({}, image)
|
||||||
clone.base64 = canvas.toDataURL("image/webp");
|
clone.data = canvas.toDataURL("image/webp");
|
||||||
clone.update = true;
|
clone.update = true;
|
||||||
resolve(clone)
|
resolve(clone)
|
||||||
};
|
};
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
{#if image.kategorie == kategorie}
|
{#if image.kategorie == kategorie}
|
||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<img
|
<img
|
||||||
src={image.base64 ? image.base64 : `/bilder/${image.uid}.webp`}
|
src={image.data ? image.data : `/bilder/${image.uid}.webp`}
|
||||||
alt={kategorie}
|
alt={kategorie}
|
||||||
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all"
|
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
// Get the scaled-down data from the canvas in the desired output format and quality
|
// Get the scaled-down data from the canvas in the desired output format and quality
|
||||||
const dataURL = canvas.toDataURL("image/jpeg", 0.8);
|
const dataURL = canvas.toDataURL("image/jpeg", 0.8);
|
||||||
|
|
||||||
images.push({ base64: dataURL as string, kategorie });
|
images.push({ data: dataURL as string, kategorie });
|
||||||
images = images;
|
images = images;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
79
src/lib/pdf/elements/Image.ts
Normal file
79
src/lib/pdf/elements/Image.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { PDFPage, PDFFont, rgb, RGB, PDFImage } from 'pdf-lib';
|
||||||
|
import { PDFElement, Size } from './PDFElement.js';
|
||||||
|
import { Margin, Padding } from './Layout.js';
|
||||||
|
import * as fs from "fs"
|
||||||
|
|
||||||
|
export interface ImageOptions {
|
||||||
|
margin?: Margin,
|
||||||
|
width?: number,
|
||||||
|
height?: number,
|
||||||
|
src?: string,
|
||||||
|
data?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Image extends PDFElement {
|
||||||
|
private options: ImageOptions
|
||||||
|
|
||||||
|
protected _width: number;
|
||||||
|
protected _height: number;
|
||||||
|
|
||||||
|
public margin: Margin
|
||||||
|
|
||||||
|
constructor(options: ImageOptions) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._width = options.width || 0;
|
||||||
|
this._height = options.height || 0;
|
||||||
|
this.options = options;
|
||||||
|
this.margin = this.options.margin || { top: 0, left: 0, right: 0, bottom: 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
addChild(...children: PDFElement[]): void {
|
||||||
|
throw new Error("Cannot add child element to Image")
|
||||||
|
}
|
||||||
|
|
||||||
|
get height() {
|
||||||
|
return this._height;
|
||||||
|
}
|
||||||
|
|
||||||
|
get width() {
|
||||||
|
return this._width;
|
||||||
|
}
|
||||||
|
|
||||||
|
async draw(page: PDFPage, x: number, y: number) {
|
||||||
|
let embed: PDFImage;
|
||||||
|
if (this.options.src) {
|
||||||
|
const img = fs.readFileSync(this.options.src)
|
||||||
|
if (this.options.src.split(".").pop() === "png") {
|
||||||
|
embed = await page.doc.embedPng(img)
|
||||||
|
} else {
|
||||||
|
embed = await page.doc.embedJpg(img)
|
||||||
|
}
|
||||||
|
} else if (this.options.data) {
|
||||||
|
embed = await page.doc.embedJpg(this.options.data)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._height === 0) {
|
||||||
|
if (this._width) {
|
||||||
|
this._height = embed.height * (this._width / embed.width)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._width === 0) {
|
||||||
|
if (this._height) {
|
||||||
|
this._width = embed.width * (this._height / embed.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
page.drawImage(embed, {
|
||||||
|
x: x + this.margin.left + this.padding.left,
|
||||||
|
y: y - this.height - this.margin.top - this.padding.top,
|
||||||
|
height: this.height,
|
||||||
|
width: this.width,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import * as txml from "#lib/helpers/txml.js"
|
|||||||
import { PDFDocument, PDFFont, rgb, StandardFonts } from "pdf-lib"
|
import { PDFDocument, PDFFont, rgb, StandardFonts } from "pdf-lib"
|
||||||
import { Checkbox, Flex, Text } from "./index.js"
|
import { Checkbox, Flex, Text } from "./index.js"
|
||||||
import { Layout } from "./Layout.js"
|
import { Layout } from "./Layout.js"
|
||||||
|
import { Image } from "./Image.js"
|
||||||
import { PDFElement } from "./PDFElement.js"
|
import { PDFElement } from "./PDFElement.js"
|
||||||
|
|
||||||
export function xml2pdf(xml: string, fonts: Record<string, PDFFont> & { "default": PDFFont }) {
|
export function xml2pdf(xml: string, fonts: Record<string, PDFFont> & { "default": PDFFont }) {
|
||||||
@@ -90,6 +91,21 @@ export function xml2pdf(xml: string, fonts: Record<string, PDFFont> & { "default
|
|||||||
|
|
||||||
iterateChildren(child.children, layout)
|
iterateChildren(child.children, layout)
|
||||||
parent.addChild(layout)
|
parent.addChild(layout)
|
||||||
|
} else if (child.tagName === "img") {
|
||||||
|
const image = new Image({
|
||||||
|
width: parseFloat(child.attributes.width),
|
||||||
|
height: parseFloat(child.attributes.height),
|
||||||
|
margin: {
|
||||||
|
bottom: parseFloat(child.attributes.marginBottom) || 0,
|
||||||
|
left: parseFloat(child.attributes.marginLeft) || 0,
|
||||||
|
right: parseFloat(child.attributes.marginRight) || 0,
|
||||||
|
top: parseFloat(child.attributes.marginTop) || 0,
|
||||||
|
},
|
||||||
|
src: child.attributes.src,
|
||||||
|
data: child.attributes.data
|
||||||
|
})
|
||||||
|
|
||||||
|
parent.addChild(image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AufnahmeClient, BenutzerClient, ObjektClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
||||||
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
|
||||||
import * as fs from "fs"
|
import * as fs from "fs"
|
||||||
import { PDFDocument, rgb, StandardFonts, TextAlignment } from "pdf-lib";
|
import { PDFDocument, rgb, StandardFonts, TextAlignment } from "pdf-lib";
|
||||||
@@ -6,12 +6,16 @@ import { xml2pdf } from "./elements/xml2pdf.js";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Heizungsstatus } from "@ibcornelsen/database/server";
|
import { Heizungsstatus } from "@ibcornelsen/database/server";
|
||||||
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
|
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import { copyPage } from "./utils/copyPage.js";
|
||||||
|
|
||||||
/* -------------------------------- Pdf Tools ------------------------------- */
|
/* -------------------------------- Pdf Tools ------------------------------- */
|
||||||
|
|
||||||
export async function pdfDatenblattVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, benutzer: BenutzerClient) {
|
export async function pdfDatenblattVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, benutzer: BenutzerClient, bilder: UploadedGebaeudeBild[]) {
|
||||||
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("./templates/Leerseite_Datenblatt.pdf", import.meta.url), "base64");
|
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("./templates/Leerseite_Datenblatt.pdf", import.meta.url), "base64");
|
||||||
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
|
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
|
||||||
|
const page3 = copyPage(pdf.getPages()[0]);
|
||||||
|
pdf.addPage(page3);
|
||||||
const pages = pdf.getPages()
|
const pages = pdf.getPages()
|
||||||
|
|
||||||
// const template = VerbrauchsausweisWohnen2016Template as Template;
|
// const template = VerbrauchsausweisWohnen2016Template as Template;
|
||||||
@@ -135,7 +139,7 @@ export async function pdfDatenblattVerbrauchsausweisGewerbe(ausweis: Verbrauchsa
|
|||||||
</flex>
|
</flex>
|
||||||
<flex direction="row" align="center" justify="space-between" width="${(innerWidth) / 2 - 7.5}">
|
<flex direction="row" align="center" justify="space-between" width="${(innerWidth) / 2 - 7.5}">
|
||||||
<text size="12" lineHeight="14">Anlage zur Kühlung:</text>
|
<text size="12" lineHeight="14">Anlage zur Kühlung:</text>
|
||||||
<text size="12" lineHeight="14">${ausweis.wird_gekuehlt ? "Ja" : "Nein"}</text>
|
<text size="12" lineHeight="14">${aufnahme.kuehlung ? "Ja" : "Nein"}</text>
|
||||||
</flex>
|
</flex>
|
||||||
<flex direction="row" align="center" justify="space-between" width="${(innerWidth) / 2 - 7.5}">
|
<flex direction="row" align="center" justify="space-between" width="${(innerWidth) / 2 - 7.5}">
|
||||||
<text size="12" lineHeight="14">Leerstand:</text>
|
<text size="12" lineHeight="14">Leerstand:</text>
|
||||||
@@ -348,8 +352,39 @@ export async function pdfDatenblattVerbrauchsausweisGewerbe(ausweis: Verbrauchsa
|
|||||||
bold
|
bold
|
||||||
})
|
})
|
||||||
|
|
||||||
layout.draw(pages[0], 0, pages[0].getHeight())
|
const images: string[][] = []
|
||||||
layoutPage2.draw(pages[1], 0, pages[1].getHeight())
|
|
||||||
|
for (const bild of bilder) {
|
||||||
|
let badge: string[];
|
||||||
|
let image: string = "";
|
||||||
|
|
||||||
|
if (bild.uid) {
|
||||||
|
image = `<img src="${fileURLToPath(new URL(`../../../../persistent/images/${bilder[0].uid}.webp`, import.meta.url))}" width="${(pages[2].getHeight() - 120) / 3.1}" />`
|
||||||
|
} else if (bild.data) {
|
||||||
|
image = `<img data="${bild.data}" width="${(pages[2].getWidth() - 120) / 3.1}" height="180" />`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.length > 0) {
|
||||||
|
let badge = images[images.length - 1]
|
||||||
|
if (badge.length == 3) {
|
||||||
|
badge = [image]
|
||||||
|
images.push(badge)
|
||||||
|
} else {
|
||||||
|
badge.push(image)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
badge = [image]
|
||||||
|
images.push(badge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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="180" 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 containerWidth = width - marginX;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AufnahmeClient, BenutzerClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
||||||
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
|
||||||
import * as fs from "fs"
|
import * as fs from "fs"
|
||||||
import { PDFDocument, rgb, StandardFonts, TextAlignment } from "pdf-lib";
|
import { PDFDocument, rgb, StandardFonts, TextAlignment } from "pdf-lib";
|
||||||
@@ -6,14 +6,19 @@ import { checkbox, flex, text } from "./elements/index.js";
|
|||||||
import { xml2pdf } from "./elements/xml2pdf.js";
|
import { xml2pdf } from "./elements/xml2pdf.js";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Heizungsstatus } from "@ibcornelsen/database/server";
|
import { Heizungsstatus } from "@ibcornelsen/database/server";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import { copyPage } from "./utils/copyPage.js";
|
||||||
|
|
||||||
/* -------------------------------- Pdf Tools ------------------------------- */
|
/* -------------------------------- Pdf Tools ------------------------------- */
|
||||||
|
|
||||||
export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, benutzer: BenutzerClient) {
|
export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, benutzer: BenutzerClient, bilder: UploadedGebaeudeBild[]) {
|
||||||
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("./templates/Leerseite_Datenblatt.pdf", import.meta.url), "base64");
|
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("./templates/Leerseite_Datenblatt.pdf", import.meta.url), "base64");
|
||||||
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
|
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
|
||||||
|
const page3 = copyPage(pdf.getPages()[0]);
|
||||||
|
pdf.addPage(page3);
|
||||||
const pages = pdf.getPages()
|
const pages = pdf.getPages()
|
||||||
|
|
||||||
|
|
||||||
// const template = VerbrauchsausweisWohnen2016Template as Template;
|
// const template = VerbrauchsausweisWohnen2016Template as Template;
|
||||||
|
|
||||||
const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt);
|
const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt);
|
||||||
@@ -290,8 +295,39 @@ export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: Verbrauchsau
|
|||||||
bold
|
bold
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const images: string[][] = []
|
||||||
|
|
||||||
|
for (const bild of bilder) {
|
||||||
|
let badge: string[];
|
||||||
|
let image: string = "";
|
||||||
|
|
||||||
|
if (bild.uid) {
|
||||||
|
image = `<img src="${fileURLToPath(new URL(`../../../../persistent/images/${bilder[0].uid}.webp`, import.meta.url))}" width="${(pages[2].getHeight() - 120) / 3.1}" />`
|
||||||
|
} else if (bild.data) {
|
||||||
|
image = `<img data="${bild.data}" width="${(pages[2].getWidth() - 120) / 3.1}" height="180" />`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.length > 0) {
|
||||||
|
let badge = images[images.length - 1]
|
||||||
|
if (badge.length == 3) {
|
||||||
|
badge = [image]
|
||||||
|
images.push(badge)
|
||||||
|
} else {
|
||||||
|
badge.push(image)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
badge = [image]
|
||||||
|
images.push(badge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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="180" marginTop="15">${badge.join("")}</flex>`).join("")}
|
||||||
|
</layout>`, { "default": font })
|
||||||
|
|
||||||
layout.draw(pages[0], 0, pages[0].getHeight())
|
layout.draw(pages[0], 0, pages[0].getHeight())
|
||||||
layoutPage2.draw(pages[1], 0, pages[1].getHeight())
|
layoutPage2.draw(pages[1], 0, pages[1].getHeight())
|
||||||
|
layoutPage3.draw(pages[2], 0, pages[2].getHeight())
|
||||||
|
|
||||||
// const containerWidth = width - marginX;
|
// const containerWidth = width - marginX;
|
||||||
|
|
||||||
|
|||||||
@@ -159,9 +159,9 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
|
|||||||
if (gebaeudeBild) {
|
if (gebaeudeBild) {
|
||||||
let image: PDFImage;
|
let image: PDFImage;
|
||||||
try {
|
try {
|
||||||
image = await pdf.embedJpg(gebaeudeBild?.base64)
|
image = await pdf.embedJpg(gebaeudeBild?.data)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
image = await pdf.embedPng(gebaeudeBild?.base64)
|
image = await pdf.embedPng(gebaeudeBild?.data)
|
||||||
}
|
}
|
||||||
pages[0].drawImage(image, {
|
pages[0].drawImage(image, {
|
||||||
x: 460.5,
|
x: 460.5,
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne
|
|||||||
if (gebaeudeBild) {
|
if (gebaeudeBild) {
|
||||||
let image: PDFImage;
|
let image: PDFImage;
|
||||||
try {
|
try {
|
||||||
image = await pdf.embedJpg(gebaeudeBild?.base64)
|
image = await pdf.embedJpg(gebaeudeBild?.data)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
image = await pdf.embedPng(gebaeudeBild?.base64)
|
image = await pdf.embedPng(gebaeudeBild?.data)
|
||||||
}
|
}
|
||||||
pages[0].drawImage(image, {
|
pages[0].drawImage(image, {
|
||||||
x: 460.5,
|
x: 460.5,
|
||||||
@@ -439,7 +439,7 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne
|
|||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
"Leerstandszuschlag",
|
"Kühlungszuschlag",
|
||||||
berechnungen?.primaerfaktorww.toString(),
|
berechnungen?.primaerfaktorww.toString(),
|
||||||
Math.round(berechnungen?.kuehlungsZuschlag || 0).toString(),
|
Math.round(berechnungen?.kuehlungsZuschlag || 0).toString(),
|
||||||
"0",
|
"0",
|
||||||
|
|||||||
12
src/lib/pdf/utils/copyPage.ts
Normal file
12
src/lib/pdf/utils/copyPage.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { PDFPage, PDFName } from "pdf-lib";
|
||||||
|
|
||||||
|
export function copyPage(originalPage: PDFPage) {
|
||||||
|
const cloneNode = originalPage.node.clone();
|
||||||
|
|
||||||
|
const { Contents } = originalPage.node.normalizedEntries();
|
||||||
|
if (Contents) cloneNode.set(PDFName.of('Contents'), Contents.clone());
|
||||||
|
|
||||||
|
const cloneRef = originalPage.doc.context.register(cloneNode);
|
||||||
|
const clonePage = PDFPage.of(cloneNode, cloneRef, originalPage.doc);
|
||||||
|
return clonePage;
|
||||||
|
}
|
||||||
@@ -10,16 +10,16 @@ export const PUT = defineApiRoute({
|
|||||||
input: BildSchema.pick({
|
input: BildSchema.pick({
|
||||||
kategorie: true,
|
kategorie: true,
|
||||||
}).merge(z.object({
|
}).merge(z.object({
|
||||||
base64: z.string()
|
data: z.string()
|
||||||
})),
|
})),
|
||||||
output: z.object({
|
output: z.object({
|
||||||
uid: z.string({ description: "Die UID des Bildes." })
|
uid: z.string({ description: "Die UID des Bildes." })
|
||||||
}),
|
}),
|
||||||
middleware: authorizationMiddleware,
|
middleware: authorizationMiddleware,
|
||||||
async fetch(input, ctx, user) {
|
async fetch(input, ctx, user) {
|
||||||
const base64 = input.base64;
|
const data = input.data;
|
||||||
|
|
||||||
if (!isBase64(base64, { mimeRequired: true })) {
|
if (!isBase64(data, { mimeRequired: true })) {
|
||||||
throw new APIError({
|
throw new APIError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Das Bild ist nicht base64.",
|
message: "Das Bild ist nicht base64.",
|
||||||
@@ -40,7 +40,7 @@ export const PUT = defineApiRoute({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataWithoutPrefix = base64.replace(
|
const dataWithoutPrefix = data.replace(
|
||||||
/^data:image\/\w+;base64,/,
|
/^data:image\/\w+;base64,/,
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const PATCH = defineApiRoute({
|
|||||||
input: BildSchema.pick({
|
input: BildSchema.pick({
|
||||||
kategorie: true,
|
kategorie: true,
|
||||||
}).merge(z.object({
|
}).merge(z.object({
|
||||||
base64: z.string()
|
data: z.string()
|
||||||
})),
|
})),
|
||||||
output: z.void(),
|
output: z.void(),
|
||||||
middleware: authorizationMiddleware,
|
middleware: authorizationMiddleware,
|
||||||
@@ -23,10 +23,10 @@ export const PATCH = defineApiRoute({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const image = await prisma.Bild.findUnique({
|
const image = await prisma.bild.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid: ctx.params.uid,
|
uid: ctx.params.uid,
|
||||||
objekt: {
|
aufnahme: {
|
||||||
benutzer_id: user.id
|
benutzer_id: user.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,23 +39,23 @@ export const PATCH = defineApiRoute({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const base64 = input.base64;
|
const data = input.data;
|
||||||
|
|
||||||
if (!isBase64(base64, { mimeRequired: true })) {
|
if (!isBase64(data, { mimeRequired: true })) {
|
||||||
throw new APIError({
|
throw new APIError({
|
||||||
code: "BAD_REQUEST",
|
code: "BAD_REQUEST",
|
||||||
message: "Das Bild ist nicht base64.",
|
message: "Das Bild ist nicht base64.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataWithoutPrefix = base64.replace(
|
const dataWithoutPrefix = data.replace(
|
||||||
/^data:image\/\w+;base64,/,
|
/^data:image\/\w+;base64,/,
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
const buffer = Buffer.from(dataWithoutPrefix, "base64");
|
const buffer = Buffer.from(dataWithoutPrefix, "base64");
|
||||||
|
|
||||||
if (input.kategorie !== image.kategorie) {
|
if (input.kategorie !== image.kategorie) {
|
||||||
await prisma.Bild.update({
|
await prisma.bild.update({
|
||||||
where: {
|
where: {
|
||||||
id: image.id
|
id: image.id
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ const objekte = await prisma.objekt.findMany({
|
|||||||
},
|
},
|
||||||
take: 10,
|
take: 10,
|
||||||
include: {
|
include: {
|
||||||
bilder: true,
|
|
||||||
unterlagen: true,
|
|
||||||
aufnahmen: {
|
aufnahmen: {
|
||||||
include: {
|
include: {
|
||||||
|
bilder: true,
|
||||||
|
unterlagen: true,
|
||||||
bedarfsausweis_wohnen: true,
|
bedarfsausweis_wohnen: true,
|
||||||
verbrauchsausweis_gewerbe: true,
|
verbrauchsausweis_gewerbe: true,
|
||||||
verbrauchsausweis_wohnen: true
|
verbrauchsausweis_wohnen: true
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ export const POST: APIRoute = async (Astro) => {
|
|||||||
|
|
||||||
let pdf: Uint8Array<ArrayBufferLike> | null = null;
|
let pdf: Uint8Array<ArrayBufferLike> | null = null;
|
||||||
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
|
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
|
||||||
pdf = await pdfDatenblattVerbrauchsausweisWohnen(ausweis, aufnahme, objekt, bilder);
|
pdf = await pdfDatenblattVerbrauchsausweisWohnen(ausweis, aufnahme, objekt, user, bilder);
|
||||||
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
|
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
|
||||||
pdf = await pdfDatenblattVerbrauchsausweisGewerbe(ausweis, aufnahme, objekt, bilder);
|
pdf = await pdfDatenblattVerbrauchsausweisGewerbe(ausweis, aufnahme, objekt, user, bilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response(pdf, {
|
return new Response(pdf, {
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ describe("Bilder hochladen", async () => {
|
|||||||
const bild = await newClient.v1.bilder.getBase64.query({ uid: image.uid });
|
const bild = await newClient.v1.bilder.getBase64.query({ uid: image.uid });
|
||||||
|
|
||||||
expect(bild).toHaveProperty("base64");
|
expect(bild).toHaveProperty("base64");
|
||||||
expect(bild.base64).toBeTypeOf("string");
|
expect(bild.data).toBeTypeOf("string");
|
||||||
expect(bild.base64).toEqual(base64);
|
expect(bild.data).toEqual(base64);
|
||||||
})
|
})
|
||||||
|
|
||||||
test("bild sollte entfernbar sein", async () => {
|
test("bild sollte entfernbar sein", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user