diff --git a/public/pdf/templates/GEG24_AushangNWG_Energieverbrauchsausweis.pdf b/public/pdf/templates/GEG24_AushangNWG_Energieverbrauchsausweis.pdf new file mode 100644 index 00000000..439e5c6b Binary files /dev/null and b/public/pdf/templates/GEG24_AushangNWG_Energieverbrauchsausweis.pdf differ diff --git a/src/lib/pdf/pdfAushangVerbrauchsausweisGewerbe.ts b/src/lib/pdf/pdfAushangVerbrauchsausweisGewerbe.ts new file mode 100644 index 00000000..ce1d46b5 --- /dev/null +++ b/src/lib/pdf/pdfAushangVerbrauchsausweisGewerbe.ts @@ -0,0 +1,834 @@ +import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types.js"; +import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js"; +import { Enums } from "#lib/server/prisma.js"; +import * as fs from "fs" +import moment from "moment"; +import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from "pdf-lib"; +import { addText } from "./utils/text.js"; +import { addAnsichtsausweisLabel, addDatumGEG, addRegistriernummer } from "./utils/helpers.js"; +import { getS3File } from "#lib/s3.js"; +import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Server.js"; + + +export async function pdfAushangVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, vorschau = true) { + const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("../../../public/pdf/templates/GEG24_AushangNWG_Energieverbrauchsausweis.pdf", import.meta.url), "base64"); + const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF) + const pages = pdf.getPages() + + // const template = VerbrauchsausweisWohnen2016Template as Template; + + const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server(ausweis, aufnahme, objekt); + + const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt) + + const height = pages[0].getHeight() + + const font = await pdf.embedFont(StandardFonts.Helvetica) + const bold = await pdf.embedFont(StandardFonts.HelveticaBold) + + const form = pdf.getForm() + form.updateFieldAppearances(font) + + pages[0].drawText(`${ausweis.registriernummer || ""}`, { + x: 393, + y: height - 112.5, + size: 10 + }) + + pages[0].drawText(aufnahme.gebaeudetyp || "", { + x: 211, + y: height - 164, + size: 10 + }) + + pages[0].drawText(objekt.adresse || "", { + x: 211, + y: height - 186, + size: 10 + }) + + pages[0].drawText(aufnahme.gebaeudeteil || "", { + x: 211, + y: height - 201, + size: 10 + }) + + pages[0].drawText(aufnahme.baujahr_gebaeude?.toString() || "", { + x: 211, + y: height - 220, + size: 10 + }) + + // pages[0].drawText(aufnahme.baujahr_heizung?.toString() || "", { + // x: 211, + // y: height - 250, + // size: 10 + // }) + + pages[0].drawText(aufnahme.nutzflaeche?.toString() || "", { + x: 211, + y: height - 237, + size: 10 + }) + + pages[0].drawText(`${ausweis.brennstoff_1}, ${ausweis.brennstoff_2 || ""}`, { + x: 211, + y: height - 250, + size: 10 + }) + + const erneuerbareEnergienVerwendung = [] + + if (ausweis.alternative_heizung) { + erneuerbareEnergienVerwendung.push("Heizung") + } + + if (ausweis.alternative_kuehlung) { + erneuerbareEnergienVerwendung.push("Kühlung") + } + + if (ausweis.alternative_lueftung) { + erneuerbareEnergienVerwendung.push("Lüftung") + } + + if (ausweis.alternative_warmwasser) { + erneuerbareEnergienVerwendung.push("Warmwasser") + } + + pages[0].drawText(erneuerbareEnergienVerwendung.join(", "), { + x: 430, + y: height - 326, + size: 8 + }) + + if (ausweis.warmwasser_enthalten) { + pages[0].drawText(`${ausweis.brennstoff_1}, ${ausweis.brennstoff_2 || ""}`, { + x: 211, + y: height - 265, + size: 10 + }) + } + + + if (aufnahme.lueftung === Enums.Lueftungskonzept.Fensterlueftung) { + pages[0].drawText("x", { + x: 215, + y: height - 280, + size: 10, + font: bold + }) + } else if (aufnahme.lueftung === Enums.Lueftungskonzept.Schachtlueftung) { + pages[0].drawText("x", { + x: 215, + y: height - 290, + size: 10, + font: bold + }) + } else if (aufnahme.lueftung === Enums.Lueftungskonzept.LueftungsanlageMitWaermerueckgewinnung) { + pages[0].drawText("x", { + x: 380, + y: height - 280, + size: 10, + font: bold + }) + } else if (aufnahme.lueftung === Enums.Lueftungskonzept.LueftungsanlageOhneWaermerueckgewinnung) { + pages[0].drawText("x", { + x: 380, + y: height - 290, + size: 10, + font: bold + }) + } + + // // Kühlung + if (aufnahme.kuehlung === "1" && aufnahme.kuehlung !== null) { + pages[0].drawText("x", { + x: 381, + y: height - 303, + size: 10, + font: bold + }) + } + + if (ausweis.kuehlung_enthalten === true && ausweis.kuehlung_enthalten !== null) { + pages[0].drawText("x", { + x: 381, + y: height - 313, + size: 10, + font: bold + }) + } + + // if (ausweis.ausstellgrund === Enums.Ausstellgrund.Neubau) { + // pages[0].drawText("x", { + // x: 214, + // y: height - 414, + // size: 10, + // font: bold + // }) + // } else if (ausweis.ausstellgrund === Enums.Ausstellgrund.Vermietung || ausweis.ausstellgrund === Enums.Ausstellgrund.Verkauf) { + // pages[0].drawText("x", { + // x: 214, + // y: height - 425, + // size: 10, + // font: bold + // }) + // } else if (ausweis.ausstellgrund === Enums.Ausstellgrund.Modernisierung) { + // pages[0].drawText("x", { + // x: 345.5, + // y: height - 414, + // size: 10, + // font: bold + // }) + // } else if (ausweis.ausstellgrund === Enums.Ausstellgrund.Sonstiges) { + // pages[0].drawText("x", { + // x: 464, + // y: height - 425, + // size: 10, + // font: bold + // }) + // } + // Aushangpflicht + // addCheckMark(pages[0], 463, height - 406) + + + + + + const bild = bilder && bilder.find(image => image.kategorie === Enums.BilderKategorie.Gebaeude); + + if (bild) { + const file = await getS3File("ibc-images", `${bild.id}.jpg`); + + if (file) { + let image: PDFImage; + image = await pdf.embedJpg(file) + pages[0].drawImage(image, { + x: 462, + y: height - 240, + width: 108, + height: 90 + }) + } + } + + // // Checkmark Verbrauchsausweis. + // pages[0].drawText("x", { + // x: 41, + // y: height - 558, + // size: 10, + // font: bold + // }) + + // // Datenerhebung durch Eigentümer + // pages[0].drawText("x", { + // x: 296.5, + // y: height - 587.5, + // size: 10, + // font: bold + // }) + + // Ausstellungsdatum + pages[0].drawText(moment().format("DD.MM.YYYY"), { + font, + size: 10, + x: 508, + y: height - 790 + }) + + // 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 || !vorschau) { + const stempel = await pdf.embedPng(fs.readFileSync(new URL("../../../public/pdf/images/stempel-unterschrift.png", import.meta.url), "base64")); + const stempelHeight = 65 + + pages[0].drawImage(stempel, { + x: 450, + y: height - 790, + height: stempelHeight, + width: stempel.width / (stempel.height / stempelHeight) + }) + } + + + // Aussteller + const aussteller = await pdf.embedPng(fs.readFileSync(new URL("../../../public/pdf/images/aussteller.png", import.meta.url), "base64")); + pages[0].drawImage(aussteller, { + x: 40, + y: height - 795, + width: 130, + height: 65 + }) + + + // // /* -------------------------------- Seite 2 -------------------------------- */ + + // // const co2Emissionen = fillFormField("co2emissionen", berechnungen?.co2EmissionenGesamt.toString(), 8, TextAlignment.Center) + + 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((berechnungen?.vergleichsWertWaerme * 2), Math.max(0, berechnungen?.endEnergieVerbrauchGesamt || 0)) / (berechnungen?.vergleichsWertWaerme * 2) + const stromVerbrauchTranslationPercentage = Math.min((berechnungen?.vergleichsWertStrom * 2), Math.max(0, berechnungen?.endEnergieVerbrauchStrom || 0)) / (berechnungen?.vergleichsWertStrom * 2) + const vergleichsWertWaermeTranslationPercentage = Math.min((berechnungen?.vergleichsWertWaerme * 2), Math.max(0, berechnungen?.vergleichsWertWaerme || 0)) / (berechnungen?.vergleichsWertWaerme * 2) + const vergleichsWertStromTranslationPercentage = Math.min((berechnungen?.vergleichsWertStrom * 2), Math.max(0, berechnungen?.vergleichsWertStrom || 0)) / (berechnungen?.vergleichsWertStrom * 2) + + const minTranslation = 78 + const maxTranslation = 512 + const endenergieverbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * endenergieverbrauchTranslationPercentage; + const stromVerbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * stromVerbrauchTranslationPercentage; + const vergleichsWertWaermeTranslationX = minTranslation + (maxTranslation - minTranslation) * vergleichsWertWaermeTranslationPercentage; + const vergleichsWertStromTranslationX = minTranslation + (maxTranslation - minTranslation) * vergleichsWertStromTranslationPercentage; + + const pfeilWidth = 20 + const margin = 5; + const adjustY = -210; + const adjustY2 = -198; + + page.drawImage(pfeilNachUnten, { + x: endenergieverbrauchTranslationX, + y: height - 210 + adjustY, + width: pfeilWidth, + height: 30 + }) + + page.drawImage(pfeilNachOben, { + x: vergleichsWertWaermeTranslationX, + y: height - 293 + adjustY, + width: pfeilWidth, + height: 30 + }) + + page.drawText("0", { + x: 85, + y: height - 241 + adjustY, + size: 13, + font: bold + }) + + const vergleichswertWaermeText2 = `${Math.round(berechnungen?.vergleichsWertWaerme).toString()}` + + page.drawText(vergleichswertWaermeText2, { + x: 295, + y: height - 241 + adjustY, + size: 13, + font: bold + }) + + const maxVergleichswertWaermeText = `> ${Math.round(berechnungen?.vergleichsWertWaerme * 2).toString()}`; + + page.drawText(maxVergleichswertWaermeText, { + x: vergleichsWertWaermeTranslationX * 2 - 78, + y: height - 241 + adjustY, + size: 13, + font: bold + }) + + page.drawText("0", { + x: 85, + y: height - 385 + adjustY2, + size: 13, + font: bold + }) + + const vergleichswertStromText2 = `${Math.round(berechnungen?.vergleichsWertStrom).toString()}` + + page.drawText(vergleichswertStromText2, { + x: 295, + y: height - 385 + adjustY2, + size: 13, + font: bold + }) + + const maxVergleichswertStromText = `> ${Math.round(berechnungen?.vergleichsWertStrom * 2).toString()}`; + + page.drawText(maxVergleichswertStromText, { + x: vergleichsWertStromTranslationX * 2 - 78, + y: height - 385 + adjustY2, + size: 13, + font: bold + }) + + const endEnergieVerbrauchGesamtText = `${Math.round(berechnungen?.endEnergieVerbrauchGesamt ?? 0).toString()}kWh/(m²a)`; + + if (endenergieverbrauchTranslationPercentage > 0.5) { + page.drawText("Endenergieverbrauch Wärme", { + x: endenergieverbrauchTranslationX - margin - font.widthOfTextAtSize("Endenergieverbrauch Wärme", 10), + y: height - 191 + adjustY, + size: 10 + }) + + page.drawText(endEnergieVerbrauchGesamtText, { + x: endenergieverbrauchTranslationX - margin - bold.widthOfTextAtSize(endEnergieVerbrauchGesamtText, 10), + y: height - 205 + adjustY, + size: 10, + font: bold + }) + } else { + page.drawText("Endenergieverbrauch Wärme", { + x: endenergieverbrauchTranslationX + pfeilWidth + margin, + y: height - 191 + adjustY, + size: 10 + }) + page.drawText(endEnergieVerbrauchGesamtText, { + x: endenergieverbrauchTranslationX + pfeilWidth + margin, + y: height - 205 + adjustY, + size: 10, + font: bold + }) + } + + const vergleichswertWaermeText = `${Math.round(berechnungen?.vergleichsWertWaerme).toString()}kWh/(m²a)` + + if (vergleichsWertWaermeTranslationPercentage > 0.5) { + page.drawText("Vergleichswert Wärme", { + x: vergleichsWertWaermeTranslationX - margin - font.widthOfTextAtSize("Vergleichswert Wärme", 10), + y: height - 275 + adjustY, + size: 10 + }) + + page.drawText(vergleichswertWaermeText, { + x: vergleichsWertWaermeTranslationX - margin - bold.widthOfTextAtSize(vergleichswertWaermeText, 10), + y: height - 289 + adjustY, + size: 10, + font: bold + }) + } else { + page.drawText("Vergleichswert Wärme", { + x: vergleichsWertWaermeTranslationX + pfeilWidth + margin, + y: height - 275 + adjustY, + size: 10 + }) + page.drawText(vergleichswertWaermeText, { + x: vergleichsWertWaermeTranslationX + pfeilWidth + margin, + y: height - 289 + adjustY, + size: 10, + font: bold + }) + } + + page.drawImage(pfeilNachUnten, { + x: stromVerbrauchTranslationX, + y: height - 354 + adjustY2, + width: pfeilWidth, + height: 30 + }) + + page.drawImage(pfeilNachOben, { + x: vergleichsWertStromTranslationX, + y: height - 437 + adjustY2, + width: pfeilWidth, + height: 30 + }) + + const stromVerbrauchGesamtText = `${Math.round(berechnungen?.endEnergieVerbrauchStrom ?? 0).toString()}kWh/(m²a)`; + + if (stromVerbrauchTranslationPercentage > 0.5) { + page.drawText("Endenergieverbrauch Strom", { + x: stromVerbrauchTranslationX - margin - font.widthOfTextAtSize("Endenergieverbrauch Strom", 10), + y: height - 335 + adjustY2, + size: 10 + }) + + page.drawText(stromVerbrauchGesamtText, { + x: stromVerbrauchTranslationX - margin - bold.widthOfTextAtSize(stromVerbrauchGesamtText, 10), + y: height - 349 + adjustY2, + size: 10, + font: bold + }) + } else { + page.drawText("Endenergieverbrauch Strom", { + x: stromVerbrauchTranslationX + pfeilWidth + margin, + y: height - 335 + adjustY2, + size: 10 + }) + page.drawText(stromVerbrauchGesamtText, { + x: stromVerbrauchTranslationX + pfeilWidth + margin, + y: height - 349 + adjustY2, + size: 10, + font: bold + }) + } + + const vergleichswertStromText = `${Math.round(berechnungen?.vergleichsWertStrom).toString()}kWh/(m²a)` + + + if (vergleichsWertWaermeTranslationPercentage > 0.5) { + page.drawText("Vergleichswert Strom", { + x: vergleichsWertStromTranslationX - margin - font.widthOfTextAtSize("Vergleichswert Strom", 10), + y: height - 420 + adjustY2, + size: 10 + }) + + page.drawText(vergleichswertStromText, { + x: vergleichsWertStromTranslationX - margin - bold.widthOfTextAtSize(vergleichswertStromText, 10), + y: height - 434 + adjustY2, + size: 10, + font: bold + }) + } else { + page.drawText("Vergleichswert Strom", { + x: vergleichsWertStromTranslationX + pfeilWidth + margin, + y: height - 420 + adjustY2, + size: 10 + }) + page.drawText(vergleichswertStromText, { + x: vergleichsWertStromTranslationX + pfeilWidth + margin, + y: height - 434 + adjustY2, + size: 10, + font: bold + }) + } + } + + addEnergieverbrauchSkalaPfeile(pages[0]) + + if (ausweis.warmwasser_enthalten) { + pages[0].drawText("x", { + x: 42, + y: height - 504, + size: 10, + font: bold + }) + } + + if (ausweis.kuehlung_enthalten) { + pages[0].drawText("x", { + x: 42, + y: height - 516, + size: 10, + font: bold + }) + } + + if (ausweis.stromverbrauch_enthaelt_heizung) { + pages[0].drawText("x", { + x: 42, + y: height - 660, + size: 10, + font: bold + }) + } + + if (ausweis.stromverbrauch_enthaelt_warmwasser) { + pages[0].drawText("x", { + x: 132, + y: height - 660, + size: 10, + font: bold + }) + } + + if (ausweis.stromverbrauch_enthaelt_lueftung) { + pages[0].drawText("x", { + x: 219, + y: height - 660, + size: 10, + font: bold + }) + } + + if (ausweis.stromverbrauch_enthaelt_beleuchtung) { + pages[0].drawText("x", { + x: 282, + y: height - 660, + size: 10, + font: bold + }) + } + + if (ausweis.stromverbrauch_enthaelt_kuehlung) { + pages[0].drawText("x", { + x: 423, + y: height - 660, + size: 10, + font: bold + }) + } + + if (ausweis.stromverbrauch_enthaelt_sonstige) { + pages[0].drawText("x", { + x: 493, + y: height - 660, + size: 10, + font: bold + }) + } + + addText(pages[0], berechnungen?.primaerEnergieVerbrauchGesamt.toString() || "", 475, height - 685, 10, font) + addText(pages[0], berechnungen?.co2EmissionenGesamt.toString() || "", 475, height - 705, 10, font) + + // // const primaerenergiebedarfIst = fillFormField("primaerenergiebedarf_ist", berechnungen?.primaerEnergieVerbrauchGesamt.toString()) + + + /* -------------------------------- Seite 3 -------------------------------- */ + + // Verbräuche + + // const addVerbrauchGenerator = () => { + // let i = 0; + // let yOffset = 14.6; + // const initialHeight = 297 + // const initialXOffset = 36; + // 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), + // size: 8, + // font + // }) + + // pages[2].drawText(zeitraum_bis || "", { + // x: initialXOffset + 47, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + + // pages[2].drawText(energietraeger || "", { + // x: initialXOffset + 94, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + + // pages[2].drawText(primaerfaktor || "", { + // x: initialXOffset + 232, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + + // pages[2].drawText(energieverbrauch || "", { + // x: initialXOffset + 275, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + + // pages[2].drawText(anteil_warmwasser || "", { + // 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[0].drawText(anteil_heizung || "", { + // 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, + // font + // }) + // i++; + // } + // } + + // const addVerbrauch = addVerbrauchGenerator(); + + // // Primäre Heizquelle + // addVerbrauch( + // moment(ausweis.startdatum).format("MM.YYYY"), + // moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"), + // ausweis.brennstoff_1 || "", + // berechnungen?.brennstoff_1.primaerenergiefaktor.toString(), + // Math.round(berechnungen?.energieVerbrauchGesamt_1 || 0).toString(), + // Math.round(berechnungen?.energieVerbrauchWarmwasser_1 || 0).toString(), + // berechnungen?.kuehlungsZuschlag_1, + // Math.round(berechnungen?.energieVerbrauchHeizung_1 || 0).toString(), + // berechnungen?.durchschnittsKlimafaktor.toString(), + // berechnungen?.energieVerbrauchStrom + // ); + + + // if (ausweis.zusaetzliche_heizquelle) { + // addVerbrauch( + // moment(ausweis.startdatum).format("MM.YYYY"), + // moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"), + // ausweis.brennstoff_2 || "", + // berechnungen?.brennstoff_2.primaerenergiefaktor.toString(), + // Math.round(berechnungen?.energieVerbrauchGesamt_2 || 0).toString(), + // Math.round(berechnungen?.energieVerbrauchWarmwasser_2 || 0).toString(), + // berechnungen?.kuehlungsZuschlag_2, + // Math.round(berechnungen?.energieVerbrauchHeizung_2 || 0).toString(), + // berechnungen?.durchschnittsKlimafaktor.toString(), + // 0 + // ); + // } + + // if (aufnahme.leerstand && aufnahme.leerstand > 0) { + // /** + // * Leerstandszuschlag + // * @link https://www.bundesanzeiger.de/pub/publication/MRYM4nI84Sdlr0EIvvW?2 + // */ + // if (ausweis.warmwasser_enthalten && ausweis.warmwasser_anteil_bekannt) { + // addVerbrauch( + // moment(ausweis.startdatum).format("MM.YYYY"), + // moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"), + // "Leerstandszuschlag", + // berechnungen?.brennstoff_1.primaerenergiefaktor.toString(), + // Math.round((berechnungen?.leerstandsZuschlagHeizung || 0) + (berechnungen?.leerstandsZuschlagWarmwasser || 0) + (berechnungen?.leerstandsZuschlagKuehlung || 0)).toString(), + // Math.round((berechnungen?.leerstandsZuschlagWarmwasser || 0)).toString(), + // Math.round((berechnungen?.leerstandsZuschlagKuehlung || 0)), + // Math.round((berechnungen?.leerstandsZuschlagHeizung || 0)).toString(), + // berechnungen?.durchschnittsKlimafaktor.toString(), + // Math.round((berechnungen?.leerstandsZuschlagStrom || 0)) + // ); + // } else { + // addVerbrauch( + // moment(ausweis.startdatum).format("MM.YYYY"), + // moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"), + // "Leerstandszuschlag", + // berechnungen?.brennstoff_1.primaerenergiefaktor.toString(), + // Math.round((berechnungen?.leerstandsZuschlagHeizung || 0) + (berechnungen?.leerstandsZuschlagWarmwasser || 0) + (berechnungen?.leerstandsZuschlagKuehlung || 0)).toString(), + // Math.round((berechnungen?.leerstandsZuschlagWarmwasser || 0)).toString(), + // Math.round((berechnungen?.leerstandsZuschlagKuehlung || 0)), + // Math.round((berechnungen?.leerstandsZuschlagHeizung || 0)).toString(), + // berechnungen?.durchschnittsKlimafaktor.toString(), + // Math.round((berechnungen?.leerstandsZuschlagStrom || 0)) + // ); + // } + // } + + // if (aufnahme.kuehlung === "1" && (ausweis.stromverbrauch_enthaelt_kuehlung === false || ausweis.stromverbrauch_enthaelt_kuehlung === null)) { + // /** + // * Kühlungszuschlag - Pauschale Erhöhung um 6kWh/m² + // * Primärenergiefaktor Strom + // * @link https://www.bundesanzeiger.de/pub/publication/MRYM4nI84Sdlr0EIvvW?2 + // */ + // addVerbrauch( + // moment(ausweis.startdatum).format("MM.YYYY"), + // moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"), + // "Kühlungszuschlag", + // "1.8", + // "", + // "", + // 0, + // "", + // "", + // Math.round(berechnungen?.kuehlungsZuschlag || 0) + // ); + // } + + + /* -------------------------------- Seite 4 -------------------------------- */ + + // const splitToSize = (text: string, size: number, font: PDFFont, fontSize: number) => { + // const lines = [] + + // let currentLine = "" + // for (const char of text) { + // if (font.widthOfTextAtSize(currentLine + char, fontSize) <= size) { + // currentLine += char; + // } else { + // lines.push(currentLine) + // currentLine = char; + // } + // } + + // lines.push(currentLine) + + // return lines.join("\n") + // } + + // const addEmpfehlungenGenerator = () => { + // let i = 0; + // let yOffset = 43; + // const initialHeight = 562 + // const initialXOffset = 36; + // return (bauteil?: string, beschreibung?: string, alsEinzelmassnahme?: boolean, amortisationszeit?: string, kosten?: string) => { + // pages[3].drawText((i + 1).toString(), { + // x: initialXOffset, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + + // pages[3].drawText(splitToSize(bauteil || "", 70, font, 8), { + // x: initialXOffset + 25, + // y: initialHeight - (i * yOffset), + // size: 8, + // font, + // lineHeight: 10 + // }) + + // pages[3].drawText(splitToSize(beschreibung || "", 230, font, 8), { + // x: initialXOffset + 98, + // y: initialHeight - (i * yOffset), + // size: 8, + // font, + // lineHeight: 10 + // }) + + + + // pages[3].drawText(amortisationszeit || "", { + // x: initialXOffset + 403, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + + // pages[3].drawText(kosten || "", { + // x: initialXOffset + 451, + // y: initialHeight - (i * yOffset), + // size: 8, + // font + // }) + // i++; + // } + // } + + // const addEmpfehlung = addEmpfehlungenGenerator() + + // for (const empfehlung of empfehlungen) { + // addEmpfehlung(empfehlung.anlagenteil, empfehlung.description, true, empfehlung.amortisationszeit, empfehlung.kosten) + // } + + + for (let i = 0; i < pages.length; i++) { + const page = pages[i]; + if (vorschau) { + addAnsichtsausweisLabel(page, font) + } + addDatumGEG(page, font) + // if (i !== pages.length - 1) { + // addRegistriernummer(page, font, ausweis.registriernummer || "") + // } + } + + + + // pdf.getForm().flatten() + + return pdf.save(); +} \ No newline at end of file diff --git a/src/lib/server/ausweis.ts b/src/lib/server/ausweis.ts index c92676ca..052cc636 100644 --- a/src/lib/server/ausweis.ts +++ b/src/lib/server/ausweis.ts @@ -3,6 +3,7 @@ import { pdfDatenblattVerbrauchsausweisGewerbe } from "#lib/pdf/pdfDatenblattVer import { pdfDatenblattVerbrauchsausweisWohnen } from "#lib/pdf/pdfDatenblattVerbrauchsausweisWohnen.js"; import { pdfVerbrauchsausweisGewerbe } from "#lib/pdf/pdfVerbrauchsausweisGewerbe.js"; import { pdfVerbrauchsausweisWohnen } from "#lib/pdf/pdfVerbrauchsausweisWohnen.js"; +import { pdfAushangVerbrauchsausweisGewerbe } from "#lib/pdf/pdfAushangVerbrauchsausweisGewerbe.js"; import { Enums, prisma, Rechnung } from "#lib/server/prisma.js"; @@ -61,5 +62,21 @@ export async function getDatenblatt(ausweis: VerbrauchsausweisWohnenClient | Ver return await pdfDatenblattVerbrauchsausweisGewerbe(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt, rechnung, bilder) } + return null +} + +/** + * Gibt den richtigen Aushang basierend auf der Ausweisart zurück. + * @param ausweis + */ +export async function getAushang(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, vorschau: boolean = true, rechnung: Rechnung, ausweisart = getAusweisartFromId(ausweis.id)) { + if (!ausweisart || !rechnung.services.includes(Enums.Service.Aushang)) { + return null + } + + if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) { + return await pdfAushangVerbrauchsausweisGewerbe(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt, bilder, user, vorschau) + } + return null } \ No newline at end of file diff --git a/src/pages/api/admin/ausstellen.ts b/src/pages/api/admin/ausstellen.ts index b013bb27..4fddefda 100644 --- a/src/pages/api/admin/ausstellen.ts +++ b/src/pages/api/admin/ausstellen.ts @@ -16,8 +16,9 @@ import { join } from "path" import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { z } from "astro:content"; import { transport } from "#lib/mail.js"; +import { Attachment } from 'nodemailer/lib/mailer'; import { BASE_URI } from "#lib/constants.js"; -import { getAnsichtsausweis, getDatenblatt } from "#lib/server/ausweis.js"; +import { getAnsichtsausweis, getDatenblatt, getAushang } from "#lib/server/ausweis.js"; import { PutObjectCommand } from "@aws-sdk/client-s3"; import { s3Client } from "#lib/s3.js"; import { createInvoice, getLexOfficeRechnung, getLexOfficeVoucherNumber } from "#lib/server/invoice.js"; @@ -29,6 +30,7 @@ import { getVerbrauchsausweisWohnenKomplett, } from "#lib/server/db.js"; import { PDFDocument } from "pdf-lib"; +import * as fs from 'fs'; export const GET = defineApiRoute({ input: z.object({ @@ -143,6 +145,16 @@ export const GET = defineApiRoute({ ausweis.rechnung ); + const pdfAushang = await getAushang( + ausweis, + ausweis.aufnahme, + ausweis.aufnahme.objekt, + ausweis.aufnahme.bilder, + ausweis.aufnahme.objekt.benutzer, + false, + ausweis.rechnung + ); + // TODO: Das ist immer noch scheiße, LexOffice ist doof // Hier müssen wir warten, damit wir sichergehen können, dass die Rechnung bei LexOffice existiert. setTimeout(async () => { @@ -196,6 +208,17 @@ export const GET = defineApiRoute({ await s3Client.send(rechnungsCommand); + if (pdfAushang){ + const aushangCommand = new PutObjectCommand({ + Bucket: "ibc-pdfs", + Key: `ID_${ausweis.id}_Aushang.pdf`, + Body: pdfDatenblatt, + ACL: "private", + }); + + await s3Client.send(rechnungsCommand); + } + // Falls Postversand angefragt wurde müssen wir die Dateien auf den Postserver hochladen if (post) { const dateiNameDruck = `1011000000000-AW_ID_${ausweis.id}.pdf`; @@ -212,6 +235,10 @@ export const GET = defineApiRoute({ await appendPdf(pdfDatenblatt); await appendPdf(pdfAusweis); + + if (pdfAushang){ + await appendPdf(pdfAushang); + } const pdfBytes = await outputPdf.save(); @@ -317,31 +344,43 @@ export const GET = defineApiRoute({

`; } + const attachments: Attachment[] = [ + { + filename: `ID_${ausweis.id}_Energieausweis.pdf`, + encoding: "binary", + content: Buffer.from(pdfAusweis), + contentType: "application/pdf", + }, + { + filename: `ID_${ausweis.id}_Datenblatt.pdf`, + encoding: "binary", + content: Buffer.from(pdfDatenblatt), + contentType: "application/pdf", + }, + { + filename: `ID_${ausweis.id}_Rechnung.pdf`, + encoding: "binary", + content: Buffer.from(pdfRechnung), + contentType: "application/pdf", + } + ]; + + if (pdfAushang) { + attachments.push({ + filename: `ID_${ausweis.id}_Aushang.pdf`, + encoding: "binary", + content: Buffer.from(pdfAushang), + contentType: "application/pdf", + }); + } + await transport.sendMail({ from: `"IBCornelsen" `, to: rechnung.email || rechnung.benutzer.email, bcc: "info@online-energieausweis.org", subject: `Ihr Originalausweis vom Ingenieurbüro Cornelsen (ID: ${ausweis.id})`, html, - attachments: [{ - filename: `ID_${ausweis.id}_Energieausweis.pdf`, - encoding: "binary", - content: Buffer.from(pdfAusweis), - contentType: "application/pdf", - contentDisposition: "attachment", - }, { - filename: `ID_${ausweis.id}_Datenblatt.pdf`, - encoding: "binary", - content: Buffer.from(pdfDatenblatt), - contentType: "application/pdf", - contentDisposition: "attachment", - }, { - filename: `ID_${ausweis.id}_Rechnung.pdf`, - encoding: "binary", - content: Buffer.from(pdfRechnung), - contentType: "application/pdf", - contentDisposition: "attachment", - }] + attachments }); if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {