Ausweis und weitere Änderungen
This commit is contained in:
4
bun.lock
4
bun.lock
@@ -30,6 +30,7 @@
|
|||||||
"js-interpolate": "^1.3.2",
|
"js-interpolate": "^1.3.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"moment-timezone": "^0.5.46",
|
"moment-timezone": "^0.5.46",
|
||||||
"nodemailer": "^6.10.0",
|
"nodemailer": "^6.10.0",
|
||||||
@@ -56,6 +57,7 @@
|
|||||||
"@types/is-base64": "^1.1.3",
|
"@types/is-base64": "^1.1.3",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/jsonwebtoken": "^9.0.7",
|
"@types/jsonwebtoken": "^9.0.7",
|
||||||
|
"@types/mime-types": "^2.1.4",
|
||||||
"@types/nodemailer": "^6.4.17",
|
"@types/nodemailer": "^6.4.17",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||||
@@ -540,6 +542,8 @@
|
|||||||
|
|
||||||
"@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
|
"@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
|
||||||
|
|
||||||
|
"@types/mime-types": ["@types/mime-types@2.1.4", "", {}, "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w=="],
|
||||||
|
|
||||||
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
||||||
|
|
||||||
"@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="],
|
"@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="],
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
"js-interpolate": "^1.3.2",
|
"js-interpolate": "^1.3.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"moment-timezone": "^0.5.46",
|
"moment-timezone": "^0.5.46",
|
||||||
"nodemailer": "^6.10.0",
|
"nodemailer": "^6.10.0",
|
||||||
@@ -70,6 +71,7 @@
|
|||||||
"@types/is-base64": "^1.1.3",
|
"@types/is-base64": "^1.1.3",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
"@types/jsonwebtoken": "^9.0.7",
|
"@types/jsonwebtoken": "^9.0.7",
|
||||||
|
"@types/mime-types": "^2.1.4",
|
||||||
"@types/nodemailer": "^6.4.17",
|
"@types/nodemailer": "^6.4.17",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||||
|
|||||||
@@ -5,22 +5,26 @@ export const createCaller = createCallerFactory({
|
|||||||
"postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"),
|
"postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"),
|
||||||
"aufnahme/[uid]": await import("../src/pages/api/aufnahme/[uid].ts"),
|
"aufnahme/[uid]": await import("../src/pages/api/aufnahme/[uid].ts"),
|
||||||
"aufnahme": await import("../src/pages/api/aufnahme/index.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/access-token": await import("../src/pages/api/auth/access-token.ts"),
|
||||||
"auth/forgot-password": await import("../src/pages/api/auth/forgot-password.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"),
|
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
|
||||||
"bilder/[uid]": await import("../src/pages/api/bilder/[uid].ts"),
|
|
||||||
"bedarfsausweis-wohnen/[uid]": await import("../src/pages/api/bedarfsausweis-wohnen/[uid].ts"),
|
"bedarfsausweis-wohnen/[uid]": await import("../src/pages/api/bedarfsausweis-wohnen/[uid].ts"),
|
||||||
"bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"),
|
"bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.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"),
|
"objekt": await import("../src/pages/api/objekt/index.ts"),
|
||||||
"rechnung": await import("../src/pages/api/rechnung/index.ts"),
|
|
||||||
"ticket": await import("../src/pages/api/ticket/index.ts"),
|
"ticket": await import("../src/pages/api/ticket/index.ts"),
|
||||||
|
"rechnung": await import("../src/pages/api/rechnung/index.ts"),
|
||||||
"user": await import("../src/pages/api/user/index.ts"),
|
"user": await import("../src/pages/api/user/index.ts"),
|
||||||
"user/self": await import("../src/pages/api/user/self.ts"),
|
"user/self": await import("../src/pages/api/user/self.ts"),
|
||||||
"verbrauchsausweis-gewerbe/[uid]": await import("../src/pages/api/verbrauchsausweis-gewerbe/[uid].ts"),
|
"verbrauchsausweis-gewerbe/[uid]": await import("../src/pages/api/verbrauchsausweis-gewerbe/[uid].ts"),
|
||||||
"verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.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/[uid]": await import("../src/pages/api/verbrauchsausweis-wohnen/[uid].ts"),
|
||||||
"verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"),
|
"verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"),
|
||||||
"webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"),
|
|
||||||
"objekt/[uid]/bilder": await import("../src/pages/api/objekt/[uid]/bilder.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]": await import("../src/pages/api/objekt/[uid]/index.ts"),
|
||||||
|
"objekt/[uid]/unterlagen": await import("../src/pages/api/objekt/[uid]/unterlagen.ts"),
|
||||||
})
|
})
|
||||||
@@ -72,7 +72,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
>
|
>
|
||||||
<option disabled selected>Bitte auswählen</option>
|
<option disabled selected>Bitte auswählen</option>
|
||||||
|
|
||||||
{#if ausweisart=="VerbrauchsausweisWohnen"}
|
{#if ausweisart==Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisVerbrauchsausweisWohnen}
|
||||||
<option value="Einfamilienhaus">Einfamilienhaus</option>
|
<option value="Einfamilienhaus">Einfamilienhaus</option>
|
||||||
<option value="Freistehendes Einfamilienhaus">Freistehendes Einfamilienhaus</option>
|
<option value="Freistehendes Einfamilienhaus">Freistehendes Einfamilienhaus</option>
|
||||||
<option value="Freistehendes Zweifamilienhaus">Freistehendes Zweifamilienhaus</option>
|
<option value="Freistehendes Zweifamilienhaus">Freistehendes Zweifamilienhaus</option>
|
||||||
@@ -84,7 +84,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
<option value="Atrium-Bungalow">Atrium-Bungalow</option>
|
<option value="Atrium-Bungalow">Atrium-Bungalow</option>
|
||||||
<option value="Winkelbungalow">Winkelbungalow</option>
|
<option value="Winkelbungalow">Winkelbungalow</option>
|
||||||
|
|
||||||
{:else if ausweisart=="VerbrauchsausweisGewerbe"}
|
{:else if ausweisart==Enums.Ausweisart.VerbrauchsausweisGewerbe}
|
||||||
<option value="Verwaltungsgebäude (allgemein)">Verwaltungsgebäude (allgemein)</option>
|
<option value="Verwaltungsgebäude (allgemein)">Verwaltungsgebäude (allgemein)</option>
|
||||||
<option value="Parlaments- und Gerichtsgebäude">Parlaments- und Gerichtsgebäude</option>
|
<option value="Parlaments- und Gerichtsgebäude">Parlaments- und Gerichtsgebäude</option>
|
||||||
<option value="Ministerien u. Ämter u. Behörden">Ministerien u. Ämter u. Behörden</option>
|
<option value="Ministerien u. Ämter u. Behörden">Ministerien u. Ämter u. Behörden</option>
|
||||||
@@ -200,7 +200,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
|
|||||||
className={auditHeizungGebaeudeBaujahr(aufnahme)
|
className={auditHeizungGebaeudeBaujahr(aufnahme)
|
||||||
? "linked"
|
? "linked"
|
||||||
: ""}
|
: ""}
|
||||||
bind:tags={aufnahme.baujahr_heizung}
|
bind:tags={aufnahme.baujahr_klima}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="help-label">
|
<div class="help-label">
|
||||||
|
|||||||
@@ -1,45 +1,49 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let progress: number = 0;
|
export let progress: number = 0;
|
||||||
export let step1: string = '';
|
export let steps: string[] = [
|
||||||
export let step2: string = '';
|
"Gebäudedaten",
|
||||||
export let step3: string = '';
|
"Kundendaten",
|
||||||
|
"Kaufbestätigung",
|
||||||
|
];
|
||||||
|
export let active: number;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-3 self-start justify-between">
|
||||||
|
|
||||||
<div class="grid grid-cols-3 self-start">
|
|
||||||
|
|
||||||
<div class="col-span-3 relative">
|
<div class="col-span-3 relative">
|
||||||
|
<div
|
||||||
<div class="w-[calc(100%-5rem)] ml-[2.5rem] absolute mt-[0.5rem] bg-gray-200 h-3 rounded-lg">
|
class="w-[calc(100%-5rem)] ml-[2.5rem] absolute mt-[0.5rem] bg-gray-200 h-3 rounded-lg"
|
||||||
<div class="bg-green-600 left-0 h-3 absolute" style={`width: ${progress}%;`}></div>
|
>
|
||||||
|
<div
|
||||||
|
class="bg-green-600 left-0 h-3 absolute"
|
||||||
|
style={`width: ${progress}%;`}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#each steps as step, i}
|
||||||
|
<div class="phase">
|
||||||
|
<div class="point" class:active={i === active}>{i + 1}</div>
|
||||||
|
<div>{step}</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/each}
|
||||||
<div class="phase justify-self-start">
|
|
||||||
<div class="{step1} point">1</div>
|
|
||||||
<div class="">Gebäudedaten</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="phase">
|
|
||||||
<div class="{step2} point">2</div>
|
|
||||||
<div class="">Kundendaten</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="phase justify-self-end">
|
|
||||||
<div class="{step3} point">3</div>
|
|
||||||
<div class="">Kaufbestätigung</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.phase{@apply grid grid-cols-1 items-center justify-items-center z-10;
|
.phase {
|
||||||
.point{@apply rounded-full w-8 h-8 text-white font-bold bg-gray-300 text-center pt-1 ring-white ring-4;}
|
@apply grid grid-cols-1 items-center justify-items-center z-10;
|
||||||
.step{@apply bg-secondary}
|
.point {
|
||||||
}
|
@apply rounded-full w-8 h-8 text-white font-bold bg-gray-300 text-center pt-1 ring-white ring-4;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
@apply bg-secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(1 of .phase) {
|
||||||
|
@apply justify-self-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phase:last-of-type {
|
||||||
|
@apply justify-self-end;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Objekt,
|
Objekt,
|
||||||
Rechnung,
|
Rechnung,
|
||||||
Tickets,
|
Tickets,
|
||||||
|
Unterlage,
|
||||||
VerbrauchsausweisGewerbe,
|
VerbrauchsausweisGewerbe,
|
||||||
VerbrauchsausweisWohnen,
|
VerbrauchsausweisWohnen,
|
||||||
} from "@ibcornelsen/database/client";
|
} from "@ibcornelsen/database/client";
|
||||||
@@ -148,3 +149,5 @@ export function getAusweisartFromUUID(uid: string): Enums.Ausweisart | null {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UnterlageClient = Omit<Unterlage, "id" | "objekt_id">
|
||||||
@@ -13,6 +13,10 @@
|
|||||||
import { CheckCircled, CrossCircled, Image } from "radix-svelte-icons";
|
import { CheckCircled, CrossCircled, Image } from "radix-svelte-icons";
|
||||||
import ChevronDown from "radix-svelte-icons/src/lib/icons/ChevronDown.svelte";
|
import ChevronDown from "radix-svelte-icons/src/lib/icons/ChevronDown.svelte";
|
||||||
import { Event } from "@ibcornelsen/database/client";
|
import { Event } from "@ibcornelsen/database/client";
|
||||||
|
import { api } from "astro-typesafe-api/client";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
|
||||||
|
import NotificationWrapper from "./Notifications/NotificationWrapper.svelte";
|
||||||
|
|
||||||
|
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
@@ -24,6 +28,25 @@
|
|||||||
ReturnType<typeof endEnergieVerbrauchVerbrauchsausweis_2016>
|
ReturnType<typeof endEnergieVerbrauchVerbrauchsausweis_2016>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
async function ausweisAusstellen(uid: string) {
|
||||||
|
try {
|
||||||
|
await api.admin.ausstellen.GET.fetch({
|
||||||
|
uid
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch(e) {
|
||||||
|
addNotification({
|
||||||
|
title: "Das hat nicht geklappt.",
|
||||||
|
description: e.cause.statusText,
|
||||||
|
timeout: 3000,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ausweisArt = getAusweisartFromUUID(ausweis.uid) // TODO: Das ist ein Platzhalter, hier muss die Ausweisart aus dem Ausweisobjekt kommen
|
const ausweisArt = getAusweisartFromUUID(ausweis.uid) // TODO: Das ist ein Platzhalter, hier muss die Ausweisart aus dem Ausweisobjekt kommen
|
||||||
@@ -449,8 +472,8 @@
|
|||||||
let infoVisible = false;
|
let infoVisible = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="border rounded-box">
|
<div class="border rounded-lg bg-base-200">
|
||||||
<table class="table table-row">
|
<table class="">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><button on:click={() => infoVisible = !infoVisible}><ChevronDown size={22} class="transition-all {infoVisible ? "" : "rotate-180"}"></ChevronDown></button></td>
|
<td><button on:click={() => infoVisible = !infoVisible}><ChevronDown size={22} class="transition-all {infoVisible ? "" : "rotate-180"}"></ChevronDown></button></td>
|
||||||
@@ -676,12 +699,12 @@
|
|||||||
<td title="Gebäudebilder anzeigen"
|
<td title="Gebäudebilder anzeigen"
|
||||||
><!-- Open the modal using ID.showModal() method -->
|
><!-- Open the modal using ID.showModal() method -->
|
||||||
<button class="btn btn-square" on:click={() => bilderModal.showModal()}><Image size={22}></Image></button>
|
<button class="btn btn-square" on:click={() => bilderModal.showModal()}><Image size={22}></Image></button>
|
||||||
<dialog bind:this={bilderModal} class="modal">
|
<dialog bind:this={bilderModal} class="modal p-4 rounded-lg">
|
||||||
<div class="modal-box flex flex-row gap-4 items-center justify-center">
|
<div class="modal-box flex flex-row gap-4 items-center justify-center">
|
||||||
{#if bilder.length === 0}
|
{#if bilder.length === 0}
|
||||||
<div class="flex flex-col gap-4 items-center justify-center">
|
<div class="flex flex-col gap-4 items-center justify-center">
|
||||||
<p>Für diesen Ausweis sind noch keine Bilder vorhanden.</p>
|
<p>Für diesen Ausweis sind noch keine Bilder vorhanden.</p>
|
||||||
<button class="btn btn-primary" tabindex="0">Erinnerung Verschicken</button>
|
<button class="button" tabindex="0">Erinnerung Verschicken</button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
{#each bilder as image}
|
{#each bilder as image}
|
||||||
@@ -693,7 +716,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<form method="dialog" class="modal-backdrop">
|
<form method="dialog" class="modal-backdrop">
|
||||||
<button>close</button>
|
<button class="button">Close</button>
|
||||||
</form>
|
</form>
|
||||||
</dialog></td
|
</dialog></td
|
||||||
>
|
>
|
||||||
@@ -874,3 +897,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<NotificationWrapper></NotificationWrapper>
|
||||||
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="dropdown dropdown-hover dropdown-bottom">
|
<div class="relative group border-r px-2">
|
||||||
<div role="button" tabindex="0">
|
<div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-content bg-gray-700 text-white z-10 menu w-max shadow rounded-lg">
|
|
||||||
|
<div class="absolute right-[50%] translate-x-[50%] z-10 mt-2 p-2 w-max origin-top-right rounded-md bg-gray-700 text-white ring-1 shadow-lg ring-black/5 focus:outline-hidden bg-grey-200 hidden group-hover:block">
|
||||||
<slot name="tooltip"></slot>
|
<slot name="tooltip"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
133
src/components/FileGrid.svelte
Normal file
133
src/components/FileGrid.svelte
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { BedarfsausweisWohnenClient, ObjektClient, UnterlageClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js";
|
||||||
|
import { Trash, Upload } from "radix-svelte-icons";
|
||||||
|
import HelpLabel from "#components/labels/HelpLabel.svelte";
|
||||||
|
|
||||||
|
export let kategorie: string = "";
|
||||||
|
export let files: (UnterlageClient & { data: string | ArrayBuffer })[] = [];
|
||||||
|
export let max: number = Infinity;
|
||||||
|
export let min: number = 1;
|
||||||
|
export let name: string = "";
|
||||||
|
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
|
||||||
|
export let objekt: ObjektClient;
|
||||||
|
import mime from "mime-types";
|
||||||
|
|
||||||
|
|
||||||
|
function getAllFiles(this: HTMLInputElement) {
|
||||||
|
const fileArray = this.files || [];
|
||||||
|
|
||||||
|
if (fileArray.length == max) {
|
||||||
|
this.value = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < fileArray.length; i++) {
|
||||||
|
const file = fileArray[i];
|
||||||
|
|
||||||
|
if (i == max) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = () => {
|
||||||
|
if (reader.readyState != reader.DONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader.result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mimeType = mime.types[file.name.split(".").pop() as string]
|
||||||
|
|
||||||
|
files.push({ data: reader.result, kategorie, name: file.name, mime: mimeType });
|
||||||
|
files = files;
|
||||||
|
|
||||||
|
|
||||||
|
if (i == (Math.min(fileArray.length, max) - 1)) {
|
||||||
|
this.value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileUpload: HTMLInputElement;
|
||||||
|
|
||||||
|
export const upload = () => {
|
||||||
|
fileUpload.click()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<!-- Falls die maximale Anzahl Dokumente erreicht wurde grauen wir den input aus und zeigen einen Hilfstext -->
|
||||||
|
{#if files.filter((file) => file.kategorie === kategorie).length === max}
|
||||||
|
<span class="bg-base-200 border px-4 py-2">Maximale Anzahl Dokumente wurde erreicht.</span>
|
||||||
|
{:else if max > 1}
|
||||||
|
<div class="input-standard">
|
||||||
|
<input type="file" class="file-input file-input-ghost h-[38px]" bind:this={fileUpload} {name} multiple on:change={getAllFiles} />
|
||||||
|
<div class="help-label">
|
||||||
|
<HelpLabel>
|
||||||
|
<slot />
|
||||||
|
</HelpLabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="input-standard">
|
||||||
|
<input type="file" class="file-input file-input-ghost h-[38px]" bind:this={fileUpload} {name} on:change={getAllFiles} />
|
||||||
|
<div class="help-label">
|
||||||
|
<HelpLabel>
|
||||||
|
<slot />
|
||||||
|
</HelpLabel>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<div class="grid grid-cols-2 gap-2">
|
||||||
|
{#each files as file, i}
|
||||||
|
{#if file.kategorie == kategorie}
|
||||||
|
<div class="relative group">
|
||||||
|
<div
|
||||||
|
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all text-center items-center flex p-4 text-opacity-75 text-black"
|
||||||
|
>{file.name}</div>
|
||||||
|
<div class="invisible group-hover:visible absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-row gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="rounded-full w-[30px] h-[30px] flex items-center justify-center p-0 bg-[rgba(0,0,0,0.4)]"
|
||||||
|
on:click={() => {
|
||||||
|
delete files[i];
|
||||||
|
files = files.filter((x) => x);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Trash size={20} color="#fff"></Trash>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<!-- Wir zeigen Platzhalter an, damit der Nutzer sieht wie viele Bilder er hochladen soll -->
|
||||||
|
{#each { length: Math.max(0, Math.min(max, 4) - files.filter(image => image.kategorie === kategorie).length) } as _, i}
|
||||||
|
<div class="relative group">
|
||||||
|
<img
|
||||||
|
src="/placeholder.png"
|
||||||
|
alt={kategorie}
|
||||||
|
class="h-full max-h-32 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all"
|
||||||
|
class:opacity-35={i >= min}
|
||||||
|
/>
|
||||||
|
<div class="invisible group-hover:visible absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-row gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="rounded-full w-[30px] h-[30px] flex items-center justify-center p-0 bg-[rgba(0,0,0,0.4)]"
|
||||||
|
on:click={upload}
|
||||||
|
>
|
||||||
|
<Upload size={20} color="#fff"></Upload>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
import { RotateCounterClockwise, Trash, Upload } from "radix-svelte-icons";
|
import { RotateCounterClockwise, Trash, Upload } from "radix-svelte-icons";
|
||||||
|
|
||||||
export let images: UploadedGebaeudeBild[] = [];
|
export let images: UploadedGebaeudeBild[] = [];
|
||||||
export let max: number = 4;
|
export let max: number = Infinity;
|
||||||
export let min: number = 1;
|
export let min: number = 1;
|
||||||
export let name: string = "";
|
export let name: string = "";
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<!-- Wir zeigen Platzhalter an, damit der Nutzer sieht wie viele Bilder er hochladen soll -->
|
<!-- Wir zeigen Platzhalter an, damit der Nutzer sieht wie viele Bilder er hochladen soll -->
|
||||||
{#each { length: max - images.filter(image => image.kategorie === kategorie).length } as _, i}
|
{#each { length: Math.max(0, Math.min(max, 4) - images.filter(image => image.kategorie === kategorie).length) } as _, i}
|
||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<img
|
<img
|
||||||
src="/placeholder.png"
|
src="/placeholder.png"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import "../style/global.css";
|
import "../style/global.css";
|
||||||
import "../style/formular.css";
|
import "../style/formular.css";
|
||||||
import "../../svelte-dialogs.config"
|
import "../../svelte-dialogs.config";
|
||||||
import Header from "#components/design/header/AusweisHeader.astro";
|
import Header from "#components/design/header/AusweisHeader.astro";
|
||||||
import Footer from "#components/design/footer/Footer.astro";
|
import Footer from "#components/design/footer/Footer.astro";
|
||||||
import SidebarLeft from "#components/design/sidebars/SidebarLeft.astro";
|
import SidebarLeft from "#components/design/sidebars/SidebarLeft.astro";
|
||||||
@@ -13,52 +13,59 @@ export interface Props {
|
|||||||
|
|
||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
---
|
---
|
||||||
<script>
|
|
||||||
window.addEventListener("scroll", (event) => {
|
|
||||||
let scroll = window.scrollY;
|
|
||||||
const skala = document.getElementById("skala")
|
|
||||||
|
|
||||||
if(scroll>=400){
|
<script>
|
||||||
|
const skala = document.getElementById("skala");
|
||||||
|
|
||||||
|
if (!skala?.classList.contains("no-scroll")) {
|
||||||
|
window.addEventListener("scroll", (event) => {
|
||||||
|
let scroll = window.scrollY;
|
||||||
|
if (scroll >= 400) {
|
||||||
if (skala) {
|
if (skala) {
|
||||||
skala.classList.add('2xl:fixed','2xl:py-4','2xl:top-0','2xl:z-20');
|
skala.classList.add(
|
||||||
skala.classList.remove('w-full');
|
"2xl:fixed",
|
||||||
|
"2xl:py-4",
|
||||||
|
"2xl:top-0",
|
||||||
|
"2xl:z-20"
|
||||||
|
);
|
||||||
|
skala.classList.remove("w-full");
|
||||||
skala.style.borderBottom = "3px solid #e6e6e6";
|
skala.style.borderBottom = "3px solid #e6e6e6";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const performanceBox =
|
||||||
const performanceBox = document.getElementById('performance-box')
|
document.getElementById("performance-box");
|
||||||
if (performanceBox) {
|
if (performanceBox) {
|
||||||
performanceBox.style.maxWidth = "688.5px";
|
performanceBox.style.maxWidth = "688.5px";
|
||||||
}
|
}
|
||||||
const progressBox = document.getElementById('progress-box');
|
const progressBox = document.getElementById("progress-box");
|
||||||
|
|
||||||
if (progressBox) {
|
if (progressBox) {
|
||||||
progressBox.style.maxWidth = "688.5px"
|
progressBox.style.maxWidth = "688.5px";
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('formInput-1')?.classList.add('2xl:mt-[370px]');
|
document
|
||||||
|
.getElementById("formInput-1")
|
||||||
|
?.classList.add("2xl:mt-[370px]");
|
||||||
|
} else {
|
||||||
|
|
||||||
}else{
|
|
||||||
if (skala) {
|
if (skala) {
|
||||||
skala.classList.remove('2xl:fixed','2xl:py-4','2xl:top-0','2xl:z-20')
|
skala.classList.remove(
|
||||||
skala.classList.add('w-full')
|
"2xl:fixed",
|
||||||
|
"2xl:py-4",
|
||||||
|
"2xl:top-0",
|
||||||
|
"2xl:z-20"
|
||||||
|
);
|
||||||
|
skala.classList.add("w-full");
|
||||||
skala.style.borderBottom = "none";
|
skala.style.borderBottom = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document
|
||||||
document.getElementById('formInput-1')?.classList.remove('2xl:mt-[370px]');
|
.getElementById("formInput-1")
|
||||||
|
?.classList.remove("2xl:mt-[370px]");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
@@ -82,7 +89,10 @@ window.addEventListener("scroll", (event) => {
|
|||||||
content="✅ Jetzt Ihren Energieausweis online erstellen. Erhalten Sie Ihren online Energieausweis rechtssicher und nach aktueller GEG (vormals EnEV) vom Diplom Ingenieur geprüft."
|
content="✅ Jetzt Ihren Energieausweis online erstellen. Erhalten Sie Ihren online Energieausweis rechtssicher und nach aktueller GEG (vormals EnEV) vom Diplom Ingenieur geprüft."
|
||||||
/>
|
/>
|
||||||
<meta property="og:url" content="https://online-energieausweis.org/" />
|
<meta property="og:url" content="https://online-energieausweis.org/" />
|
||||||
<meta property="og:site_name" content="Energieausweis online erstellen" />
|
<meta
|
||||||
|
property="og:site_name"
|
||||||
|
content="Energieausweis online erstellen"
|
||||||
|
/>
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta
|
<meta
|
||||||
@@ -98,12 +108,11 @@ window.addEventListener("scroll", (event) => {
|
|||||||
content="https://online-energieausweis.org/images/energieausweis-online-erstellen.jpg"
|
content="https://online-energieausweis.org/images/energieausweis-online-erstellen.jpg"
|
||||||
/>
|
/>
|
||||||
<title>
|
<title>
|
||||||
{title || 'Energieausweis online erstellen - Online Energieausweis'}
|
{title || "Energieausweis online erstellen - Online Energieausweis"}
|
||||||
</title>
|
</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<main
|
<main
|
||||||
@@ -113,20 +122,17 @@ window.addEventListener("scroll", (event) => {
|
|||||||
md:grid-cols-[minmax(1fr,1fr)] md:gap-2 md:p-0
|
md:grid-cols-[minmax(1fr,1fr)] md:gap-2 md:p-0
|
||||||
lg:grid-cols-[minmax(250px,250px)1fr] lg:gap-3 lg:p-4
|
lg:grid-cols-[minmax(250px,250px)1fr] lg:gap-3 lg:p-4
|
||||||
xl:grid-cols-[minmax(350px,350px)1fr] xl:gap-4 xl:p-6
|
xl:grid-cols-[minmax(350px,350px)1fr] xl:gap-4 xl:p-6
|
||||||
2xl:grid-cols-[minmax(300px,300px)1fr] 2xl:gap-5 2xl:p-6
|
2xl:grid-cols-[minmax(300px,300px)1fr] 2xl:gap-5 2xl:p-6"
|
||||||
">
|
>
|
||||||
|
|
||||||
<SidebarLeft />
|
<SidebarLeft />
|
||||||
|
|
||||||
<article class="box rounded-tl-none p-2 lg:p-12">
|
<article class="box rounded-tl-none p-2 lg:p-12">
|
||||||
<slot />
|
<slot />
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
<NotificationWrapper client:load />
|
<NotificationWrapper client:load />
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -98,24 +98,17 @@ export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis:
|
|||||||
|
|
||||||
// Endenergieverbrauch
|
// Endenergieverbrauch
|
||||||
// Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden.
|
// Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden.
|
||||||
let umrechnungsfaktor = 1, primaerfaktor = 1, coe = 1;
|
let brennstoff_1 = { coe: 0, energietraeger: "", einheit: "", umrechnungsfaktor: 0, primaerenergiefaktor: 0 }, brennstoff_2 = { coe: 0, energietraeger: "", einheit: "", umrechnungsfaktor: 0, primaerenergiefaktor: 0 };
|
||||||
let umrechnungsfaktor_1 = 1, primaerfaktor_1 = 1, coe_1 = 1;
|
|
||||||
if (ausweis.brennstoff_1 && ausweis.einheit_1) {
|
if (ausweis.brennstoff_1 && ausweis.einheit_1) {
|
||||||
let result = getHeizwertfaktor(ausweis.brennstoff_1, ausweis.einheit_1);
|
brennstoff_1 = getHeizwertfaktor(ausweis.brennstoff_1, ausweis.einheit_1);
|
||||||
umrechnungsfaktor = result.umrechnungsfaktor
|
|
||||||
primaerfaktor = result.primaerenergiefaktor
|
|
||||||
coe = result.coe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ausweis.brennstoff_2 && ausweis.einheit_2) {
|
if (ausweis.brennstoff_2 && ausweis.einheit_2) {
|
||||||
let result = getHeizwertfaktor(ausweis.brennstoff_2, ausweis.einheit_2);
|
brennstoff_2 = getHeizwertfaktor(ausweis.brennstoff_2, ausweis.einheit_2);
|
||||||
umrechnungsfaktor_1 = result.umrechnungsfaktor
|
|
||||||
primaerfaktor_1 = result.primaerenergiefaktor
|
|
||||||
coe_1 = result.coe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let energieVerbrauchGesamt_1 = ((ausweis.verbrauch_1 || 0) + (ausweis.verbrauch_2 || 0) + (ausweis.verbrauch_3 || 0)) * umrechnungsfaktor;
|
let energieVerbrauchGesamt_1 = ((ausweis.verbrauch_1 || 0) + (ausweis.verbrauch_2 || 0) + (ausweis.verbrauch_3 || 0)) * brennstoff_1?.umrechnungsfaktor;
|
||||||
let energieVerbrauchGesamt_2 = ((ausweis.verbrauch_4 || 0) + (ausweis.verbrauch_5 || 0) + (ausweis.verbrauch_6 || 0)) * umrechnungsfaktor_1;
|
let energieVerbrauchGesamt_2 = ((ausweis.verbrauch_4 || 0) + (ausweis.verbrauch_5 || 0) + (ausweis.verbrauch_6 || 0)) * brennstoff_2?.umrechnungsfaktor;
|
||||||
|
|
||||||
let energieVerbrauchWarmwasser_1 = 0;
|
let energieVerbrauchWarmwasser_1 = 0;
|
||||||
let energieVerbrauchWarmwasser_2 = 0;
|
let energieVerbrauchWarmwasser_2 = 0;
|
||||||
@@ -180,7 +173,7 @@ export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis:
|
|||||||
let endEnergieVerbrauch_1 = (energieVerbrauchHeizungBereinigt_1 + energieVerbrauchWarmwasser_1 + kuehlungsZuschlag_1) / (3 * nutzflaeche);
|
let endEnergieVerbrauch_1 = (energieVerbrauchHeizungBereinigt_1 + energieVerbrauchWarmwasser_1 + kuehlungsZuschlag_1) / (3 * nutzflaeche);
|
||||||
let endEnergieVerbrauch_2 = (energieVerbrauchHeizungBereinigt_2 + energieVerbrauchWarmwasser_2 + kuehlungsZuschlag_2) / (3 * nutzflaeche);
|
let endEnergieVerbrauch_2 = (energieVerbrauchHeizungBereinigt_2 + energieVerbrauchWarmwasser_2 + kuehlungsZuschlag_2) / (3 * nutzflaeche);
|
||||||
|
|
||||||
let energieVerbrauchStrom = ausweis.strom_1 + ausweis.strom_2 + ausweis.strom_3;
|
let energieVerbrauchStrom = (ausweis.strom_1 || 0) + (ausweis.strom_2 || 0) + (ausweis.strom_3 || 0);
|
||||||
let leerstandsZuschlagStrom = leerstand * energieVerbrauchStrom;
|
let leerstandsZuschlagStrom = leerstand * energieVerbrauchStrom;
|
||||||
|
|
||||||
let endEnergieVerbrauchStrom = (energieVerbrauchStrom + leerstandsZuschlagStrom) / (3 * nutzflaeche);
|
let endEnergieVerbrauchStrom = (energieVerbrauchStrom + leerstandsZuschlagStrom) / (3 * nutzflaeche);
|
||||||
@@ -192,19 +185,19 @@ export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis:
|
|||||||
let endEnergieVerbrauchKuehlungsZuschlag_1 = kuehlungsZuschlag_1 / (3 * nutzflaeche);
|
let endEnergieVerbrauchKuehlungsZuschlag_1 = kuehlungsZuschlag_1 / (3 * nutzflaeche);
|
||||||
let endEnergieVerbrauchKuehlungsZuschlag_2 = kuehlungsZuschlag_2 / (3 * nutzflaeche);
|
let endEnergieVerbrauchKuehlungsZuschlag_2 = kuehlungsZuschlag_2 / (3 * nutzflaeche);
|
||||||
|
|
||||||
let primaerEnergieVerbrauch_1 = endEnergieVerbrauch_1 * primaerfaktor;
|
let primaerEnergieVerbrauch_1 = endEnergieVerbrauch_1 * brennstoff_1.primaerenergiefaktor;
|
||||||
let primaerEnergieVerbrauch_2 = endEnergieVerbrauch_2 * primaerfaktor_1;
|
let primaerEnergieVerbrauch_2 = endEnergieVerbrauch_2 * brennstoff_2.primaerenergiefaktor;
|
||||||
|
|
||||||
let primaerEnergieVerbrauchLeerstandsZuschlag = endEnergieVerbrauchLeerstandsZuschlag * primaerfaktor;
|
let primaerEnergieVerbrauchLeerstandsZuschlag = endEnergieVerbrauchLeerstandsZuschlag * brennstoff_1.primaerenergiefaktor;
|
||||||
let primaerEnergieVerbrauchKuehlungsZuschlag_1 = endEnergieVerbrauchKuehlungsZuschlag_1 * primaerfaktor;
|
let primaerEnergieVerbrauchKuehlungsZuschlag_1 = endEnergieVerbrauchKuehlungsZuschlag_1 * brennstoff_1.primaerenergiefaktor;
|
||||||
let primaerEnergieVerbrauchKuehlungsZuschlag_2 = endEnergieVerbrauchKuehlungsZuschlag_2 * primaerfaktor_1;
|
let primaerEnergieVerbrauchKuehlungsZuschlag_2 = endEnergieVerbrauchKuehlungsZuschlag_2 * brennstoff_2.primaerenergiefaktor;
|
||||||
|
|
||||||
let co2Emissionen_1 = endEnergieVerbrauch_1 * coe;
|
let co2Emissionen_1 = endEnergieVerbrauch_1 * brennstoff_1.coe;
|
||||||
let co2Emissionen_2 = endEnergieVerbrauch_2 * coe_1;
|
let co2Emissionen_2 = endEnergieVerbrauch_2 * brennstoff_2.coe;
|
||||||
|
|
||||||
let co2EmissionenLeerstandsZuschlag = endEnergieVerbrauchLeerstandsZuschlag * coe;
|
let co2EmissionenLeerstandsZuschlag = endEnergieVerbrauchLeerstandsZuschlag * brennstoff_1.coe;
|
||||||
let co2EmissionenKuehlungsZuschlag_1 = endEnergieVerbrauchKuehlungsZuschlag_1 * coe;
|
let co2EmissionenKuehlungsZuschlag_1 = endEnergieVerbrauchKuehlungsZuschlag_1 * brennstoff_1.coe;
|
||||||
let co2EmissionenKuehlungsZuschlag_2 = endEnergieVerbrauchKuehlungsZuschlag_2 * coe_1;
|
let co2EmissionenKuehlungsZuschlag_2 = endEnergieVerbrauchKuehlungsZuschlag_2 * brennstoff_2.coe;
|
||||||
|
|
||||||
let endEnergieVerbrauchGesamt = endEnergieVerbrauch_1 + endEnergieVerbrauch_2 + endEnergieVerbrauchLeerstandsZuschlag;
|
let endEnergieVerbrauchGesamt = endEnergieVerbrauch_1 + endEnergieVerbrauch_2 + endEnergieVerbrauchLeerstandsZuschlag;
|
||||||
let primaerEnergieVerbrauchGesamt = primaerEnergieVerbrauch_1 + primaerEnergieVerbrauch_2 + primaerEnergieVerbrauchLeerstandsZuschlag + primaerEnergieVerbrauchStrom;
|
let primaerEnergieVerbrauchGesamt = primaerEnergieVerbrauch_1 + primaerEnergieVerbrauch_2 + primaerEnergieVerbrauchLeerstandsZuschlag + primaerEnergieVerbrauchStrom;
|
||||||
@@ -214,26 +207,22 @@ export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis:
|
|||||||
|
|
||||||
// Return all the steps that this function includes for debugging as a json object
|
// Return all the steps that this function includes for debugging as a json object
|
||||||
return {
|
return {
|
||||||
umrechnungsfaktor : umrechnungsfaktor,
|
brennstoff_1,
|
||||||
primaerfaktor : primaerfaktor,
|
brennstoff_2,
|
||||||
coe : coe,
|
|
||||||
umrechnungsfaktor_1 : umrechnungsfaktor_1,
|
|
||||||
primaerfaktor_1 : primaerfaktor_1,
|
|
||||||
coe_1 : coe_1,
|
|
||||||
kuehlungsZuschlag_1 : Math.round(kuehlungsZuschlag_1),
|
kuehlungsZuschlag_1 : Math.round(kuehlungsZuschlag_1),
|
||||||
kuehlungsZuschlag_2: Math.round(kuehlungsZuschlag_2),
|
kuehlungsZuschlag_2: Math.round(kuehlungsZuschlag_2),
|
||||||
durchschnittsKlimafaktor : Math.round(durchschnittsKlimafaktor,2),
|
durchschnittsKlimafaktor : Math.round(durchschnittsKlimafaktor * 100) / 100,
|
||||||
Klimafaktor_1 : klimafaktoren[0],
|
Klimafaktor_1 : klimafaktoren[0],
|
||||||
Klimafaktor_2 : klimafaktoren[1],
|
Klimafaktor_2 : klimafaktoren[1],
|
||||||
Klimafaktor_3 : klimafaktoren[2],
|
Klimafaktor_3 : klimafaktoren[2],
|
||||||
anteil_heizung_1: 1 - ((ausweis.anteil_warmwasser_1 || 0) / 100),
|
anteil_heizung_1: 1 - ((ausweis.anteil_warmwasser_1 || 0) / 100),
|
||||||
anteil_heizung_2: 1 - ((ausweis.anteil_warmwasser_2 || 0) / 100),
|
anteil_heizung_2: 1 - ((ausweis.anteil_warmwasser_2 || 0) / 100),
|
||||||
verbrauch_1_kwh: ausweis.verbrauch_1 * umrechnungsfaktor,
|
verbrauch_1_kwh: (ausweis.verbrauch_1 || 0) * brennstoff_1.umrechnungsfaktor,
|
||||||
verbrauch_2_kwh: ausweis.verbrauch_2 * umrechnungsfaktor,
|
verbrauch_2_kwh: (ausweis.verbrauch_2 || 0) * brennstoff_1.umrechnungsfaktor,
|
||||||
verbrauch_3_kwh: ausweis.verbrauch_3 * umrechnungsfaktor,
|
verbrauch_3_kwh: (ausweis.verbrauch_3 || 0) * brennstoff_1.umrechnungsfaktor,
|
||||||
verbrauch_4_kwh: ausweis.verbrauch_4 * umrechnungsfaktor_1,
|
verbrauch_4_kwh: (ausweis.verbrauch_4 || 0) * brennstoff_2.umrechnungsfaktor,
|
||||||
verbrauch_5_kwh: ausweis.verbrauch_5 * umrechnungsfaktor_1,
|
verbrauch_5_kwh: (ausweis.verbrauch_5 || 0) * brennstoff_2.umrechnungsfaktor,
|
||||||
verbrauch_6_kwh: ausweis.verbrauch_6 * umrechnungsfaktor_1,
|
verbrauch_6_kwh: (ausweis.verbrauch_6 || 0) * brennstoff_2.umrechnungsfaktor,
|
||||||
klimafaktoren : klimafaktoren,
|
klimafaktoren : klimafaktoren,
|
||||||
nutzflaeche : Math.round(nutzflaeche),
|
nutzflaeche : Math.round(nutzflaeche),
|
||||||
leerstand : leerstand,
|
leerstand : leerstand,
|
||||||
@@ -250,12 +239,12 @@ export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis:
|
|||||||
energieVerbrauchWarmwasser_2: Math.round(energieVerbrauchWarmwasser_2),
|
energieVerbrauchWarmwasser_2: Math.round(energieVerbrauchWarmwasser_2),
|
||||||
energieVerbrauchHeizung_1: energieVerbrauchHeizung_1,
|
energieVerbrauchHeizung_1: energieVerbrauchHeizung_1,
|
||||||
energieVerbrauchHeizung_2: energieVerbrauchHeizung_2,
|
energieVerbrauchHeizung_2: energieVerbrauchHeizung_2,
|
||||||
anteil_warmwasser_1: ausweis.anteil_warmwasser_1 / 100,
|
anteil_warmwasser_1: (ausweis.anteil_warmwasser_1 || 0) / 100,
|
||||||
anteil_warmwasser_2: ausweis.anteil_warmwasser_2 / 100,
|
anteil_warmwasser_2: (ausweis.anteil_warmwasser_2 || 0) / 100,
|
||||||
energieVerbrauchHeizungBereinigt_1: Math.round(energieVerbrauchHeizungBereinigt_1),
|
energieVerbrauchHeizungBereinigt_1: Math.round(energieVerbrauchHeizungBereinigt_1),
|
||||||
energieVerbrauchHeizungBereinigt_2: Math.round(energieVerbrauchHeizungBereinigt_2),
|
energieVerbrauchHeizungBereinigt_2: Math.round(energieVerbrauchHeizungBereinigt_2),
|
||||||
durchschnittsEnergieVerbrauchHeizungBereingt: Math.round(durchschnittsEnergieVerbrauchHeizungBereingt),
|
durchschnittsEnergieVerbrauchHeizungBereingt: Math.round(durchschnittsEnergieVerbrauchHeizungBereingt),
|
||||||
faktorDurchschnittsEnergieVerbrauchHeizungBereinigt: Math.round(faktorDurchschnittsEnergieVerbrauchHeizungBereinigt,3),
|
faktorDurchschnittsEnergieVerbrauchHeizungBereinigt: Math.round(faktorDurchschnittsEnergieVerbrauchHeizungBereinigt * 1000) / 1000,
|
||||||
endEnergieVerbrauch_1: Math.round(endEnergieVerbrauch_1),
|
endEnergieVerbrauch_1: Math.round(endEnergieVerbrauch_1),
|
||||||
endEnergieVerbrauch_2: Math.round(endEnergieVerbrauch_2),
|
endEnergieVerbrauch_2: Math.round(endEnergieVerbrauch_2),
|
||||||
energieVerbrauchStrom: energieVerbrauchStrom,
|
energieVerbrauchStrom: energieVerbrauchStrom,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { AufnahmeClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
import { AufnahmeClient, BedarfsausweisWohnenClient, ObjektClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
||||||
import { Enums } from "@ibcornelsen/database/client";
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|
||||||
export function getEmpfehlungen(ausweis: VerbrauchsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient): {
|
export function getEmpfehlungen(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient): {
|
||||||
title: string,
|
title: string,
|
||||||
description: string,
|
description: string,
|
||||||
anlagenteil: string,
|
anlagenteil: string,
|
||||||
|
|||||||
@@ -60,3 +60,5 @@ export const SERVICES: Record<
|
|||||||
Telefonberatung: 0,
|
Telefonberatung: 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const BASE_URI = process.env.NODE_ENV == "production" ? "https://online-energieausweis.org" : "http://localhost:3000";
|
||||||
11
src/lib/mail.ts
Normal file
11
src/lib/mail.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import * as nodemailer from "nodemailer";
|
||||||
|
|
||||||
|
export const transport = nodemailer.createTransport({
|
||||||
|
host: "smtp.ionos.de",
|
||||||
|
port: 465,
|
||||||
|
secure: true,
|
||||||
|
auth: {
|
||||||
|
user: "info@online-energieausweis.org",
|
||||||
|
pass: "Katendeich5a2024!",
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -92,3 +92,19 @@ export async function maybeAuthorizationMiddleware(input: any, ctx: TypesafeAPIC
|
|||||||
export const authorizationHeaders = {
|
export const authorizationHeaders = {
|
||||||
Authorization: z.string()
|
Authorization: z.string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function adminMiddleware(input: any, ctx: TypesafeAPIContextWithRequest<any>) {
|
||||||
|
try {
|
||||||
|
const user = await authorizationMiddleware(input, ctx)
|
||||||
|
|
||||||
|
if (user.rolle === "ADMIN") {
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new APIError({
|
||||||
|
code: "FORBIDDEN",
|
||||||
|
"message": "Diese Route ist für Admins vorbehalten."
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { AufnahmeClient, BenutzerClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
import { AufnahmeClient, BenutzerClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
|
||||||
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
|
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
|
||||||
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";
|
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";
|
||||||
import { Enums } from "@ibcornelsen/database/server";
|
import { Enums } from "@ibcornelsen/database/server";
|
||||||
import * as fs from "fs"
|
import * as fs from "fs"
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { PDFDocument, PDFFont, PDFName, PDFNumber, PDFPage, StandardFonts, TextAlignment } from "pdf-lib";
|
import { PDFDocument, PDFFont, PDFImage, PDFName, PDFNumber, PDFPage, StandardFonts, TextAlignment } from "pdf-lib";
|
||||||
|
|
||||||
|
|
||||||
export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: UploadedGebaeudeBild[], user: BenutzerClient) {
|
export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: UploadedGebaeudeBild[], user: BenutzerClient) {
|
||||||
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("./templates/GEG24_Nichtwohngebaeude.pdf", import.meta.url), "base64");
|
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("./templates/GEG24_Nichtwohngebaeude.pdf", import.meta.url), "base64");
|
||||||
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
|
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
|
||||||
const pages = pdf.getPages()
|
const pages = pdf.getPages()
|
||||||
@@ -15,7 +15,6 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisWohn
|
|||||||
// const template = VerbrauchsausweisWohnen2016Template as Template;
|
// const template = VerbrauchsausweisWohnen2016Template as Template;
|
||||||
|
|
||||||
const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt);
|
const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt);
|
||||||
console.log(berechnungen);
|
|
||||||
|
|
||||||
const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt)
|
const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt)
|
||||||
|
|
||||||
@@ -44,6 +43,50 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisWohn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pages[0].drawText(aufnahme.gebaeudetyp || "", {
|
||||||
|
x: 181,
|
||||||
|
y: height - 191,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[0].drawText(objekt.adresse || "", {
|
||||||
|
x: 181,
|
||||||
|
y: height - 210,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[0].drawText(aufnahme.gebaeudeteil || "", {
|
||||||
|
x: 181,
|
||||||
|
y: height - 226,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[0].drawText(aufnahme.baujahr_gebaeude?.toString() || "", {
|
||||||
|
x: 181,
|
||||||
|
y: height - 242.5,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[0].drawText(aufnahme.baujahr_heizung?.toString() || "", {
|
||||||
|
x: 181,
|
||||||
|
y: height - 259,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[0].drawText(aufnahme.nutzflaeche?.toString() || "", {
|
||||||
|
x: 181,
|
||||||
|
y: height - 295,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
pages[0].drawText(`${aufnahme.brennstoff_1}, ${aufnahme.brennstoff_2 || ""}`, {
|
||||||
|
x: 181,
|
||||||
|
y: height - 314,
|
||||||
|
size: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const gebaeudetyp = fillFormField("gebaeudetyp", aufnahme.gebaeudetyp || "")
|
// const gebaeudetyp = fillFormField("gebaeudetyp", aufnahme.gebaeudetyp || "")
|
||||||
|
|
||||||
// const adresse = fillFormField("adresse", objekt.adresse)
|
// const adresse = fillFormField("adresse", objekt.adresse)
|
||||||
@@ -76,7 +119,22 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisWohn
|
|||||||
// toggleCheck("anlass_sonstiges", ausweis.ausstellgrund == "Sonstiges")
|
// toggleCheck("anlass_sonstiges", ausweis.ausstellgrund == "Sonstiges")
|
||||||
|
|
||||||
|
|
||||||
// const gebaeudeBild = bilder.find(image => image.kategorie === "Gebaeude");
|
const gebaeudeBild = bilder.find(image => image.kategorie === Enums.BilderKategorie.Gebaeude);
|
||||||
|
|
||||||
|
if (gebaeudeBild) {
|
||||||
|
let image: PDFImage;
|
||||||
|
try {
|
||||||
|
image = await pdf.embedJpg(gebaeudeBild?.base64)
|
||||||
|
} catch(e) {
|
||||||
|
image = await pdf.embedPng(gebaeudeBild?.base64)
|
||||||
|
}
|
||||||
|
pages[0].drawImage(image, {
|
||||||
|
x: 424.5,
|
||||||
|
y: height - 321,
|
||||||
|
width: 111,
|
||||||
|
height: 143
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// /* -------------------------------- Seite 2 -------------------------------- */
|
// /* -------------------------------- Seite 2 -------------------------------- */
|
||||||
@@ -248,50 +306,44 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisWohn
|
|||||||
|
|
||||||
const addVerbrauch = addVerbrauchGenerator();
|
const addVerbrauch = addVerbrauchGenerator();
|
||||||
|
|
||||||
|
if (!ausweis.warmwasser_enthalten) {
|
||||||
|
// Mit Warmwasserzuschlag
|
||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(1, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
aufnahme.brennstoff_1,
|
aufnahme.brennstoff_1 || "",
|
||||||
berechnungen?.primaerfaktor.toString(),
|
berechnungen?.brennstoff_1.primaerenergiefaktor.toString(),
|
||||||
Math.round(berechnungen?.verbrauch_1_kwh).toString(),
|
Math.round(berechnungen?.energieVerbrauchGesamt_1 || 0).toString(),
|
||||||
Math.round(
|
"0",
|
||||||
berechnungen?.anteil_warmwasser_1 * berechnungen?.verbrauch_1_kwh
|
Math.round(berechnungen?.energieVerbrauchHeizung_1 || 0).toString(),
|
||||||
).toString(),
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
Math.round(
|
|
||||||
berechnungen?.anteil_heizung_1 * berechnungen?.verbrauch_1_kwh
|
|
||||||
).toString(),
|
|
||||||
berechnungen?.klimafaktoren[0].klimafaktor.toString()
|
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// Ohne Warmwasserzuschlag
|
||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).add(1, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(2, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
aufnahme.brennstoff_1,
|
aufnahme.brennstoff_1 || "",
|
||||||
berechnungen?.primaerfaktor.toString(),
|
berechnungen?.brennstoff_1.primaerenergiefaktor.toString(),
|
||||||
Math.round(berechnungen?.verbrauch_2_kwh).toString(),
|
Math.round(berechnungen?.energieVerbrauchGesamt_1 || 0).toString(),
|
||||||
Math.round(
|
Math.round(berechnungen?.energieVerbrauchWarmwasser_1 || 0).toString(),
|
||||||
berechnungen?.anteil_warmwasser_1 * berechnungen?.verbrauch_2_kwh
|
Math.round(berechnungen?.energieVerbrauchHeizung_1 || 0).toString(),
|
||||||
).toString(),
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
Math.round(
|
|
||||||
berechnungen?.anteil_heizung_1 * berechnungen?.verbrauch_2_kwh
|
|
||||||
).toString(),
|
|
||||||
berechnungen?.klimafaktoren[0].klimafaktor.toString()
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ausweis.zusaetzliche_heizquelle) {
|
||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).add(2, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(3, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
aufnahme.brennstoff_1,
|
aufnahme.brennstoff_2 || "",
|
||||||
berechnungen?.primaerfaktor.toString(),
|
berechnungen?.brennstoff_2.primaerenergiefaktor.toString(),
|
||||||
Math.round(berechnungen?.verbrauch_3_kwh).toString(),
|
Math.round(berechnungen?.energieVerbrauchGesamt_2 || 0).toString(),
|
||||||
Math.round(
|
Math.round(berechnungen?.energieVerbrauchWarmwasser_2 || 0).toString(),
|
||||||
berechnungen?.anteil_warmwasser_1 * berechnungen?.verbrauch_3_kwh
|
Math.round(berechnungen?.energieVerbrauchHeizung_2 || 0).toString(),
|
||||||
).toString(),
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
Math.round(
|
|
||||||
berechnungen?.anteil_heizung_1 * berechnungen?.verbrauch_3_kwh
|
|
||||||
).toString(),
|
|
||||||
berechnungen?.klimafaktoren[0].klimafaktor.toString()
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------- Seite 4 -------------------------------- */
|
/* -------------------------------- Seite 4 -------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";
|
|||||||
import { Enums } from "@ibcornelsen/database/server";
|
import { Enums } from "@ibcornelsen/database/server";
|
||||||
import * as fs from "fs"
|
import * as fs from "fs"
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { PDFDocument, PDFFont, PDFPage, RotationTypes, StandardFonts, TextAlignment } from "pdf-lib";
|
import { PDFDocument, PDFFont, PDFImage, PDFPage, RotationTypes, StandardFonts, TextAlignment } from "pdf-lib";
|
||||||
|
|
||||||
/* -------------------------------- Pdf Tools ------------------------------- */
|
/* -------------------------------- Pdf Tools ------------------------------- */
|
||||||
|
|
||||||
@@ -74,11 +74,22 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne
|
|||||||
toggleCheck("anlass_modernisierung", ausweis.ausstellgrund == "Modernisierung")
|
toggleCheck("anlass_modernisierung", ausweis.ausstellgrund == "Modernisierung")
|
||||||
toggleCheck("anlass_sonstiges", ausweis.ausstellgrund == "Sonstiges")
|
toggleCheck("anlass_sonstiges", ausweis.ausstellgrund == "Sonstiges")
|
||||||
|
|
||||||
console.log(bilder);
|
const gebaeudeBild = bilder.find(image => image.kategorie === Enums.BilderKategorie.Gebaeude);
|
||||||
|
|
||||||
|
|
||||||
const gebaeudeBild = bilder.find(image => image.kategorie === "Gebaeude");
|
|
||||||
|
|
||||||
|
if (gebaeudeBild) {
|
||||||
|
let image: PDFImage;
|
||||||
|
try {
|
||||||
|
image = await pdf.embedJpg(gebaeudeBild?.base64)
|
||||||
|
} catch(e) {
|
||||||
|
image = await pdf.embedPng(gebaeudeBild?.base64)
|
||||||
|
}
|
||||||
|
pages[0].drawImage(image, {
|
||||||
|
x: 460.5,
|
||||||
|
y: height - 289,
|
||||||
|
width: 111,
|
||||||
|
height: 138
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------- Seite 2 -------------------------------- */
|
/* -------------------------------- Seite 2 -------------------------------- */
|
||||||
|
|
||||||
@@ -244,50 +255,109 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne
|
|||||||
|
|
||||||
const addVerbrauch = addVerbrauchGenerator();
|
const addVerbrauch = addVerbrauchGenerator();
|
||||||
|
|
||||||
|
if (!ausweis.warmwasser_enthalten) {
|
||||||
|
// Mit Warmwasserzuschlag
|
||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(1, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
aufnahme.brennstoff_1,
|
aufnahme.brennstoff_1,
|
||||||
berechnungen?.primaerfaktorww.toString(),
|
berechnungen?.brennstoff_1.primaerenergiefaktor.toString(),
|
||||||
Math.round(berechnungen?.verbrauch_1_kwh).toString(),
|
Math.round(berechnungen?.energieVerbrauchGesamt_1).toString(),
|
||||||
Math.round(
|
"0",
|
||||||
berechnungen?.anteil_warmwasser_1 * berechnungen?.verbrauch_1_kwh
|
Math.round(berechnungen?.energieVerbrauchHeizung_1).toString(),
|
||||||
).toString(),
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
Math.round(
|
|
||||||
berechnungen?.anteil_heizung_1 * berechnungen?.verbrauch_1_kwh
|
|
||||||
).toString(),
|
|
||||||
berechnungen?.klimafaktoren[0].klimafaktor.toString()
|
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// Ohne Warmwasserzuschlag
|
||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).add(1, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(2, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
aufnahme.brennstoff_1,
|
aufnahme.brennstoff_1,
|
||||||
berechnungen?.primaerfaktorww.toString(),
|
berechnungen?.brennstoff_1.primaerenergiefaktor.toString(),
|
||||||
Math.round(berechnungen?.verbrauch_2_kwh).toString(),
|
Math.round(berechnungen?.energieVerbrauchGesamt_1).toString(),
|
||||||
Math.round(
|
Math.round(berechnungen?.energieVerbrauchWarmwasser_1).toString(),
|
||||||
berechnungen?.anteil_warmwasser_1 * berechnungen?.verbrauch_2_kwh
|
Math.round(berechnungen?.energieVerbrauchHeizung_1).toString(),
|
||||||
).toString(),
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
Math.round(
|
|
||||||
berechnungen?.anteil_heizung_1 * berechnungen?.verbrauch_2_kwh
|
|
||||||
).toString(),
|
|
||||||
berechnungen?.klimafaktoren[0].klimafaktor.toString()
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ausweis.zusaetzliche_heizquelle) {
|
||||||
addVerbrauch(
|
addVerbrauch(
|
||||||
moment(ausweis.startdatum).add(2, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).format("MM.YYYY"),
|
||||||
moment(ausweis.startdatum).add(3, "year").format("MM.YYYY"),
|
moment(ausweis.startdatum).add(3, "years").format("MM.YYYY"),
|
||||||
aufnahme.brennstoff_1,
|
aufnahme.brennstoff_2,
|
||||||
berechnungen?.primaerfaktorww.toString(),
|
berechnungen?.brennstoff_2.primaerenergiefaktor.toString(),
|
||||||
Math.round(berechnungen?.verbrauch_3_kwh).toString(),
|
Math.round(berechnungen?.energieVerbrauchGesamt_2).toString(),
|
||||||
Math.round(
|
Math.round(berechnungen?.energieVerbrauchWarmwasser_2).toString(),
|
||||||
berechnungen?.anteil_warmwasser_1 * berechnungen?.verbrauch_3_kwh
|
Math.round(berechnungen?.energieVerbrauchHeizung_2).toString(),
|
||||||
).toString(),
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
Math.round(
|
|
||||||
berechnungen?.anteil_heizung_1 * berechnungen?.verbrauch_3_kwh
|
|
||||||
).toString(),
|
|
||||||
berechnungen?.klimafaktoren[0].klimafaktor.toString()
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ausweis.warmwasser_enthalten) {
|
||||||
|
/**
|
||||||
|
* Dezentrale Warmwasserversorgung - Pauschale Erhöhung um 20kWh/m²
|
||||||
|
* @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"),
|
||||||
|
"Warmwasserzuschlag",
|
||||||
|
berechnungen?.primaerfaktorww.toString(),
|
||||||
|
Math.round(berechnungen?.energieVerbrauchWarmwasser_1).toString(),
|
||||||
|
Math.round(berechnungen?.energieVerbrauchWarmwasser_1).toString(),
|
||||||
|
"0",
|
||||||
|
"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 + berechnungen?.leerstandsZuschlagWarmwasser).toString(),
|
||||||
|
Math.round(berechnungen?.leerstandsZuschlagWarmwasser).toString(),
|
||||||
|
Math.round(berechnungen?.leerstandsZuschlagHeizung).toString(),
|
||||||
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
|
);
|
||||||
|
} 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 + berechnungen?.leerstandsZuschlagWarmwasser).toString(),
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
berechnungen?.durchschnittsKlimafaktor.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ausweis.wird_gekuehlt) {
|
||||||
|
/**
|
||||||
|
* 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"),
|
||||||
|
"Leerstandszuschlag",
|
||||||
|
berechnungen?.primaerfaktorww.toString(),
|
||||||
|
Math.round(berechnungen?.kuehlungsZuschlag).toString(),
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1.8"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------- Seite 4 -------------------------------- */
|
/* -------------------------------- Seite 4 -------------------------------- */
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -18,9 +18,6 @@
|
|||||||
bilder: UploadedGebaeudeBild[],
|
bilder: UploadedGebaeudeBild[],
|
||||||
events: Event[]
|
events: Event[]
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
console.log(ausweise);
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="gap-4 flex flex-col">
|
<div class="gap-4 flex flex-col">
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
<h2 class="text-primary text-xl">
|
<h2 class="text-primary text-xl">
|
||||||
Verbrauchsausweis Wohnen {PRICES.VerbrauchsausweisWohnen[0]} €
|
Verbrauchsausweis Wohnen {PRICES.VerbrauchsausweisWohnen[0]} €
|
||||||
</h2>
|
</h2>
|
||||||
<Progressbar step2={'step'}/>
|
<Progressbar active={1}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
<h1 class="text-secondary text-3xl m-0">Energiesausweis erstellen</h1>
|
<h1 class="text-secondary text-3xl m-0">Energiesausweis erstellen</h1>
|
||||||
<h2 class="text-primary text-xl">Verbrauchsausweis Gewerbe {PRICES.VerbrauchsausweisGewerbe[0]} €</h2>
|
<h2 class="text-primary text-xl">Verbrauchsausweis Gewerbe {PRICES.VerbrauchsausweisGewerbe[0]} €</h2>
|
||||||
<Progressbar step1={'step'} />
|
<Progressbar active={0} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -227,9 +227,9 @@ lg:grid-cols-2 lg:gap-x-6
|
|||||||
|
|
||||||
<div id="progress-box" class="w-full box relative px-4 py-3 text-center order-2 self-stretch">
|
<div id="progress-box" class="w-full box relative px-4 py-3 text-center order-2 self-stretch">
|
||||||
|
|
||||||
<h1 class="text-secondary text-3xl m-0">Energiesausweis erstellen</h1>
|
<h1 class="text-secondary text-3xl m-0">Energieausweis erstellen</h1>
|
||||||
<h2 class="text-primary text-xl">{ausweisart} {PRICES.VerbrauchsausweisWohnen[0]} €</h2>
|
<h2 class="text-primary text-xl">{ausweisart} {PRICES.VerbrauchsausweisWohnen[0]} €</h2>
|
||||||
<Progressbar step1={'step'}/>
|
<Progressbar active={0}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,372 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Ausweisart from "#components/Ausweis/Ausweisart.svelte";
|
||||||
|
import GebaeudeDaten from "#components/Ausweis/GebaeudeDaten.svelte";
|
||||||
|
import {
|
||||||
|
VerbrauchsausweisWohnenClient,
|
||||||
|
ObjektClient,
|
||||||
|
AufnahmeClient,
|
||||||
|
BenutzerClient,
|
||||||
|
UploadedGebaeudeBild,
|
||||||
|
UnterlageClient,
|
||||||
|
BedarfsausweisWohnenClient,
|
||||||
|
VerbrauchsausweisGewerbeClient,
|
||||||
|
} from "#components/Ausweis/types.js";
|
||||||
|
import Bereich from "#components/labels/Bereich.svelte";
|
||||||
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
|
import InputLabel from "#components/labels/InputLabel.svelte";
|
||||||
|
import HelpLabel from "#components/labels/HelpLabel.svelte";
|
||||||
|
import Progressbar from "#components/Ausweis/Progressbar.svelte";
|
||||||
|
import FileGrid from "#components/FileGrid.svelte";
|
||||||
|
import Hilfe from "#components/Ausweis/Hilfe.svelte";
|
||||||
|
import Overlay from "#components/Overlay.svelte";
|
||||||
|
import EmbeddedAuthFlowModule from "#modules/EmbeddedAuthFlowModule.svelte";
|
||||||
|
import { validateAccessTokenClient } from "#client/lib/validateAccessToken.js";
|
||||||
|
import { api } from "astro-typesafe-api/client";
|
||||||
|
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
|
||||||
|
import { exclude } from "#lib/exclude.js";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
|
export async function ausweisSpeichern(
|
||||||
|
ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient,
|
||||||
|
objekt: ObjektClient,
|
||||||
|
aufnahme: AufnahmeClient,
|
||||||
|
unterlagen: (UnterlageClient & { data?: string | ArrayBuffer })[],
|
||||||
|
ausweisart: Enums.Ausweisart
|
||||||
|
) {
|
||||||
|
if (objekt.uid) {
|
||||||
|
await api.objekt._uid.PATCH.fetch({
|
||||||
|
...exclude(objekt, ["uid"])
|
||||||
|
}, {
|
||||||
|
params: {
|
||||||
|
uid: objekt.uid
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const { uid } = await api.objekt.PUT.fetch({
|
||||||
|
...exclude(objekt, ["uid"])
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
objekt.uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (aufnahme.uid) {
|
||||||
|
await api.aufnahme._uid.PATCH.fetch({
|
||||||
|
...exclude(aufnahme, ["uid"])
|
||||||
|
}, {
|
||||||
|
params: {
|
||||||
|
uid: aufnahme.uid
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const { uid } = await api.aufnahme.PUT.fetch({
|
||||||
|
aufnahme,
|
||||||
|
uid_objekt: objekt.uid
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
aufnahme.uid = uid
|
||||||
|
}
|
||||||
|
|
||||||
|
let patchRoute: any;
|
||||||
|
let putRoute: any;
|
||||||
|
if (ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen) {
|
||||||
|
patchRoute = api["verbrauchsausweis-wohnen"]._uid.PATCH
|
||||||
|
putRoute = api["verbrauchsausweis-wohnen"].PUT
|
||||||
|
} else if (ausweisart == Enums.Ausweisart.VerbrauchsausweisGewerbe) {
|
||||||
|
patchRoute = api["verbrauchsausweis-gewerbe"]._uid.PATCH
|
||||||
|
putRoute = api["verbrauchsausweis-gewerbe"].PUT
|
||||||
|
} else if (ausweisart == Enums.Ausweisart.BedarfsausweisWohnen) {
|
||||||
|
patchRoute = api["bedarfsausweis-wohnen"]._uid.PATCH
|
||||||
|
putRoute = api["bedarfsausweis-wohnen"].PUT
|
||||||
|
} else if (ausweisart == Enums.Ausweisart.GEGNachweisVerbrauchsausweisWohnen) {
|
||||||
|
patchRoute = api["geg-nachweis-verbrauchsausweis-wohnen"]._uid.PATCH
|
||||||
|
putRoute = api["geg-nachweis-verbrauchsausweis-wohnen"].PUT
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ausweis.uid) {
|
||||||
|
await patchRoute.fetch({
|
||||||
|
...exclude(ausweis, ["uid"])
|
||||||
|
}, {
|
||||||
|
params: {
|
||||||
|
uid: ausweis.uid
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const { uid } = await putRoute.fetch({
|
||||||
|
ausweis,
|
||||||
|
uid_aufnahme: aufnahme.uid
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ausweis.uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const unterlage of unterlagen) {
|
||||||
|
if (unterlage.uid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api.objekt._uid.unterlagen.PUT.fetch({
|
||||||
|
data: unterlage.data,
|
||||||
|
kategorie: unterlage.kategorie,
|
||||||
|
mime: unterlage.mime,
|
||||||
|
name: unterlage.name
|
||||||
|
}, {
|
||||||
|
params: {
|
||||||
|
uid: objekt.uid
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
unterlage.uid = response.uid
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid_ausweis: ausweis.uid,
|
||||||
|
uid_aufnahme: aufnahme.uid,
|
||||||
|
uid_objekt: objekt.uid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function ausweisAbschicken() {
|
||||||
|
if (!(await validateAccessTokenClient())) {
|
||||||
|
loginOverlayHidden = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ausweisSpeichern(ausweis, objekt, aufnahme, unterlagen, Enums.Ausweisart.VerbrauchsausweisGewerbe)
|
||||||
|
|
||||||
|
loginOverlayHidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function spaeterWeitermachen() {
|
||||||
|
if (!(await validateAccessTokenClient())) {
|
||||||
|
loginOverlayHidden = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loginOverlayHidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let loginOverlayHidden = true;
|
||||||
|
|
||||||
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
|
export let objekt: ObjektClient;
|
||||||
|
export let aufnahme: AufnahmeClient;
|
||||||
|
export let user: BenutzerClient = {} as BenutzerClient;
|
||||||
|
export let bilder: UploadedGebaeudeBild[] = [];
|
||||||
|
export let plaene: (UnterlageClient & { data: string | ArrayBuffer })[] =
|
||||||
|
[];
|
||||||
|
export let unterlagen: (UnterlageClient & {
|
||||||
|
data: string | ArrayBuffer;
|
||||||
|
})[] = [];
|
||||||
|
|
||||||
|
|
||||||
|
if (Object.keys(ausweis).length === 0) {
|
||||||
|
const localStorageAusweis = localStorage.getItem("ausweis");
|
||||||
|
if (localStorageAusweis) {
|
||||||
|
ausweis = JSON.parse(localStorageAusweis)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(aufnahme).length === 0) {
|
||||||
|
const localStorageAufnahme = localStorage.getItem("aufnahme");
|
||||||
|
if (localStorageAufnahme) {
|
||||||
|
aufnahme = JSON.parse(localStorageAufnahme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(objekt).length === 0) {
|
||||||
|
const localStorageObjekt = localStorage.getItem("objekt");
|
||||||
|
if (localStorageObjekt) {
|
||||||
|
objekt = JSON.parse(localStorageObjekt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (ausweis.uid && objekt.uid && aufnahme.uid) {
|
||||||
|
localStorage.setItem(ausweis.uid, JSON.stringify(ausweis))
|
||||||
|
localStorage.setItem(objekt.uid, JSON.stringify(objekt))
|
||||||
|
localStorage.setItem(aufnahme.uid, JSON.stringify(aufnahme))
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("ausweis", JSON.stringify(ausweis))
|
||||||
|
localStorage.setItem("aufnahme", JSON.stringify(aufnahme))
|
||||||
|
localStorage.setItem("objekt", JSON.stringify(objekt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ausweisart = Enums.Ausweisart.GEGNachweisVerbrauchsausweisWohnen;
|
||||||
|
|
||||||
|
function automatischAusfüllen() {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="skala"
|
||||||
|
class="bg-white grid grid-cols-1 p-4 lg:grid-cols-2 lg:gap-x-6 no-scroll"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="progress-box"
|
||||||
|
class="w-full box relative px-4 py-3 text-center order-2 self-stretch"
|
||||||
|
>
|
||||||
|
<h1 class="text-secondary text-3xl m-0">GEG Nachweis Anfragen</h1>
|
||||||
|
<h2 class="text-primary text-xl">Verbrauchsausweis Wohnen</h2>
|
||||||
|
<Progressbar
|
||||||
|
active={0}
|
||||||
|
steps={["Gebäudedaten", "Kundendaten", "Bestätigung"]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form
|
||||||
|
id="formInput-1"
|
||||||
|
on:submit={ausweisAbschicken}
|
||||||
|
name="ausweis"
|
||||||
|
data-test="ausweis"
|
||||||
|
>
|
||||||
|
<div id="formular-box" class="formular-boxen ring-0">
|
||||||
|
<!-- A Prüfung der Ausweisart -->
|
||||||
|
|
||||||
|
<Bereich bereich="A" title="Prüfung der Ausweisart">
|
||||||
|
<Ausweisart bind:objekt bind:aufnahme bind:ausweis {ausweisart} />
|
||||||
|
</Bereich>
|
||||||
|
|
||||||
|
<!-- B Eingabe der Gebäudeadresse - Angaben zu Wohnfläche, Keller und Dachgeschoss -->
|
||||||
|
|
||||||
|
<Bereich
|
||||||
|
bereich="B"
|
||||||
|
title="Eingabe der Gebäudeadresse - Angaben zu Wohnfläche, Keller und Dachgeschoss"
|
||||||
|
><GebaeudeDaten bind:aufnahme bind:objekt {ausweisart} /></Bereich
|
||||||
|
>
|
||||||
|
|
||||||
|
<Bereich bereich="C" title="Beschreibung des Bauvorhabens">
|
||||||
|
<div class="bereich-box">
|
||||||
|
<div class="input-standard order-3 md:order-5 xl:order-3">
|
||||||
|
<InputLabel
|
||||||
|
title="Angaben zur Heizung, Lüftung, Energieerezugung, Qualität und Aufbau der Gebäudehülle usw."
|
||||||
|
></InputLabel>
|
||||||
|
|
||||||
|
<textarea class="rounded-e-none" rows="10"></textarea>
|
||||||
|
|
||||||
|
<div class="help-label">
|
||||||
|
<HelpLabel>
|
||||||
|
Geben Sie kurz an: Heizung, Lüftung, regenerative
|
||||||
|
Energie (Solar, PV) und die Gebäudehülle (Qualität,
|
||||||
|
Aufbau).
|
||||||
|
</HelpLabel>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Bereich>
|
||||||
|
|
||||||
|
<Bereich bereich="D" title="Gebäudepläne & Unterlagen">
|
||||||
|
<div
|
||||||
|
class="bereich-box grid grid-cols-1 lg:grid-cols-2 gap-x-6 mt-6"
|
||||||
|
>
|
||||||
|
<div class="md:box md:card mb-0">
|
||||||
|
<div class="font-bold mb-2">Pläne</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Hier können sie Grundrisspläne, Ansichtspläne und
|
||||||
|
Schnitte hochladen. Die Dateien können entweder im PDF
|
||||||
|
Format oder als Bild hochgeladen werden.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="md:box md:card mb-0 mt-6 md:mt-0">
|
||||||
|
<div>
|
||||||
|
<strong
|
||||||
|
>Bitte laden Sie hier mind. 1 Dokument hoch:</strong
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<FileGrid
|
||||||
|
max={Infinity}
|
||||||
|
min={1}
|
||||||
|
name={"plaene"}
|
||||||
|
bind:files={plaene}
|
||||||
|
bind:ausweis
|
||||||
|
bind:objekt
|
||||||
|
></FileGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="bereich-box grid grid-cols-1 lg:grid-cols-2 gap-x-6 mt-6"
|
||||||
|
>
|
||||||
|
<div class="md:box md:card mb-0">
|
||||||
|
<div class="font-bold mb-2">Unterlagen</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Hier können sie weitere Unterlagen wie z.B.
|
||||||
|
Baugenehmigungen, U-Wert Berechnungen, Anlagentechnik
|
||||||
|
oder ihren alten Energieausweis hochladen. Die Dateien
|
||||||
|
können entweder im PDF Format oder als Bild hochgeladen
|
||||||
|
werden.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="md:box md:card mb-0 mt-6 md:mt-0">
|
||||||
|
<FileGrid
|
||||||
|
max={Infinity}
|
||||||
|
min={0}
|
||||||
|
name={"unterlagen"}
|
||||||
|
bind:files={unterlagen}
|
||||||
|
bind:ausweis
|
||||||
|
bind:objekt
|
||||||
|
></FileGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Bereich>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="grid grid-cols-[1fr_min-content_min-content_min-content] grid-rows-[min_content_1fr] gap-x-2 self-start justify-self-end mt-8"
|
||||||
|
>
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
<Hilfe />
|
||||||
|
|
||||||
|
<button class="button" type="button" on:click={spaeterWeitermachen}
|
||||||
|
>Später Weitermachen
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Overlay bind:hidden={loginOverlayHidden}>
|
||||||
|
<div class="bg-white w-full max-w-screen-sm py-8">
|
||||||
|
<EmbeddedAuthFlowModule onLogin={ausweisAbschicken}
|
||||||
|
></EmbeddedAuthFlowModule>
|
||||||
|
</div>
|
||||||
|
</Overlay>
|
||||||
|
|
||||||
|
<button
|
||||||
|
on:click={ausweisAbschicken}
|
||||||
|
type="button"
|
||||||
|
class="button"
|
||||||
|
data-cy="weiter">Weiter</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
---
|
||||||
|
import AusweisLayout from "#layouts/AusweisLayoutDaten.astro";
|
||||||
|
import { AufnahmeClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { createCaller } from "../../../astro-typesafe-api-caller.js";
|
||||||
|
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
|
||||||
|
import { validateAccessTokenServer } from "#server/lib/validateAccessToken.js";
|
||||||
|
import GEGNachweisVerbrauchsausweisWohnenModule from "#modules/angebot-anfragen/GEGNachweisVerbrauchsausweisWohnenModule.svelte";
|
||||||
|
|
||||||
|
const uid = Astro.url.searchParams.get("uid");
|
||||||
|
let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient;
|
||||||
|
let aufnahme: AufnahmeClient = {} as AufnahmeClient;
|
||||||
|
let objekt: ObjektClient = {} as ObjektClient;
|
||||||
|
let bilder: UploadedGebaeudeBild[] = []
|
||||||
|
|
||||||
|
const valid = validateAccessTokenServer(Astro);
|
||||||
|
|
||||||
|
const caller = createCaller(Astro);
|
||||||
|
|
||||||
|
if (uid) {
|
||||||
|
if (!valid) {
|
||||||
|
return Astro.redirect(
|
||||||
|
`/auth/login?redirect=${Astro.url.toString()}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ausweis = await caller["verbrauchsausweis-wohnen"]._uid.GET.fetch(null, {
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
uid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
aufnahme = await caller.aufnahme._uid.GET.fetch(null, {
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
uid: ausweis.uid_aufnahme
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
objekt = await caller.objekt._uid.GET.fetch(null, {
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
uid: ausweis.uid_objekt
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
bilder = await caller.objekt._uid.bilder.GET.fetch(null, {
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
uid: ausweis.uid_objekt
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!ausweis) {
|
||||||
|
// Der Ausweis scheint nicht zu existieren.
|
||||||
|
// Wir leiten auf die generische Ausweisseite ohne UID weiter.
|
||||||
|
return Astro.redirect(
|
||||||
|
"/energieausweis-erstellen/verbrauchsausweis-wohnen"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
return Astro.redirect(
|
||||||
|
"/energieausweis-erstellen/verbrauchsausweis-wohnen"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<AusweisLayout title="Verbrauchsausweis erstellen">
|
||||||
|
<GEGNachweisVerbrauchsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} />
|
||||||
|
</AusweisLayout>
|
||||||
|
|||||||
209
src/pages/api/admin/ausstellen.ts
Normal file
209
src/pages/api/admin/ausstellen.ts
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
import { getAusweisartFromUUID } from "#components/Ausweis/types.js";
|
||||||
|
import { adminMiddleware } from "#lib/middleware/authorization.js";
|
||||||
|
import { pdfDatenblattVerbrauchsausweisWohnen } from "#lib/pdf/pdfDatenblattVerbrauchsausweisWohnen.js";
|
||||||
|
import { pdfVerbrauchsausweisWohnen } from "#lib/pdf/pdfVerbrauchsausweisWohnen.js";
|
||||||
|
import { Enums, prisma } from "@ibcornelsen/database/server";
|
||||||
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
|
import { z } from "astro:content";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { transport } from "#lib/mail.js";
|
||||||
|
import { BASE_URI } from "#lib/constants.js";
|
||||||
|
|
||||||
|
export const GET = defineApiRoute({
|
||||||
|
input: z.object({
|
||||||
|
uid: z.string(),
|
||||||
|
}),
|
||||||
|
output: z.void(),
|
||||||
|
middleware: adminMiddleware,
|
||||||
|
async fetch({ uid }, context, user) {
|
||||||
|
const ausweisart = getAusweisartFromUUID(uid);
|
||||||
|
|
||||||
|
if (ausweisart === "VerbrauchsausweisWohnen") {
|
||||||
|
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||||
|
where: {
|
||||||
|
uid,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
aufnahme: {
|
||||||
|
include: {
|
||||||
|
objekt: {
|
||||||
|
include: {
|
||||||
|
gebaeude_bilder: true,
|
||||||
|
benutzer: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!ausweis) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Ausweis existiert nicht.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const rechnung = await prisma.rechnung.findFirst({
|
||||||
|
where: {
|
||||||
|
aufnahme_id: ausweis.aufnahme.id,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
erstellt_am: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!rechnung) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message:
|
||||||
|
"Die Rechnung wurde noch nicht erstellt, wir können nicht fortfahren.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// SECTION: Rechnung erstellen (LexOffice)
|
||||||
|
// Wir wollen die Rechnung an lex office versenden, und uns die ID von da holen.
|
||||||
|
// Falls die Rechnung bereits existiert ist das nicht nötig.
|
||||||
|
// if (!$rechnung->lex_office_id) {
|
||||||
|
// [$lex_office_id, $renr] = createInvoice($ausweis, $rechnung);
|
||||||
|
// sleep(1); // TODO: Nach der Umstellung von LexOffice auf etwas anderes MUSS das hier unbedingt entfernt werden!
|
||||||
|
|
||||||
|
// if (!$lex_office_id || !$renr) {
|
||||||
|
// die("Bei der Erstellung der Rechnung ist etwas schiefgelaufen - Möglicherweise ist etwas mit LexOffice?");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $rechnung->lex_office_id = $lex_office_id;
|
||||||
|
// $rechnung->rechnungsnummer = $renr;
|
||||||
|
// $rechnung->save();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// if ($ausweis->erledigt != 2) {$ausweis->erstellungsdatum = date("Y-m-d H:i:s");}
|
||||||
|
// $ausweis->erledigt = 2;
|
||||||
|
// $ausweis->save();
|
||||||
|
|
||||||
|
const pdfAusweis = await pdfVerbrauchsausweisWohnen(
|
||||||
|
ausweis,
|
||||||
|
ausweis.aufnahme,
|
||||||
|
ausweis.aufnahme.objekt,
|
||||||
|
ausweis.aufnahme.objekt.gebaeude_bilder,
|
||||||
|
ausweis.aufnahme.objekt.benutzer
|
||||||
|
);
|
||||||
|
const pdfDatenblatt = await pdfDatenblattVerbrauchsausweisWohnen(
|
||||||
|
ausweis,
|
||||||
|
ausweis.aufnahme,
|
||||||
|
ausweis.aufnahme.objekt,
|
||||||
|
ausweis.aufnahme.objekt.benutzer
|
||||||
|
);
|
||||||
|
|
||||||
|
const pdfAusweisPath = fileURLToPath(
|
||||||
|
new URL(
|
||||||
|
`../../../../persistent/generated/Ausweis-${ausweis.uid}.pdf`,
|
||||||
|
import.meta.url
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const pdfDatenblattPath = fileURLToPath(
|
||||||
|
new URL(
|
||||||
|
`../../../../persistent/generated/Datenblatt-${ausweis.uid}.pdf`,
|
||||||
|
import.meta.url
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.writeFileSync(pdfAusweisPath, pdfAusweis);
|
||||||
|
fs.writeFileSync(pdfDatenblattPath, pdfDatenblatt);
|
||||||
|
|
||||||
|
let text: string;
|
||||||
|
|
||||||
|
if (rechnung.status === Enums.Rechnungsstatus.paid) {
|
||||||
|
text = `
|
||||||
|
<p>Sehr geehrte*r ${user.vorname} ${user.name},</p>
|
||||||
|
|
||||||
|
<p>im Anhang finden Sie Ihren geprüften Energieusweis inkl. Rechnung als PDF-Datei. Den Rechnungsbetrag haben Sie bereits bezahlt. Vielen Dank.</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Mit freundlichen Grüßen,
|
||||||
|
<br>
|
||||||
|
Dipl.-Ing. Jens Cornelsen
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<strong>IB Cornelsen</strong>
|
||||||
|
<br>
|
||||||
|
Katendeich 5A
|
||||||
|
<br>
|
||||||
|
21035 Hamburg
|
||||||
|
<br>
|
||||||
|
www.online-energieausweis.org
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
fon 040 · 209339850
|
||||||
|
<br>
|
||||||
|
fax 040 · 209339859
|
||||||
|
</p>`;
|
||||||
|
} else {
|
||||||
|
text = `
|
||||||
|
<p>Sehr geehrte*r ${user.vorname} ${user.name},</p>
|
||||||
|
|
||||||
|
<p>im Anhang finden Sie Ihren geprüften Energieusweis inkl. Rechnung als PDF-Datei. Nachfolgend finden Sie unsere Bankverbindung. Bitte geben Sie als Verwendungszweck die Rechnungsnummer an (siehe unten). Vielen Dank.</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<table>
|
||||||
|
<tr><td>Kreditinstitut</td><td>:</td><td>\t Commerzbank AG</td>
|
||||||
|
<tr><td>Empfänger</td><td>:</td><td>\t IB Cornelsen</td>
|
||||||
|
<tr><td>IBAN</td><td>:<td>\t DE81 2004 0000 0348 6008 00</td>
|
||||||
|
<tr><td>BIC</td><td>:</td><td>\t COBADEFFXXX</td>
|
||||||
|
<tr><td>Betrag</td><td>:</td><td>\t <b>${rechnung.betrag}€</b></td>
|
||||||
|
<tr><td>Verwendungszweck</td><td>:</td><td>\t <b>${rechnung.uid}</b></td>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Alternativ können Sie auch direkt online zahlen indem Sie auf den entsprechenden Link klicken:
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><td>Per Einzuglastschrift zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=SEPA'>jetzt per ELV bezahlen</a></td></tr>
|
||||||
|
<tr><td>Per Sofortüberweisung zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=Sofort'>jetzt per Sofortüberweisung bezahlen</a></td></tr>
|
||||||
|
<tr><td>Über PayPal zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=PayPal'>jetzt per Paypal bezahlen</a></td></tr>
|
||||||
|
<tr><td>Per Giropay zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=Giropay'>jetzt per Giropay bezahlen</a></td></tr>
|
||||||
|
<tr><td>Per Visa oder MasterCard zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=Kreditkarte'>jetzt per Kreditkarte bezahlen</a></td></tr>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Mit freundlichen Grüßen,
|
||||||
|
<br>
|
||||||
|
Dipl.-Ing. Jens Cornelsen
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<strong>IB Cornelsen</strong>
|
||||||
|
<br>
|
||||||
|
Katendeich 5A
|
||||||
|
<br>
|
||||||
|
21035 Hamburg
|
||||||
|
<br>
|
||||||
|
www.online-energieausweis.org
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
fon 040 · 209339850
|
||||||
|
<br>
|
||||||
|
fax 040 · 209339859
|
||||||
|
</p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
await transport.sendMail({
|
||||||
|
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
||||||
|
to: user.email,
|
||||||
|
subject: `Ihr Originalausweis vom Ingenieurbüro Cornelsen (ID: ${ausweis.uid})`,
|
||||||
|
text,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -5,6 +5,7 @@ import { prisma } from "@ibcornelsen/database/server";
|
|||||||
import { decodeToken, encodeToken } from "#lib/auth/token.js";
|
import { decodeToken, encodeToken } from "#lib/auth/token.js";
|
||||||
import { TokenType } from "#lib/auth/types.js";
|
import { TokenType } from "#lib/auth/types.js";
|
||||||
import { hashPassword } from "#lib/password.js";
|
import { hashPassword } from "#lib/password.js";
|
||||||
|
import { transport } from "#lib/mail.js";
|
||||||
|
|
||||||
export const GET = defineApiRoute({
|
export const GET = defineApiRoute({
|
||||||
input: z.object({
|
input: z.object({
|
||||||
@@ -33,16 +34,6 @@ export const GET = defineApiRoute({
|
|||||||
uid: user.uid
|
uid: user.uid
|
||||||
})
|
})
|
||||||
|
|
||||||
const transport = nodemailer.createTransport({
|
|
||||||
host: "smtp.ionos.de",
|
|
||||||
port: 465,
|
|
||||||
secure: true,
|
|
||||||
auth: {
|
|
||||||
user: "info@online-energieausweis.org",
|
|
||||||
pass: "Katendeich5a2024!"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const info = await transport.sendMail({
|
const info = await transport.sendMail({
|
||||||
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
||||||
to: input.email,
|
to: input.email,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js";
|
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, VerbrauchsausweisWohnenClient, ZodOverlap } from "#components/Ausweis/types.js";
|
||||||
import { exclude } from "#lib/exclude.js";
|
import { exclude } from "#lib/exclude.js";
|
||||||
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
|
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||||
import { BedarfsausweisWohnenSchema, prisma } from "@ibcornelsen/database/server";
|
import { BedarfsausweisWohnenSchema, prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
|
||||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export const PATCH = defineApiRoute({
|
export const PATCH = defineApiRoute({
|
||||||
input: BedarfsausweisWohnenSchema.omit({
|
input: VerbrauchsausweisWohnenSchema.omit({
|
||||||
uid: true,
|
uid: true,
|
||||||
id: true,
|
id: true,
|
||||||
benutzer_id: true,
|
benutzer_id: true,
|
||||||
@@ -18,7 +18,7 @@ export const PATCH = defineApiRoute({
|
|||||||
},
|
},
|
||||||
middleware: authorizationMiddleware,
|
middleware: authorizationMiddleware,
|
||||||
async fetch(input, ctx, user) {
|
async fetch(input, ctx, user) {
|
||||||
const objekt = await prisma.bedarfsausweisWohnen.findUnique({
|
const objekt = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid: ctx.params.uid,
|
uid: ctx.params.uid,
|
||||||
benutzer: {
|
benutzer: {
|
||||||
@@ -34,7 +34,7 @@ export const PATCH = defineApiRoute({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.bedarfsausweisWohnen.update({
|
await prisma.verbrauchsausweisWohnen.update({
|
||||||
where: {
|
where: {
|
||||||
uid: ctx.params.uid
|
uid: ctx.params.uid
|
||||||
},
|
},
|
||||||
@@ -61,7 +61,7 @@ export const DELETE = defineApiRoute({
|
|||||||
|
|
||||||
// Wir holen uns den Bedarfsausweis
|
// Wir holen uns den Bedarfsausweis
|
||||||
// Dieser MUSS mit dem Nutzer verknüpft sein.
|
// Dieser MUSS mit dem Nutzer verknüpft sein.
|
||||||
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
|
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid,
|
uid,
|
||||||
},
|
},
|
||||||
@@ -155,7 +155,7 @@ export const GET = defineApiRoute({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
output: ZodOverlap<OptionalNullable<BedarfsausweisWohnenClient>>(BedarfsausweisWohnenSchema.merge(z.object({
|
output: ZodOverlap<OptionalNullable<VerbrauchsausweisWohnenClient>>(VerbrauchsausweisWohnenSchema.merge(z.object({
|
||||||
uid_aufnahme: UUidWithPrefix,
|
uid_aufnahme: UUidWithPrefix,
|
||||||
uid_objekt: UUidWithPrefix,
|
uid_objekt: UUidWithPrefix,
|
||||||
uid_benutzer: UUidWithPrefix.optional()
|
uid_benutzer: UUidWithPrefix.optional()
|
||||||
@@ -175,7 +175,7 @@ export const GET = defineApiRoute({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
|
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid,
|
uid,
|
||||||
benutzer_id: user.id
|
benutzer_id: user.id
|
||||||
|
|||||||
217
src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/[uid].ts
Normal file
217
src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/[uid].ts
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js";
|
||||||
|
import { exclude } from "#lib/exclude.js";
|
||||||
|
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||||
|
import { BedarfsausweisWohnenSchema, prisma } from "@ibcornelsen/database/server";
|
||||||
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const PATCH = defineApiRoute({
|
||||||
|
input: BedarfsausweisWohnenSchema.omit({
|
||||||
|
uid: true,
|
||||||
|
id: true,
|
||||||
|
benutzer_id: true,
|
||||||
|
aufnahme_id: true,
|
||||||
|
}),
|
||||||
|
output: z.void(),
|
||||||
|
headers: {
|
||||||
|
"Authorization": z.string()
|
||||||
|
},
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
async fetch(input, ctx, user) {
|
||||||
|
const objekt = await prisma.bedarfsausweisWohnen.findUnique({
|
||||||
|
where: {
|
||||||
|
uid: ctx.params.uid,
|
||||||
|
benutzer: {
|
||||||
|
id: user.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!objekt) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Ausweis konnte nicht gefunden werden oder gehört einem anderen Benutzer."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.bedarfsausweisWohnen.update({
|
||||||
|
where: {
|
||||||
|
uid: ctx.params.uid
|
||||||
|
},
|
||||||
|
data: input
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const DELETE = defineApiRoute({
|
||||||
|
meta: {
|
||||||
|
description: "Storniert einen Ausweis"
|
||||||
|
},
|
||||||
|
headers: authorizationHeaders,
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
async fetch(input, ctx, user) {
|
||||||
|
const { uid } = ctx.params;
|
||||||
|
|
||||||
|
if (!UUidWithPrefix.safeParse(uid).success) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "UID konnte nicht verifiziert werden."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wir holen uns den Bedarfsausweis
|
||||||
|
// Dieser MUSS mit dem Nutzer verknüpft sein.
|
||||||
|
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
|
||||||
|
where: {
|
||||||
|
uid,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
aufnahme: {
|
||||||
|
select: {
|
||||||
|
storniert: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!ausweis) {
|
||||||
|
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
|
||||||
|
throw new APIError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Ausweis konnte nicht gefunden werden.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wir dürfen den Ausweis nur stornieren, wenn er noch nicht ausgestellt wurde
|
||||||
|
// Außerdem müssen wir schauen, ob wir Admin oder der Besitzer des Ausweises sind.
|
||||||
|
if ((ausweis.benutzer_id !== user.id) && user.rolle !== "ADMIN") {
|
||||||
|
// Falls der Ausweis nicht dem Nutzer gehört, werfen wir einen Fehler
|
||||||
|
throw new APIError({
|
||||||
|
code: "FORBIDDEN",
|
||||||
|
message: "Ausweis gehört nicht dem Nutzer.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (ausweis.erledigt) {
|
||||||
|
// // Falls der Ausweis bereits ausgestellt wurde, werfen wir einen Fehler
|
||||||
|
// throw new TRPCError({
|
||||||
|
// code: "BAD_REQUEST",
|
||||||
|
// message: "Ausweis wurde bereits ausgestellt.",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (ausweis.aufnahme.storniert) {
|
||||||
|
// Falls der Ausweis bereits storniert ist, werfen wir einen Fehler
|
||||||
|
throw new APIError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Ausweis wurde bereits storniert.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.aufnahme.update({
|
||||||
|
where: {
|
||||||
|
id: ausweis.aufnahme_id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
storniert: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Wir erstellen ein Event, dass der Ausweis storniert wurde
|
||||||
|
// Dann können wir das in der Historie anzeigen
|
||||||
|
await prisma.event.create({
|
||||||
|
data: {
|
||||||
|
title: "Ausweis storniert",
|
||||||
|
description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.",
|
||||||
|
benutzer: {
|
||||||
|
connect: {
|
||||||
|
id: user.id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
aufnahme: {
|
||||||
|
connect: {
|
||||||
|
id: ausweis.aufnahme_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const GET = defineApiRoute({
|
||||||
|
meta: {
|
||||||
|
description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
|
||||||
|
tags: ["Gebäude"],
|
||||||
|
headers: {
|
||||||
|
"Authorization": {
|
||||||
|
description: "Ein gültiger Authentifizierungstoken",
|
||||||
|
required: true,
|
||||||
|
allowEmptyValue: false,
|
||||||
|
examples: {
|
||||||
|
Bearer: {
|
||||||
|
value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
output: ZodOverlap<OptionalNullable<BedarfsausweisWohnenClient>>(BedarfsausweisWohnenSchema.merge(z.object({
|
||||||
|
uid_aufnahme: UUidWithPrefix,
|
||||||
|
uid_objekt: UUidWithPrefix,
|
||||||
|
uid_benutzer: UUidWithPrefix.optional()
|
||||||
|
})).omit({
|
||||||
|
id: true,
|
||||||
|
aufnahme_id: true,
|
||||||
|
benutzer_id: true
|
||||||
|
})),
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
async fetch(input, context, user) {
|
||||||
|
const { uid } = context.params;
|
||||||
|
|
||||||
|
if (!uid) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Missing uid in request params"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
|
||||||
|
where: {
|
||||||
|
uid,
|
||||||
|
benutzer_id: user.id
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
benutzer: {
|
||||||
|
select: {
|
||||||
|
uid: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
aufnahme: {
|
||||||
|
select: {
|
||||||
|
uid: true,
|
||||||
|
objekt: {
|
||||||
|
select: {
|
||||||
|
uid: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!ausweis) {
|
||||||
|
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
|
||||||
|
throw new APIError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Ausweis konnte nicht gefunden werden.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid_aufnahme: ausweis.aufnahme.uid,
|
||||||
|
uid_objekt: ausweis.aufnahme.objekt.uid,
|
||||||
|
uid_benutzer: ausweis.benutzer?.uid,
|
||||||
|
...exclude(ausweis, ["id", "aufnahme_id", "benutzer_id", "aufnahme"])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
146
src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts
Normal file
146
src/pages/api/geg-nachweis-verbrauchsausweis-wohnen/index.ts
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import { UUidWithPrefix } from "#components/Ausweis/types.js";
|
||||||
|
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||||
|
import { BedarfsausweisWohnenSchema, prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
|
||||||
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const PUT = defineApiRoute({
|
||||||
|
meta: {
|
||||||
|
contentTypes: ["application/json"],
|
||||||
|
description:
|
||||||
|
"Erstellt einen neuen GEG Nachweis für Wohngebäude.",
|
||||||
|
tags: ["GEG Nachweis", "Verbrauchsausweis Wohnen"],
|
||||||
|
},
|
||||||
|
input: z.object({
|
||||||
|
ausweis: VerbrauchsausweisWohnenSchema.omit({
|
||||||
|
id: true,
|
||||||
|
benutzer_id: true,
|
||||||
|
uid: true,
|
||||||
|
aufnahme_id: true
|
||||||
|
}),
|
||||||
|
uid_aufnahme: UUidWithPrefix
|
||||||
|
}),
|
||||||
|
output: z.object({
|
||||||
|
uid: UUidWithPrefix,
|
||||||
|
objekt_uid: UUidWithPrefix,
|
||||||
|
aufnahme_uid: UUidWithPrefix,
|
||||||
|
}),
|
||||||
|
headers: authorizationHeaders,
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
async fetch(input, ctx, user) {
|
||||||
|
const aufnahme = await prisma.aufnahme.findUnique({
|
||||||
|
where: {
|
||||||
|
uid: input.uid_aufnahme
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!aufnahme || aufnahme.benutzer_id !== user.id) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "FORBIDDEN",
|
||||||
|
message: "Aufnahme konnte nicht gefunden werden oder gehört nicht zu diesem Benutzer."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdAusweis = await prisma.verbrauchsausweisWohnen.create({
|
||||||
|
data: {
|
||||||
|
...input.ausweis,
|
||||||
|
benutzer: {
|
||||||
|
connect: {
|
||||||
|
id: user.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
aufnahme: {
|
||||||
|
connect: {
|
||||||
|
uid: aufnahme.uid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
uid: true,
|
||||||
|
aufnahme: {
|
||||||
|
select: {
|
||||||
|
uid: true,
|
||||||
|
objekt: {
|
||||||
|
select: {
|
||||||
|
uid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid: createdAusweis.uid,
|
||||||
|
objekt_uid: createdAusweis.aufnahme.objekt.uid,
|
||||||
|
aufnahme_uid: createdAusweis.aufnahme.uid,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const GET = defineApiRoute({
|
||||||
|
meta: {
|
||||||
|
description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
|
||||||
|
tags: ["Gebäude"],
|
||||||
|
headers: {
|
||||||
|
Authorization: {
|
||||||
|
description: "Ein gültiger Authentifizierungstoken",
|
||||||
|
required: true,
|
||||||
|
allowEmptyValue: false,
|
||||||
|
examples: {
|
||||||
|
Bearer: {
|
||||||
|
value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
async fetch(input, context, user) {
|
||||||
|
const { uid } = context.params;
|
||||||
|
|
||||||
|
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||||
|
where: {
|
||||||
|
uid,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
benutzer: true,
|
||||||
|
aufnahme: {
|
||||||
|
include: {
|
||||||
|
objekt: {
|
||||||
|
include: {
|
||||||
|
gebaeude_bilder: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rechnungen: true,
|
||||||
|
events: {
|
||||||
|
include: {
|
||||||
|
benutzer: {
|
||||||
|
select: {
|
||||||
|
uid: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
date: "asc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
!ausweis ||
|
||||||
|
(ausweis.benutzer_id !== null && ausweis.benutzer_id !== user.id)
|
||||||
|
) {
|
||||||
|
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
|
||||||
|
throw new APIError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Ausweis konnte nicht gefunden werden.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ausweis;
|
||||||
|
},
|
||||||
|
});
|
||||||
116
src/pages/api/objekt/[uid]/unterlagen.ts
Normal file
116
src/pages/api/objekt/[uid]/unterlagen.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||||
|
import { prisma, UnterlageSchema } from "@ibcornelsen/database/server";
|
||||||
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import { writeFileSync } from "fs";
|
||||||
|
|
||||||
|
export const PUT = defineApiRoute({
|
||||||
|
input: UnterlageSchema.omit({
|
||||||
|
objekt_id: true,
|
||||||
|
id: true,
|
||||||
|
uid: true
|
||||||
|
}).merge(z.object({
|
||||||
|
data: z.string(),
|
||||||
|
})),
|
||||||
|
output: z.object({
|
||||||
|
uid: z.string({ description: "Die UID der Unterlage." })
|
||||||
|
}),
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
async fetch({ data, name, kategorie, mime }, ctx, user) {
|
||||||
|
if (mime !== "application/pdf" && mime !== "image/png" && mime !== "image/jpeg") {
|
||||||
|
throw new APIError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Nicht unterstützter mimetype, unterstützt werden 'image/jpeg', 'image/png', 'application/pdf'."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let objekt = await prisma.objekt.findUnique({
|
||||||
|
where: {
|
||||||
|
uid: ctx.params.uid,
|
||||||
|
benutzer_id: user.id
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!objekt) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Objekt nicht gefunden oder gehört einem anderen Benutzer.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const buffer = Buffer.from(data, "base64");
|
||||||
|
|
||||||
|
const unterlage = await prisma.unterlage.create({
|
||||||
|
data: {
|
||||||
|
kategorie: kategorie,
|
||||||
|
objekt: {
|
||||||
|
connect: {
|
||||||
|
id: objekt.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
uid: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const filePath = fileURLToPath(new URL(`../../../../../persistent/unterlagen/${unterlage.uid}`, import.meta.url));
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeFileSync(filePath, buffer)
|
||||||
|
} catch(e) {
|
||||||
|
// Unterlage wurde nicht gespeichert, wir löschen den Eintrag wieder
|
||||||
|
await prisma.unterlage.delete({
|
||||||
|
where: {
|
||||||
|
uid: unterlage.uid
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Und geben einen Fehler zurück
|
||||||
|
throw new APIError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: "Unterlage konnte nicht gespeichert werden.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid: unterlage.uid
|
||||||
|
};
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const GET = defineApiRoute({
|
||||||
|
middleware: authorizationMiddleware,
|
||||||
|
output: z.array(UnterlageSchema.pick({
|
||||||
|
kategorie: true,
|
||||||
|
uid: true
|
||||||
|
})),
|
||||||
|
async fetch(input, ctx, user) {
|
||||||
|
const { uid } = ctx.params;
|
||||||
|
|
||||||
|
const objekt = await prisma.objekt.findUnique({
|
||||||
|
where: {
|
||||||
|
uid,
|
||||||
|
benutzer_id: user.id
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
benutzer_id: true,
|
||||||
|
unterlagen: {
|
||||||
|
select: {
|
||||||
|
kategorie: true,
|
||||||
|
uid: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!objekt) {
|
||||||
|
throw new APIError({
|
||||||
|
code: "FORBIDDEN",
|
||||||
|
message: "Objekt existiert nicht oder gehört einem anderen Benutzer."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return objekt.unterlagen
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -3,8 +3,8 @@ import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
|
|||||||
import { validateAccessTokenServer } from "#server/lib/validateAccessToken.js";
|
import { validateAccessTokenServer } from "#server/lib/validateAccessToken.js";
|
||||||
import { prisma } from "@ibcornelsen/database/server";
|
import { prisma } from "@ibcornelsen/database/server";
|
||||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||||
import { fileURLToPath } from "bun";
|
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
export const GET = defineApiRoute({
|
export const GET = defineApiRoute({
|
||||||
async fetch(input, context, transfer) {
|
async fetch(input, context, transfer) {
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
---
|
|
||||||
import UserLayout from "../../../layouts/UserLayout.astro";
|
|
||||||
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
|
|
||||||
import DashboardAusweisePruefenModule from "#modules/Dashboard/DashboardAusweisePruefenModule.svelte";
|
|
||||||
import { prisma } from "@ibcornelsen/database/server";
|
|
||||||
import { createCaller } from "#lib/caller";
|
|
||||||
|
|
||||||
const accessTokenValid = await validateAccessTokenServer(Astro);
|
|
||||||
|
|
||||||
if (!accessTokenValid) {
|
|
||||||
return Astro.redirect("/auth/login")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Nutzer darf nur auf diese Seite, wenn er die Rolle "admin" hat
|
|
||||||
|
|
||||||
const caller = createCaller(Astro);
|
|
||||||
|
|
||||||
const ausweise = await caller.v1.verbrauchsausweisWohnen.getMany({
|
|
||||||
limit: 25,
|
|
||||||
});
|
|
||||||
---
|
|
||||||
|
|
||||||
<UserLayout title="Dashboard">
|
|
||||||
<DashboardAusweisePruefenModule ausweise={ausweise} client:load></DashboardAusweisePruefenModule>
|
|
||||||
</UserLayout>
|
|
||||||
@@ -3,7 +3,7 @@ import { AufnahmeClient, BenutzerClient, ObjektClient, UploadedGebaeudeBild, Ver
|
|||||||
import UserLayout from "#layouts/UserLayout.astro";
|
import UserLayout from "#layouts/UserLayout.astro";
|
||||||
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
|
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
|
||||||
import DashboardAusweisePruefenModule from "#modules/Dashboard/DashboardAusweisePruefenModule.svelte";
|
import DashboardAusweisePruefenModule from "#modules/Dashboard/DashboardAusweisePruefenModule.svelte";
|
||||||
import { prisma } from "@ibcornelsen/database/server";
|
import { Enums, prisma } from "@ibcornelsen/database/server";
|
||||||
import { createCaller } from "src/astro-typesafe-api-caller";
|
import { createCaller } from "src/astro-typesafe-api-caller";
|
||||||
|
|
||||||
const caller = createCaller(Astro)
|
const caller = createCaller(Astro)
|
||||||
@@ -20,6 +20,10 @@ try {
|
|||||||
return Astro.redirect("/auth/login")
|
return Astro.redirect("/auth/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.rolle !== Enums.BenutzerRolle.ADMIN) {
|
||||||
|
return Astro.redirect("/dashboard")
|
||||||
|
}
|
||||||
|
|
||||||
const ausweise = await prisma.verbrauchsausweisWohnen.findMany({
|
const ausweise = await prisma.verbrauchsausweisWohnen.findMany({
|
||||||
where: {
|
where: {
|
||||||
benutzer: {
|
benutzer: {
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ export const GET: 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 pdfVerbrauchsausweisWohnen(ausweis, aufnahme, objekt, bilder, user);
|
pdf = await pdfVerbrauchsausweisWohnen(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt, bilder, user);
|
||||||
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
|
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
|
||||||
pdf = await pdfVerbrauchsausweisGewerbe(ausweis, aufnahme, objekt, bilder, user);
|
pdf = await pdfVerbrauchsausweisGewerbe(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt, bilder, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response(pdf, {
|
return new Response(pdf, {
|
||||||
@@ -92,10 +92,10 @@ export const POST: APIRoute = async (Astro) => {
|
|||||||
|
|
||||||
const caller = createCaller(Astro);
|
const caller = createCaller(Astro);
|
||||||
|
|
||||||
const ausweis = JSON.parse(params.get("ausweis"));
|
const ausweis = JSON.parse(params.get("ausweis") || "{}");
|
||||||
const aufnahme = JSON.parse(params.get("aufnahme"));
|
const aufnahme = JSON.parse(params.get("aufnahme") || "{}");
|
||||||
const objekt = JSON.parse(params.get("objekt"));
|
const objekt = JSON.parse(params.get("objekt") || "{}");
|
||||||
const bilder = JSON.parse(params.get("bilder"));
|
const bilder = JSON.parse(params.get("bilder") || "{}");
|
||||||
const ausweisart: Enums.Ausweisart = params.get("ausweisart")
|
const ausweisart: Enums.Ausweisart = params.get("ausweisart")
|
||||||
|
|
||||||
let user: BenutzerClient = {};
|
let user: BenutzerClient = {};
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
|
#formular-box {
|
||||||
|
@apply bg-white;
|
||||||
|
}
|
||||||
|
|
||||||
#formular-box{@apply bg-white;}
|
.formular-boxen {
|
||||||
|
@apply w-full ml-[2px] ring-2 ring-formular-rahmen py-4 px-0 sm:px-2 md:px-4 rounded-lg;
|
||||||
|
}
|
||||||
|
|
||||||
.formular-boxen{@apply w-full ml-[2px] ring-2 ring-formular-rahmen py-4 px-0 sm:px-2 md:px-4 rounded-lg}
|
.formular-abschnitt1 {
|
||||||
|
@apply text-[1.25rem] py-[1px] px-[10px] ml-[2px] text-secondary/80 bg-black/15 ring-2 ring-black/30 rounded-sm font-bold;
|
||||||
|
}
|
||||||
|
.formular-abschnitt2 {
|
||||||
|
@apply [font-size:_clamp(16px,1vw,28px)] pl-1 justify-self-start
|
||||||
|
md:[font-size:_clamp(20px,1.25vw,36px)];
|
||||||
|
}
|
||||||
|
|
||||||
|
.bereichs-label {
|
||||||
|
@apply px-4 sm:px-0 mt-6 mb-3;
|
||||||
|
}
|
||||||
|
|
||||||
.formular-abschnitt1{@apply text-[1.25rem] py-[1px] px-[10px] ml-[2px] text-secondary/80 bg-black/15 ring-2 ring-black/30 rounded-sm font-bold;}
|
.collapseBereich {
|
||||||
.formular-abschnitt2{@apply [font-size:_clamp(16px,1vw,28px)] pl-1 justify-self-start
|
@apply transition-all ease-in-out duration-200 h-[auto];
|
||||||
md:[font-size:_clamp(20px,1.25vw,36px)]
|
}
|
||||||
|
.bereich-box {
|
||||||
|
@apply w-full bg-gray-500/10 rounded-sm xl:rounded-md border-2 border-gray-500/15 pt-6 pb-8 px-4;
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.bereichs-label{@apply px-4 sm:px-0 mt-6 mb-3}
|
|
||||||
|
|
||||||
.collapseBereich{@apply transition-all ease-in-out duration-200 h-[auto]}
|
|
||||||
.bereich-box {@apply w-full bg-gray-500/10 rounded-sm xl:rounded-md border-2 border-gray-500/15 pt-6 pb-8 px-4;
|
|
||||||
|
|
||||||
transform-origin: top center;
|
transform-origin: top center;
|
||||||
/*background: linear-gradient(
|
/*background: linear-gradient(
|
||||||
@@ -28,18 +34,23 @@
|
|||||||
); */
|
); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-standard {
|
||||||
|
@apply w-full grid grid-cols-[1fr_25px] items-center relative mt-2;
|
||||||
|
}
|
||||||
|
.input-noHelp {
|
||||||
|
@apply w-full grid grid-cols-[1fr] items-center relative mt-2;
|
||||||
|
}
|
||||||
|
.input-checkboxen {
|
||||||
|
@apply h-[38px] grid grid-cols-[1fr_1fr] gap-2 items-center ring-1 ring-black/15 rounded-sm bg-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-row {
|
||||||
|
@apply w-full min-h-[38px] grid grid-cols-[1fr_1fr] sm:grid-cols-[1fr_1fr_1fr_1fr] items-center py-[6px] px-[10px] ring-1 ring-black/15 rounded-sm bg-white;
|
||||||
|
}
|
||||||
|
|
||||||
.input-standard{@apply w-full grid grid-cols-[1fr_25px] items-center relative mt-2}
|
.help-label {
|
||||||
.input-noHelp{@apply w-full grid grid-cols-[1fr] items-center relative mt-2}
|
@apply bg-black/15 rounded-e-sm ring-1 ring-black/15 self-stretch;
|
||||||
.input-checkboxen{@apply h-[38px] grid grid-cols-[1fr_1fr] gap-2 items-center ring-1 ring-black/15 rounded-sm bg-white}
|
}
|
||||||
|
|
||||||
.input-row{@apply w-full min-h-[38px] grid grid-cols-[1fr_1fr] sm:grid-cols-[1fr_1fr_1fr_1fr] items-center py-[6px] px-[10px] ring-1 ring-black/15 rounded-sm bg-white }
|
|
||||||
|
|
||||||
.help-label{@apply bg-black/15 rounded-e-sm ring-1 ring-black/15 self-stretch}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ input[type="email"],
|
|||||||
input[type="number"],
|
input[type="number"],
|
||||||
input[type="password"],
|
input[type="password"],
|
||||||
input[type="file"],
|
input[type="file"],
|
||||||
|
textarea,
|
||||||
select{
|
select{
|
||||||
@apply p-1 min-h-[38px] ring-1 ring-black/15 rounded-sm}
|
@apply p-1 min-h-[38px] ring-1 ring-black/15 rounded-sm}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user