From df00cb88e299168b3270d0b8849d2b9a28951390 Mon Sep 17 00:00:00 2001 From: Moritz Utcke Date: Wed, 19 Feb 2025 11:11:24 +1100 Subject: [PATCH] Verbrauchsausweis Gewerbe --- src/astro-typesafe-api-caller.ts | 10 +- src/components/Ausweis/types.ts | 4 +- .../VerbrauchsausweisGewerbe_2016.ts | 5 +- src/lib/altes-system/import.ts | 2 +- src/lib/pdf/pdfVerbrauchsausweisGewerbe.ts | 246 ++++++++++++++---- src/lib/pdf/pdfVerbrauchsausweisWohnen.ts | 27 +- src/lib/pdf/utils/helpers.ts | 24 ++ src/lib/validators/index.ts | 20 +- src/modules/Dashboard/DashboardModule.svelte | 14 +- src/pages/api/admin/ausstellen.ts | 4 +- src/pages/api/bedarfsausweis-wohnen/index.ts | 2 +- src/pages/api/bilder/[uid].ts | 8 +- .../index.ts | 2 +- src/pages/api/objekt/[uid]/bilder.ts | 14 +- .../api/verbrauchsausweis-gewerbe/index.ts | 2 +- .../api/verbrauchsausweis-wohnen/index.ts | 2 +- src/pages/bilder/[uid].webp.ts | 4 +- src/pages/dashboard/ausweise-pruefen.astro | 6 +- src/pages/dashboard/index.astro | 28 +- 19 files changed, 291 insertions(+), 133 deletions(-) create mode 100644 src/lib/pdf/utils/helpers.ts diff --git a/src/astro-typesafe-api-caller.ts b/src/astro-typesafe-api-caller.ts index f2a456e9..2059e34b 100644 --- a/src/astro-typesafe-api-caller.ts +++ b/src/astro-typesafe-api-caller.ts @@ -3,27 +3,27 @@ import { createCallerFactory } from "astro-typesafe-api/server"; export const createCaller = createCallerFactory({ "klimafaktoren": await import("../src/pages/api/klimafaktoren.ts"), "postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"), + "admin/ausstellen": await import("../src/pages/api/admin/ausstellen.ts"), "aufnahme/[uid]": await import("../src/pages/api/aufnahme/[uid].ts"), "aufnahme": await import("../src/pages/api/aufnahme/index.ts"), - "admin/ausstellen": await import("../src/pages/api/admin/ausstellen.ts"), "auth/access-token": await import("../src/pages/api/auth/access-token.ts"), "auth/forgot-password": await import("../src/pages/api/auth/forgot-password.ts"), "auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"), "bedarfsausweis-wohnen/[uid]": await import("../src/pages/api/bedarfsausweis-wohnen/[uid].ts"), "bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"), + "bilder/[uid]": await import("../src/pages/api/bilder/[uid].ts"), "geg-nachweis-verbrauchsausweis-wohnen/[uid]": await import("../src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/[uid].ts"), "geg-nachweis-verbrauchsausweis-wohnen": await import("../src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts"), - "bilder/[uid]": await import("../src/pages/api/bilder/[uid].ts"), "objekt": await import("../src/pages/api/objekt/index.ts"), - "ticket": await import("../src/pages/api/ticket/index.ts"), "rechnung": await import("../src/pages/api/rechnung/index.ts"), + "ticket": await import("../src/pages/api/ticket/index.ts"), "user": await import("../src/pages/api/user/index.ts"), "user/self": await import("../src/pages/api/user/self.ts"), + "verbrauchsausweis-wohnen/[uid]": await import("../src/pages/api/verbrauchsausweis-wohnen/[uid].ts"), + "verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"), "verbrauchsausweis-gewerbe/[uid]": await import("../src/pages/api/verbrauchsausweis-gewerbe/[uid].ts"), "verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.ts"), "webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"), - "verbrauchsausweis-wohnen/[uid]": await import("../src/pages/api/verbrauchsausweis-wohnen/[uid].ts"), - "verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"), "objekt/[uid]/bilder": await import("../src/pages/api/objekt/[uid]/bilder.ts"), "objekt/[uid]": await import("../src/pages/api/objekt/[uid]/index.ts"), "objekt/[uid]/unterlagen": await import("../src/pages/api/objekt/[uid]/unterlagen.ts"), diff --git a/src/components/Ausweis/types.ts b/src/components/Ausweis/types.ts index ddc77842..d4858bec 100644 --- a/src/components/Ausweis/types.ts +++ b/src/components/Ausweis/types.ts @@ -4,7 +4,7 @@ import { BedarfsausweisWohnen, Benutzer, Enums, - GebaeudeBilder, + Bild, Objekt, Rechnung, Tickets, @@ -16,7 +16,7 @@ import { z, ZodSchema } from "zod"; export type OmitKeys = Omit; -export type UploadedGebaeudeBild = OmitKeys & { +export type UploadedGebaeudeBild = OmitKeys & { base64: string } diff --git a/src/lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.ts b/src/lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.ts index 672bdd1c..d1fd3b49 100644 --- a/src/lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.ts +++ b/src/lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.ts @@ -135,13 +135,10 @@ export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis: energieVerbrauchWarmwasser_2 = 0; } - let kuehlungsZuschlag_1: number; - let kuehlungsZuschlag_2: number; + let kuehlungsZuschlag_1: number = 0, kuehlungsZuschlag_2: number = 0; if (ausweis.wird_gekuehlt) { kuehlungsZuschlag_1 = energieVerbrauchGesamt_1 * ((ausweis.anteil_kuehlung_1 || 0) / 100); kuehlungsZuschlag_2 = energieVerbrauchGesamt_2 * ((ausweis.anteil_kuehlung_2 || 0) / 100); - } else { - kuehlungsZuschlag_1 = kuehlungsZuschlag_2 = 0; } // Leerstand wird in Prozent angegeben, muss hier aber in eine Zahl zwischen 0 und 1 umgerechnet werden. diff --git a/src/lib/altes-system/import.ts b/src/lib/altes-system/import.ts index 2cfff4bc..8752ac26 100644 --- a/src/lib/altes-system/import.ts +++ b/src/lib/altes-system/import.ts @@ -43,7 +43,7 @@ export function verbrauchsausweisWohnenImportTranslate(ausweis: Record`, { - x, - y, - scale: 0.4, - color: rgb(0,0,0) - }) - } if (aufnahme.lueftung === Enums.Lueftungskonzept.Fensterlueftung) { - checkbox(pages[0], 213, height - 334) + addCheckMark(pages[0], 213, height - 334) } else if (aufnahme.lueftung === Enums.Lueftungskonzept.Schachtlueftung) { - checkbox(pages[0], 213, height - 345) + addCheckMark(pages[0], 213, height - 345) } else if (aufnahme.lueftung === Enums.Lueftungskonzept.LueftungsanlageMitWaermerueckgewinnung) { - checkbox(pages[0], 355, height - 334) + addCheckMark(pages[0], 355, height - 334) } else if (aufnahme.lueftung === Enums.Lueftungskonzept.LueftungsanlageOhneWaermerueckgewinnung) { - checkbox(pages[0], 355, height - 345) + addCheckMark(pages[0], 355, height - 345) } + // Kühlung + if (ausweis.wird_gekuehlt) { + addCheckMark(pages[0], 213, height - 362.5) + } else { + addCheckMark(pages[0], 355, height - 373.5) + } + + if (ausweis.ausstellgrund === Enums.Ausstellgrund.Neubau) { + addCheckMark(pages[0], 213, height - 406) + } else if (ausweis.ausstellgrund === Enums.Ausstellgrund.Vermietung) { + addCheckMark(pages[0], 213, height - 417) + } else if (ausweis.ausstellgrund === Enums.Ausstellgrund.Modernisierung) { + addCheckMark(pages[0], 344.5, height - 406) + } else if (ausweis.ausstellgrund === Enums.Ausstellgrund.Sonstiges) { + addCheckMark(pages[0], 463, height - 417) + } + // Aushangpflicht + // addCheckMark(pages[0], 463, height - 406) + + + const gebaeudeBild = bilder.find(image => image.kategorie === Enums.BilderKategorie.Gebaeude); @@ -131,6 +171,51 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe }) } + // Checkmark Angabe energetische Qualität des Gebäudes. + addCheckMark(pages[0], 40, height - 550) + + // Datenerhebung durch Eigentümer + addCheckMark(pages[0], 295, height - 580) + + // Ausstellungsdatum + pages[0].drawText(moment().format("DD.MM.YYYY"), { + font, + size: 10, + x: 508, + y: height - 752 + }) + + // Gültig bis + pages[0].drawText(moment().add(10, "years").format("DD.MM.YYYY"), { + font: bold, + size: 10, + x: 90, + y: height - 113 + }) + + // Stempel und Unterschrift + if (ausweis.ausgestellt) { + const stempel = await pdf.embedPng(fs.readFileSync(new URL("./images/stempel-unterschrift.png", import.meta.url), "base64")); + const stempelHeight = 60 + + pages[0].drawImage(stempel, { + x: 450, + y: height - 750, + height: stempelHeight, + width: stempel.width / (stempel.height / stempelHeight) + }) + } + + + // Aussteller + const aussteller = await pdf.embedPng(fs.readFileSync(new URL("./images/aussteller.png", import.meta.url), "base64")); + pages[0].drawImage(aussteller, { + x: 40, + y: height - 750, + width: 100, + height: 50 + }) + // /* -------------------------------- Seite 2 -------------------------------- */ @@ -138,95 +223,128 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe const addEnergieverbrauchSkalaPfeile = async (page: PDFPage) => { const pfeilNachUnten = await pdf.embedPng(fs.readFileSync(new URL("../../../public/images/pfeil-nach-unten.png", import.meta.url), "base64")) - const pfeilNachOben = await pdf.embedPng(fs.readFileSync(new URL("../../../public/images/pfeil-nach-oben.png", import.meta.url), "base64")) // Wir müssen den berechneten Wert zwischen 0 und 1000 als Wert zwischen 0 und 1 festlegen const endenergieverbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.endEnergieVerbrauchGesamt || 0)) / 1000 - const primaerenergieverbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.primaerEnergieVerbrauchGesamt || 0)) / 1000 + const stromVerbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.endEnergieVerbrauchStrom || 0)) / 1000 - const minTranslation = 120 - const maxTranslation = 457 + const minTranslation = 78 + const maxTranslation = 512 const endenergieverbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * endenergieverbrauchTranslationPercentage; - const primaerenergieverbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * primaerenergieverbrauchTranslationPercentage; + const stromVerbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * stromVerbrauchTranslationPercentage; const pfeilWidth = 20 const margin = 5; page.drawImage(pfeilNachUnten, { x: endenergieverbrauchTranslationX, - y: height - 215, + y: height - 210, width: pfeilWidth, height: 30 }) const endEnergieVerbrauchGesamtText = `${berechnungen?.endEnergieVerbrauchGesamt.toString()}kWh/(m²a)`; - const primaerEnergieVerbrauchGesamtText = `${berechnungen?.primaerEnergieVerbrauchGesamt.toString()}kWh/(m²a)`; + const stromVerbrauchGesamtText = `${berechnungen?.endEnergieVerbrauchStrom.toString()}kWh/(m²a)`; if (endenergieverbrauchTranslationPercentage > 0.5) { - page.drawText("Endenergieverbrauch", { + page.drawText("Endenergieverbrauch Wärme", { x: endenergieverbrauchTranslationX - margin - font.widthOfTextAtSize("Endenergieverbrauch", 10), - y: height - 193, + y: height - 191, size: 10 }) page.drawText(endEnergieVerbrauchGesamtText, { x: endenergieverbrauchTranslationX - margin - bold.widthOfTextAtSize(endEnergieVerbrauchGesamtText, 10), - y: height - 207, + y: height - 205, size: 10, font: bold }) } else { - page.drawText("Endenergieverbrauch", { + page.drawText("Endenergieverbrauch Wärme", { x: endenergieverbrauchTranslationX + pfeilWidth + margin, - y: height - 193, + y: height - 191, size: 10 }) page.drawText(endEnergieVerbrauchGesamtText, { x: endenergieverbrauchTranslationX + pfeilWidth + margin, - y: height - 207, + y: height - 205, size: 10, font: bold }) } - page.drawImage(pfeilNachOben, { - x: primaerenergieverbrauchTranslationX, - y: height - 298, + page.drawImage(pfeilNachUnten, { + x: stromVerbrauchTranslationX, + y: height - 354, width: pfeilWidth, height: 30 }) if (endenergieverbrauchTranslationPercentage > 0.5) { - page.drawText("Primärenergieverbrauch", { - x: primaerenergieverbrauchTranslationX - margin - font.widthOfTextAtSize("Primärenergieverbrauch", 10), - y: height - 280, + page.drawText("Endenergieverbrauch Strom", { + x: stromVerbrauchTranslationX - margin - font.widthOfTextAtSize("Primärenergieverbrauch", 10), + y: height - 335, size: 10 }) - page.drawText(primaerEnergieVerbrauchGesamtText, { - x: primaerenergieverbrauchTranslationX - margin - bold.widthOfTextAtSize(primaerEnergieVerbrauchGesamtText, 10), - y: height - 294, + page.drawText(stromVerbrauchGesamtText, { + x: stromVerbrauchTranslationX - margin - bold.widthOfTextAtSize(stromVerbrauchGesamtText, 10), + y: height - 349, size: 10, font: bold }) } else { - page.drawText("Primärenergieverbrauch", { - x: primaerenergieverbrauchTranslationX + pfeilWidth + margin, - y: height - 280, + page.drawText("Endenergieverbrauch Strom", { + x: stromVerbrauchTranslationX + pfeilWidth + margin, + y: height - 335, size: 10 }) - page.drawText(primaerEnergieVerbrauchGesamtText, { - x: primaerenergieverbrauchTranslationX + pfeilWidth + margin, - y: height - 294, + page.drawText(stromVerbrauchGesamtText, { + x: stromVerbrauchTranslationX + pfeilWidth + margin, + y: height - 349, size: 10, font: bold }) } } - addEnergieverbrauchSkalaPfeile(pages[1]) addEnergieverbrauchSkalaPfeile(pages[2]) + if (ausweis.warmwasser_enthalten) { + addCheckMark(pages[2], 41, height - 269) + } + + if (ausweis.kuehlung_enthalten) { + addCheckMark(pages[2], 41, height - 281) + } + + if (ausweis.stromverbrauch_enthaelt_heizung) { + addCheckMark(pages[2], 41, height - 456) + } + + if (ausweis.stromverbrauch_enthaelt_warmwasser) { + addCheckMark(pages[2], 131, height - 456) + } + + if (ausweis.stromverbrauch_enthaelt_lueftung) { + addCheckMark(pages[2], 218, height - 456) + } + + if (ausweis.stromverbrauch_enthaelt_beleuchtung) { + addCheckMark(pages[2], 281, height - 456) + } + + if (ausweis.stromverbrauch_enthaelt_kuehlung) { + addCheckMark(pages[2], 422, height - 456) + } + + if (ausweis.stromverbrauch_enthaelt_sonstige) { + addCheckMark(pages[2], 492, height - 456) + } + + addText(pages[2], berechnungen?.primaerEnergieVerbrauchGesamt.toString() || "", 475, height - 614, 10, font) + addText(pages[2], berechnungen?.co2EmissionenGesamt.toString() || "", 475, height - 633, 10, font) + // const primaerenergiebedarfIst = fillFormField("primaerenergiebedarf_ist", berechnungen?.primaerEnergieVerbrauchGesamt.toString()) @@ -237,9 +355,9 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe const addVerbrauchGenerator = () => { let i = 0; let yOffset = 14.6; - const initialHeight = 435 + const initialHeight = 297 const initialXOffset = 36; - return (zeitraum_von?: string, zeitraum_bis?: string, energietraeger?: string, primaerfaktor?: string, energieverbrauch?: string, anteil_warmwasser?: string, anteil_heizung?: string, klimafaktor?: string) => { + return (zeitraum_von?: string, zeitraum_bis?: string, energietraeger?: string, primaerfaktor?: string, energieverbrauch?: string, anteil_warmwasser?: string, anteil_kaelte?: number, anteil_heizung?: string, klimafaktor?: string, strom?: number) => { pages[2].drawText(zeitraum_von || "", { x: initialXOffset, y: initialHeight - (i * yOffset), @@ -262,34 +380,48 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe }) pages[2].drawText(primaerfaktor || "", { - x: initialXOffset + 317, + x: initialXOffset + 232, y: initialHeight - (i * yOffset), size: 8, font }) pages[2].drawText(energieverbrauch || "", { - x: initialXOffset + 351, + x: initialXOffset + 275, y: initialHeight - (i * yOffset), size: 8, font }) pages[2].drawText(anteil_warmwasser || "", { - x: initialXOffset + 402, + x: initialXOffset + 325, + y: initialHeight - (i * yOffset), + size: 8, + font + }) + + pages[2].drawText(anteil_kaelte?.toString() || "", { + x: initialXOffset + 378, y: initialHeight - (i * yOffset), size: 8, font }) pages[2].drawText(anteil_heizung || "", { - x: initialXOffset + 453, + x: initialXOffset + 430, y: initialHeight - (i * yOffset), size: 8, font }) pages[2].drawText(klimafaktor || "", { + x: initialXOffset + 464, + y: initialHeight - (i * yOffset), + size: 8, + font + }) + + pages[2].drawText(strom?.toString() || "", { x: initialXOffset + 504, y: initialHeight - (i * yOffset), size: 8, @@ -310,8 +442,10 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe berechnungen?.brennstoff_1.primaerenergiefaktor.toString(), Math.round(berechnungen?.energieVerbrauchGesamt_1 || 0).toString(), "0", + berechnungen?.endEnergieVerbrauchKuehlungsZuschlag_1, Math.round(berechnungen?.energieVerbrauchHeizung_1 || 0).toString(), - berechnungen?.durchschnittsKlimafaktor.toString() + berechnungen?.durchschnittsKlimafaktor.toString(), + berechnungen?.energieVerbrauchStrom ); } else { // Ohne Warmwasserzuschlag @@ -322,8 +456,10 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe berechnungen?.brennstoff_1.primaerenergiefaktor.toString(), Math.round(berechnungen?.energieVerbrauchGesamt_1 || 0).toString(), Math.round(berechnungen?.energieVerbrauchWarmwasser_1 || 0).toString(), + berechnungen?.endEnergieVerbrauchKuehlungsZuschlag_1, Math.round(berechnungen?.energieVerbrauchHeizung_1 || 0).toString(), - berechnungen?.durchschnittsKlimafaktor.toString() + berechnungen?.durchschnittsKlimafaktor.toString(), + berechnungen?.energieVerbrauchStrom ); } @@ -335,8 +471,10 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe berechnungen?.brennstoff_2.primaerenergiefaktor.toString(), Math.round(berechnungen?.energieVerbrauchGesamt_2 || 0).toString(), Math.round(berechnungen?.energieVerbrauchWarmwasser_2 || 0).toString(), + berechnungen?.endEnergieVerbrauchKuehlungsZuschlag_2, Math.round(berechnungen?.energieVerbrauchHeizung_2 || 0).toString(), - berechnungen?.durchschnittsKlimafaktor.toString() + berechnungen?.durchschnittsKlimafaktor.toString(), + 0 ); } @@ -415,6 +553,12 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe } + for (const page of pages) { + addAnsichtsausweisLabel(page, font) + addDatumGEG(page, font) + } + + // pdf.getForm().flatten() diff --git a/src/lib/pdf/pdfVerbrauchsausweisWohnen.ts b/src/lib/pdf/pdfVerbrauchsausweisWohnen.ts index 2bb508fc..5eb2a0a5 100644 --- a/src/lib/pdf/pdfVerbrauchsausweisWohnen.ts +++ b/src/lib/pdf/pdfVerbrauchsausweisWohnen.ts @@ -7,6 +7,7 @@ import moment from "moment"; import { PDFDocument, PDFFont, PDFImage, PDFPage, RotationTypes, StandardFonts, TextAlignment } from "pdf-lib"; import { addCheckMark } from "./utils/checkbox.js"; import { addText } from "./utils/text.js"; +import { addAnsichtsausweisLabel, addDatumGEG } from "./utils/helpers.js"; /* -------------------------------- Pdf Tools ------------------------------- */ @@ -93,6 +94,7 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne }) } + // Nach 82 aus Wohnfläche ermittelt if (aufnahme.flaeche == 0) { addCheckMark(pages[0], 274, height - 277) } @@ -120,8 +122,6 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne }) // Stempel und Unterschrift - - // TODO: ausweis.erledigt if (ausweis.ausgestellt) { const stempel = await pdf.embedPng(fs.readFileSync(new URL("./images/stempel-unterschrift.png", import.meta.url), "base64")); const stempelHeight = 60 @@ -517,29 +517,6 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne for (const empfehlung of empfehlungen) { addEmpfehlung(empfehlung.anlagenteil, empfehlung.description, true, empfehlung.amortisationszeit, empfehlung.kosten) } - - - function addAnsichtsausweisLabel(page: PDFPage, font: PDFFont) { - page.drawText("Ansichtsausweis", { - x: page.getWidth() / 2 - font.heightAtSize(112) * 2.2, y: page.getHeight() - font.heightAtSize(112) / 2, - size: 112, - font, - rotate: { - type: RotationTypes.Degrees, - angle: -60 - }, - opacity: 0.3 - }) - } - - function addDatumGEG(page: PDFPage, font: PDFFont) { - page.drawText("20. Juli 2022", { - x: 308, - y: page.getHeight() - 70, - size: 10, - font - }) - } for (const page of pages) { addAnsichtsausweisLabel(page, font) diff --git a/src/lib/pdf/utils/helpers.ts b/src/lib/pdf/utils/helpers.ts new file mode 100644 index 00000000..dd9d3655 --- /dev/null +++ b/src/lib/pdf/utils/helpers.ts @@ -0,0 +1,24 @@ +import { PDFPage, PDFFont, RotationTypes } from "pdf-lib"; + +export function addDatumGEG(page: PDFPage, font: PDFFont) { + page.drawText("20. Juli 2022", { + x: 308, + y: page.getHeight() - 70, + size: 10, + font, + }); +} + +export function addAnsichtsausweisLabel(page: PDFPage, font: PDFFont) { + page.drawText("Ansichtsausweis", { + x: page.getWidth() / 2 - font.heightAtSize(112) * 2.2, + y: page.getHeight() - font.heightAtSize(112) / 2, + size: 112, + font, + rotate: { + type: RotationTypes.Degrees, + angle: -60, + }, + opacity: 0.3, + }); +} diff --git a/src/lib/validators/index.ts b/src/lib/validators/index.ts index fb89fafd..63bd961a 100644 --- a/src/lib/validators/index.ts +++ b/src/lib/validators/index.ts @@ -2,7 +2,7 @@ import { VerbrauchsausweisWohnenSchema, AufnahmeSchema, ObjektSchema, - GebaeudeBilderSchema, + BildSchema, RechnungSchema, EventSchema, BenutzerSchema, @@ -30,7 +30,7 @@ export const AnteilshaberValidator = AnteilshaberSchema.omit({ objekt_id: true }) -export const GebaeudeBilderValidator = GebaeudeBilderSchema.omit({ +export const BildValidator = BildSchema.omit({ id: true, objekt_id: true }) @@ -79,8 +79,8 @@ export const ObjektValidator = ObjektSchema.omit({ aufnahme: z.array( AufnahmeValidator ).nullable().optional(), - gebaeude_bilder: z.array( - GebaeudeBilderValidator + bilder: z.array( + BildValidator ).nullable().optional(), gebaeude_plaene: z.array( GebaeudePlaeneValidator @@ -112,8 +112,8 @@ export const VerbrauchsausweisWohnenValidator = id: true, }).merge( z.object({ - gebaeude_bilder: z.array( - GebaeudeBilderSchema.omit({ + bilder: z.array( + BildSchema.omit({ id: true, objekt_id: true, }) @@ -170,8 +170,8 @@ BedarfsausweisWohnenSchema.merge( id: true, }).merge( z.object({ - gebaeude_bilder: z.array( - GebaeudeBilderSchema.omit({ + bilder: z.array( + BildSchema.omit({ id: true, objekt_id: true, }) @@ -221,8 +221,8 @@ export const VerbrauchsausweisGewerbeValidator = id: true, }).merge( z.object({ - gebaeude_bilder: z.array( - GebaeudeBilderSchema.omit({ + bilder: z.array( + BildSchema.omit({ id: true, objekt_id: true, }) diff --git a/src/modules/Dashboard/DashboardModule.svelte b/src/modules/Dashboard/DashboardModule.svelte index 8c7f4793..bf26aacf 100644 --- a/src/modules/Dashboard/DashboardModule.svelte +++ b/src/modules/Dashboard/DashboardModule.svelte @@ -1,8 +1,12 @@

Willkommen zurück, {user.vorname}!

@@ -12,11 +16,11 @@

Gebäude

- +{/each}
\ No newline at end of file diff --git a/src/pages/api/admin/ausstellen.ts b/src/pages/api/admin/ausstellen.ts index 91ec6b74..6223cd51 100644 --- a/src/pages/api/admin/ausstellen.ts +++ b/src/pages/api/admin/ausstellen.ts @@ -29,7 +29,7 @@ export const GET = defineApiRoute({ include: { objekt: { include: { - gebaeude_bilder: true, + bilder: true, benutzer: true, }, }, @@ -88,7 +88,7 @@ export const GET = defineApiRoute({ ausweis, ausweis.aufnahme, ausweis.aufnahme.objekt, - ausweis.aufnahme.objekt.gebaeude_bilder, + ausweis.aufnahme.objekt.bilder, ausweis.aufnahme.objekt.benutzer ); const pdfDatenblatt = await pdfDatenblattVerbrauchsausweisWohnen( diff --git a/src/pages/api/bedarfsausweis-wohnen/index.ts b/src/pages/api/bedarfsausweis-wohnen/index.ts index 8aca276c..ecebf20c 100644 --- a/src/pages/api/bedarfsausweis-wohnen/index.ts +++ b/src/pages/api/bedarfsausweis-wohnen/index.ts @@ -109,7 +109,7 @@ export const GET = defineApiRoute({ include: { objekt: { include: { - gebaeude_bilder: true, + bilder: true, }, }, rechnungen: true, diff --git a/src/pages/api/bilder/[uid].ts b/src/pages/api/bilder/[uid].ts index eaa8afb6..ae786af2 100644 --- a/src/pages/api/bilder/[uid].ts +++ b/src/pages/api/bilder/[uid].ts @@ -1,5 +1,5 @@ import { authorizationMiddleware } from "#lib/middleware/authorization.js"; -import { GebaeudeBilderSchema, prisma } from "@ibcornelsen/database/server"; +import { BildSchema, prisma } from "@ibcornelsen/database/server"; import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { z } from "zod"; import isBase64 from "is-base64"; @@ -8,7 +8,7 @@ import { writeFileSync } from "fs"; import { UUidWithPrefix } from "#components/Ausweis/types.js"; export const PATCH = defineApiRoute({ - input: GebaeudeBilderSchema.pick({ + input: BildSchema.pick({ kategorie: true, }).merge(z.object({ base64: z.string() @@ -23,7 +23,7 @@ export const PATCH = defineApiRoute({ }) } - const image = await prisma.gebaeudeBilder.findUnique({ + const image = await prisma.Bild.findUnique({ where: { uid: ctx.params.uid, objekt: { @@ -55,7 +55,7 @@ export const PATCH = defineApiRoute({ const buffer = Buffer.from(dataWithoutPrefix, "base64"); if (input.kategorie !== image.kategorie) { - await prisma.gebaeudeBilder.update({ + await prisma.Bild.update({ where: { id: image.id }, diff --git a/src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts b/src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts index 701ad9f8..c1df057b 100644 --- a/src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts +++ b/src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts @@ -109,7 +109,7 @@ export const GET = defineApiRoute({ include: { objekt: { include: { - gebaeude_bilder: true, + bilder: true, }, }, rechnungen: true, diff --git a/src/pages/api/objekt/[uid]/bilder.ts b/src/pages/api/objekt/[uid]/bilder.ts index 2f478df3..72acb3fe 100644 --- a/src/pages/api/objekt/[uid]/bilder.ts +++ b/src/pages/api/objekt/[uid]/bilder.ts @@ -1,5 +1,5 @@ import { authorizationMiddleware } from "#lib/middleware/authorization.js"; -import { GebaeudeBilderSchema, prisma } from "@ibcornelsen/database/server"; +import { BildSchema, prisma } from "@ibcornelsen/database/server"; import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { z } from "zod"; import isBase64 from "is-base64"; @@ -7,7 +7,7 @@ import { fileURLToPath } from "url"; import { writeFileSync } from "fs"; export const PUT = defineApiRoute({ - input: GebaeudeBilderSchema.pick({ + input: BildSchema.pick({ kategorie: true, }).merge(z.object({ base64: z.string() @@ -46,7 +46,7 @@ export const PUT = defineApiRoute({ ); const buffer = Buffer.from(dataWithoutPrefix, "base64"); - const bild = await prisma.gebaeudeBilder.create({ + const bild = await prisma.Bild.create({ data: { kategorie: input.kategorie, objekt: { @@ -72,7 +72,7 @@ export const PUT = defineApiRoute({ console.log(e); // Bild wurde nicht gespeichert, wir löschen den Eintrag wieder - await prisma.gebaeudeBilder.delete({ + await prisma.Bild.delete({ where: { uid: bild.uid } @@ -92,7 +92,7 @@ export const PUT = defineApiRoute({ export const GET = defineApiRoute({ middleware: authorizationMiddleware, - output: z.array(GebaeudeBilderSchema.pick({ + output: z.array(BildSchema.pick({ kategorie: true, uid: true })), @@ -106,7 +106,7 @@ export const GET = defineApiRoute({ }, select: { benutzer_id: true, - gebaeude_bilder: { + bilder: { select: { kategorie: true, uid: true @@ -122,6 +122,6 @@ export const GET = defineApiRoute({ }) } - return objekt.gebaeude_bilder + return objekt.bilder }, }) \ No newline at end of file diff --git a/src/pages/api/verbrauchsausweis-gewerbe/index.ts b/src/pages/api/verbrauchsausweis-gewerbe/index.ts index 3bac4930..8f93ce0a 100644 --- a/src/pages/api/verbrauchsausweis-gewerbe/index.ts +++ b/src/pages/api/verbrauchsausweis-gewerbe/index.ts @@ -109,7 +109,7 @@ export const GET = defineApiRoute({ include: { objekt: { include: { - gebaeude_bilder: true, + bilder: true, }, }, rechnungen: true, diff --git a/src/pages/api/verbrauchsausweis-wohnen/index.ts b/src/pages/api/verbrauchsausweis-wohnen/index.ts index 4d384540..679faab8 100644 --- a/src/pages/api/verbrauchsausweis-wohnen/index.ts +++ b/src/pages/api/verbrauchsausweis-wohnen/index.ts @@ -113,7 +113,7 @@ export const GET = defineApiRoute({ include: { objekt: { include: { - gebaeude_bilder: true, + bilder: true, }, }, rechnungen: true, diff --git a/src/pages/bilder/[uid].webp.ts b/src/pages/bilder/[uid].webp.ts index 63cdb2aa..abd0ea61 100644 --- a/src/pages/bilder/[uid].webp.ts +++ b/src/pages/bilder/[uid].webp.ts @@ -27,7 +27,7 @@ export const GET = defineApiRoute({ }) } - const image = await prisma.gebaeudeBilder.findUnique({ + const image = await prisma.bild.findUnique({ where: { uid } @@ -40,7 +40,7 @@ export const GET = defineApiRoute({ }) } - const path = fileURLToPath(new URL(`../../../../../persistent/images/${image.uid}.webp`, import.meta.url)) + const path = fileURLToPath(new URL(`../../../persistent/images/${image.uid}.webp`, import.meta.url)) const base64 = fs.readFileSync(path, "base64") const buffer = Buffer.from(base64, "base64"); diff --git a/src/pages/dashboard/ausweise-pruefen.astro b/src/pages/dashboard/ausweise-pruefen.astro index 839fe550..5acac832 100644 --- a/src/pages/dashboard/ausweise-pruefen.astro +++ b/src/pages/dashboard/ausweise-pruefen.astro @@ -35,7 +35,7 @@ const ausweise = await prisma.verbrauchsausweisWohnen.findMany({ include: { objekt: { include: { - gebaeude_bilder: true, + bilder: true, } }, events: true @@ -52,8 +52,8 @@ function omit(key: string, obj: Record) { const reformedAusweise = ausweise.map(ausweis => ({ ausweis: omit("aufnahme", ausweis) as VerbrauchsausweisWohnenClient, aufnahme: omit("objekt", omit("events", ausweis.aufnahme)) as AufnahmeClient, - objekt: omit("gebaeude_bilder", ausweis.aufnahme.objekt) as ObjektClient, - bilder: ausweis.aufnahme.objekt.gebaeude_bilder as unknown as UploadedGebaeudeBild[], + objekt: omit("bilder", ausweis.aufnahme.objekt) as ObjektClient, + bilder: ausweis.aufnahme.objekt.bilder as unknown as UploadedGebaeudeBild[], events: ausweis.aufnahme.events })) --- diff --git a/src/pages/dashboard/index.astro b/src/pages/dashboard/index.astro index cff83023..497e9fad 100644 --- a/src/pages/dashboard/index.astro +++ b/src/pages/dashboard/index.astro @@ -1,9 +1,10 @@ --- import { createCaller } from "../../astro-typesafe-api-caller.js"; -import UserLayout from "../../layouts/UserLayout.astro"; import { validateAccessTokenServer } from "#server/lib/validateAccessToken"; import DashboardModule from "#modules/Dashboard/DashboardModule.svelte"; import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants"; +import Layout from "#layouts/Layout.astro"; +import { prisma } from "@ibcornelsen/database/server"; const accessTokenValid = await validateAccessTokenServer(Astro); @@ -18,13 +19,24 @@ const user = await caller.user.self.GET.fetch(undefined, { "Authorization": `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` } }); -const gebaeudeArray = await caller.objekt.GET.fetch({ limit: 5 }, { - headers: { - "Authorization": `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` + +if (!user) { + return Astro.redirect("/auth/login") +} + +const objekte = await prisma.objekt.findMany({ + where: { + benutzer: { + uid: user.uid + } + }, + take: 10, + include: { + bilder: true, } -}); +}) --- - - - \ No newline at end of file + + + \ No newline at end of file