Compare commits
35 Commits
VAOnScreen
...
49-plausib
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6d141a229 | ||
|
|
12d7f11c1b | ||
|
|
19d83c286e | ||
|
|
5b6fbf686b | ||
|
|
7bc549dfc4 | ||
|
|
4bfc4c4baf | ||
|
|
3997f288fa | ||
|
|
a1a0a8e2d9 | ||
|
|
0b735bcf4e | ||
|
|
cc5032e0e1 | ||
|
|
8af5ed39b1 | ||
|
|
25171210a5 | ||
|
|
28a3f9b57c | ||
|
|
63ae424665 | ||
|
|
eb41d87f1c | ||
|
|
b45206290f | ||
|
|
c3d9913cc7 | ||
|
|
918b470639 | ||
|
|
df8fa9cce1 | ||
|
|
39f4435386 | ||
|
|
80d62ffdc2 | ||
|
|
8c188a54fa | ||
|
|
e994383317 | ||
|
|
02e108140a | ||
|
|
538fc7eb01 | ||
|
|
976afd1cd4 | ||
|
|
f679f215cc | ||
|
|
9964fded85 | ||
|
|
4f479b9c6c | ||
|
|
00e283a01c | ||
|
|
26058e3205 | ||
|
|
db7cc9af33 | ||
|
|
f2be7a36bd | ||
|
|
022fe20524 | ||
|
|
0341ea4526 |
20
.github/workflows/build-and-test.yml
vendored
20
.github/workflows/build-and-test.yml
vendored
@@ -1,20 +0,0 @@
|
|||||||
name: Build and Test
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ dev ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Build the application
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- uses: oven-sh/setup-bun@v1
|
|
||||||
with:
|
|
||||||
bun-version: "latest"
|
|
||||||
- run: bun install
|
|
||||||
- run: bun run build
|
|
||||||
- run: bun run test:unit
|
|
||||||
- run: bun run test:e2e
|
|
||||||
21
.github/workflows/dev-pipeline.yml
vendored
21
.github/workflows/dev-pipeline.yml
vendored
@@ -1,27 +1,26 @@
|
|||||||
name: Dev Pipeline
|
name: Dev Pipeline
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
push:
|
push:
|
||||||
branches: [ dev ]
|
branches: [main]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy dev changes.
|
- uses: actions/checkout@v2
|
||||||
uses: appleboy/ssh-action@master
|
- uses: appleboy/ssh-action@master
|
||||||
with:
|
with:
|
||||||
host: "212.227.155.91"
|
host: ${{ secrets.DEV_HOST }}
|
||||||
username: "root"
|
username: ${{ secrets.DEV_USERNAME }}
|
||||||
password: "!2Zc727cI1"
|
password: ${{ secrets.DEV_PASSWORD }}
|
||||||
port: 22
|
port: 22
|
||||||
script: |
|
script: |
|
||||||
cd ~/apps/online-energieausweis
|
cd ~/online-energieausweis
|
||||||
git reset --hard HEAD
|
git reset --hard HEAD
|
||||||
git clean -f -d
|
git clean -f -d
|
||||||
git pull origin main
|
git pull origin main
|
||||||
git status
|
git status
|
||||||
npm install -g bun
|
|
||||||
bun install
|
|
||||||
bash build.sh
|
bash build.sh
|
||||||
27
.github/workflows/prod-pipeline.yml
vendored
27
.github/workflows/prod-pipeline.yml
vendored
@@ -1,27 +0,0 @@
|
|||||||
name: Production Deployment
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [ created ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Deploy to production.
|
|
||||||
uses: appleboy/ssh-action@master
|
|
||||||
with:
|
|
||||||
host: "212.227.155.91"
|
|
||||||
username: "root"
|
|
||||||
password: "!2Zc727cI1"
|
|
||||||
port: 22
|
|
||||||
script: |
|
|
||||||
cd ~/apps/online-energieausweis
|
|
||||||
git reset --hard HEAD
|
|
||||||
git clean -f -d
|
|
||||||
git pull origin main
|
|
||||||
git status
|
|
||||||
npm install -g bun
|
|
||||||
bun install
|
|
||||||
bash build.sh
|
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"i18n-ally.localesPaths": [
|
"i18n-ally.localesPaths": [
|
||||||
"public/locales"
|
"public/locales"
|
||||||
]
|
],
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib"
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ import mdx from "@astrojs/mdx";
|
|||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [/*astroI18next(),*/svelte(), tailwind(), mdx()],
|
integrations: [svelte(), tailwind(), mdx()],
|
||||||
outDir: "./dist",
|
outDir: "./dist",
|
||||||
output: "server",
|
output: "server",
|
||||||
vite: {
|
vite: {
|
||||||
|
|||||||
75
build.sh
75
build.sh
@@ -9,50 +9,55 @@ DB_USER="main"
|
|||||||
DB_PASSWORD="hHMP8cd^N3SnzGRR"
|
DB_PASSWORD="hHMP8cd^N3SnzGRR"
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
|
|
||||||
git_pull_force() {
|
# Wir gehen davon aus, dass die Änderungen bereits von GitHub gepullt wurden
|
||||||
git reset --hard HEAD
|
# Dieses Skript ist nur dafür gedacht, von GitHub bei einer Automation
|
||||||
git clean -f -d
|
# ausgeführt zu werden. Außerdem würde es nicht wirklich Sinn ergeben, wenn das
|
||||||
git pull origin main
|
# Build Skript sich die Änderungen am build Skript holen würde...
|
||||||
}
|
# Wir müssen alle lokalen Pakete verlinken
|
||||||
|
cd ../database
|
||||||
|
bun link
|
||||||
|
cd ../api
|
||||||
|
bun link
|
||||||
|
cd ../ui
|
||||||
|
bun link
|
||||||
|
cd ../database
|
||||||
|
bun install
|
||||||
|
cd ../api
|
||||||
|
bun install
|
||||||
|
cd ../ui
|
||||||
|
bun install
|
||||||
|
cd ../$APP_NAME
|
||||||
|
|
||||||
# Zuerst müssen wir neue Änderungen von GitHub pullen.
|
|
||||||
cd ~/apps/$APP_NAME
|
|
||||||
git_pull_force;
|
|
||||||
|
|
||||||
# Dann bauen wir das Docker Image unserer Application
|
# Als erstes linken wir das package mit bun, damit wir z.B. in online-energieausweis darauf zugreifen können.
|
||||||
cd ~/apps/$APP_NAME
|
bun link
|
||||||
|
# Dann installieren wir noch einmal alle dependencies, das ist besonders wichtig
|
||||||
|
# falls wir lokal verlinkte Projekte haben, sonst werden die nicht in unser
|
||||||
|
# docker image übernommen
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Dann stoppen wir unser altes docker image und bauen es neu.
|
||||||
docker stop $APP_NAME
|
docker stop $APP_NAME
|
||||||
docker rm $APP_NAME
|
docker rm $APP_NAME
|
||||||
docker build -t $APP_NAME .
|
docker build -t $APP_NAME .
|
||||||
|
|
||||||
# SECTION: Startup jobs zu crontab hinzufügen.
|
# Jeder unserer Applikationen hat ein Verzeichnis in dem alle Dateien dauerhaft,
|
||||||
# Erstmal den cronfile leeren.
|
# Versionsunabhängig gespeichert werden. Dieses legen wir hier an, falls es noch
|
||||||
crontab -r;
|
# nicht existiert.
|
||||||
|
PERSISTENT_DIR="${HOME}/persistent/${APP_NAME}";
|
||||||
# Alle builds schlagen fehl wenn die Datenbank nicht da ist, also muss der Container zuerst gebaut werden.
|
|
||||||
(crontab -l ; echo "@reboot sudo ~/database/build.sh &") | crontab -;
|
|
||||||
(crontab -l ; echo "@reboot sudo ~/apps/online-energieausweis/build.sh &") | crontab -;
|
|
||||||
(crontab -l ; echo "@reboot sudo ~/apps/layout-tool/build.sh &") | crontab -;
|
|
||||||
|
|
||||||
# Wir legen ein persistent directory an
|
|
||||||
PERSISTENT_DIR="${HOME}/persistent/online-energieausweis";
|
|
||||||
mkdir -p $PERSISTENT_DIR;
|
mkdir -p $PERSISTENT_DIR;
|
||||||
|
|
||||||
# Wir legen einen .env file für unsere letsencrypt keys an.
|
# TODO: Wir legen hier die .env Datei an, die die SSL Zertifikate enthält.
|
||||||
rm -f ~/apps/$APP_NAME/.env;
|
# rm -f ~/$APP_NAME/.env;
|
||||||
touch ~/apps/$APP_NAME/.env;
|
# touch ~/$APP_NAME/.env;
|
||||||
echo "PRIVATE_KEY=$(cat /etc/letsencrypt/live/ibcornelsen.de/privkey.pem | base64 | tr -d '\n')" >> ~/apps/$APP_NAME/.env;
|
# echo "PRIVATE_KEY=$(cat /etc/letsencrypt/live/ibcornelsen.de/privkey.pem | base64 | tr -d '\n')" >> ~/$APP_NAME/.env;
|
||||||
echo "CERTIFICATE=$(cat /etc/letsencrypt/live/ibcornelsen.de/fullchain.pem | base64 | tr -d '\n')" >> ~/apps/$APP_NAME/.env;
|
# echo "CERTIFICATE=$(cat /etc/letsencrypt/live/ibcornelsen.de/fullchain.pem | base64 | tr -d '\n')" >> ~/$APP_NAME/.env;
|
||||||
|
|
||||||
# Und starten unsere App wieder.
|
# Jetzt wo wir alle Vorbereitungen getroffen haben, starten wir das Docker Image und linken es mit der Datenbank.
|
||||||
docker run -d --name $APP_NAME --link $DB_CONTAINER_NAME \
|
docker run -d --name $APP_NAME --link $DB_CONTAINER_NAME \
|
||||||
-v "${PERSISTENT_DIR}:/persistent" \
|
-v "${PERSISTENT_DIR}:/persistent" \
|
||||||
-p "${APP_PORT}:80" \
|
-v "./node_modules/@ibcornelsen/database:/${APP_NAME}/node_modules/@ibcornelsen/database" \
|
||||||
-e DB_CONNECTION=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_CONTAINER_NAME}:${DB_PORT}/${DB_NAME} \
|
-v "./node_modules/@ibcornelsen/api:/${APP_NAME}/node_modules/@ibcornelsen/api" \
|
||||||
-e DB_PORT=${DB_PORT} \
|
-v "./node_modules/@ibcornelsen/ui:/${APP_NAME}/node_modules/@ibcornelsen/ui" \
|
||||||
--env-file ~/apps/${APP_NAME}/.env \
|
-p "${APP_PORT}:3000" \
|
||||||
$APP_NAME;
|
$APP_NAME;
|
||||||
|
|
||||||
# Crontab Updaten
|
|
||||||
cd ~/$APP_NAME
|
|
||||||
crontab .crontab
|
|
||||||
15
install.sh
Normal file
15
install.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
git clone https://github.com/IBCornelsen/online-energieausweis
|
||||||
|
git clone https://github.com/IBCornelsen/database
|
||||||
|
git clone https://github.com/IBCornelsen/api
|
||||||
|
|
||||||
|
cd ./database
|
||||||
|
bun link
|
||||||
|
bun install
|
||||||
|
|
||||||
|
cd ../api
|
||||||
|
bun link
|
||||||
|
bun install
|
||||||
|
|
||||||
|
cd ../online-energieausweis
|
||||||
|
bun link
|
||||||
|
bun install
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
layout: ../layouts/Layout.astro
|
layout; ../layouts/Layout.astro
|
||||||
title: AGB - online-energieausweis.org
|
title: AGB - online-energieausweis.org
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ layout: ../layouts/Layout.astro
|
|||||||
title: Energieausweis EnEV/GEG
|
title: Energieausweis EnEV/GEG
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
# EnEV Zusammenfassung (Archiv - Seit 1. Mai 2021 abgelöst durch GEG)
|
# EnEV Zusammenfassung (Archiv - Seit 1. Mai 2021 abgelöst durch GEG)
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
layout: ../layouts/Layout.astro
|
layout: ../layouts/Layout.astro
|
||||||
title: Welcher Energieausweis?
|
title: "Welcher Energieausweis?"
|
||||||
---
|
---
|
||||||
|
|
||||||
import { BoxWithHeading } from "@ibcornelsen/ui";
|
import { BoxWithHeading } from "@ibcornelsen/ui";
|
||||||
19
notes/ausweis-erstellung.md
Normal file
19
notes/ausweis-erstellung.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Ausweis Erstellung
|
||||||
|
|
||||||
|
Wenn ein neuer Nutzer auf unsere Seite kommt und einen Ausweis erstellen möchte muss er sich nicht unbedingt sofort registrieren. Um den Kunden ein reibungsloses Erlebnis zu bieten versuchen wir den Nutzer automatisch anzulegen, allerdings kann es sein, dass der Ausweis nicht weiter bearbeitet wird. In diesem Fall müssen wir den Ausweis nach einer Zeit wieder löschen, damit er nicht für immer in unserer Datenbank bleibt.
|
||||||
|
|
||||||
|
```tefcha
|
||||||
|
Nutzer Kommt auf unsere Seite
|
||||||
|
|
||||||
|
if Nutzer ist eingeloggt
|
||||||
|
Ausweis wird erstellt und Nutzer zugewiesen
|
||||||
|
else
|
||||||
|
Ausweis erstellen
|
||||||
|
-> Schritt 2
|
||||||
|
if Nutzer registriert sich
|
||||||
|
Ausweis wird verknüpft
|
||||||
|
else
|
||||||
|
Ausweis nach einer Woche gelöscht
|
||||||
|
|
||||||
|
usw...
|
||||||
|
```
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^0.18.4",
|
"@astrojs/mdx": "^2.1.1",
|
||||||
"@astrojs/node": "^5.1.4",
|
"@astrojs/node": "^5.1.4",
|
||||||
"@astrojs/svelte": "^2.2.0",
|
"@astrojs/svelte": "^2.2.0",
|
||||||
"@astrojs/tailwind": "^3.1.3",
|
"@astrojs/tailwind": "^3.1.3",
|
||||||
@@ -51,17 +51,21 @@
|
|||||||
"katex": "^0.16.7",
|
"katex": "^0.16.7",
|
||||||
"knex": "^2.4.2",
|
"knex": "^2.4.2",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
|
"moment-timezone": "^0.5.45",
|
||||||
"pg": "^8.11.0",
|
"pg": "^8.11.0",
|
||||||
"radix-svelte-icons": "^1.0.0",
|
"radix-svelte-icons": "^1.0.0",
|
||||||
|
"remark-frontmatter": "^5.0.0",
|
||||||
"sass": "^1.62.1",
|
"sass": "^1.62.1",
|
||||||
"svelte": "^3.59.1",
|
"svelte": "^3.59.1",
|
||||||
"svelte-dialogs": "^1.2.2",
|
"svelte-dialogs": "^1.2.2",
|
||||||
|
"svelte-katex": "^0.1.2",
|
||||||
"svelte-preprocess": "^5.0.3",
|
"svelte-preprocess": "^5.0.3",
|
||||||
"svelte-ripple-action": "^1.0.5",
|
"svelte-ripple-action": "^1.0.5",
|
||||||
"svelte-tabs": "^1.1.0",
|
"svelte-tabs": "^1.1.0",
|
||||||
"tailwindcss": "^3.3.2",
|
"tailwindcss": "^3.3.2",
|
||||||
"trpc-openapi": "^1.2.0",
|
"trpc-openapi": "^1.2.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
|
"uuid-validate": "^0.0.3",
|
||||||
"vite-tsconfig-paths": "^4.2.0",
|
"vite-tsconfig-paths": "^4.2.0",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
|
|||||||
65
src/client/lib/bilderHochladen.ts
Normal file
65
src/client/lib/bilderHochladen.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
|
import { addNotification, updateNotification } from "@ibcornelsen/ui";
|
||||||
|
import { client } from "src/trpc";
|
||||||
|
|
||||||
|
export async function bilderHochladen(images: (UploadedGebaeudeBild & { base64?: string })[], gebaeude_uid: string) {
|
||||||
|
if (images.length == 0) {
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn Bilder hochgeladen werden konvertieren wir sie zu base64, das heißt, dass die base64 Eigenschaft bei diesen Bildern
|
||||||
|
// existiert. Das müssen wir TypeScript nur wissen lassen, damit es uns in Ruhe lässt.
|
||||||
|
const imagesToUpload = images.filter(image => !image.uid || image.update) as unknown as { base64: string, kategorie: string, uid?: string, update: boolean }[];
|
||||||
|
|
||||||
|
if (imagesToUpload.length == 0) {
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alle Bilder hochladen
|
||||||
|
const notification = addNotification({
|
||||||
|
dismissable: false,
|
||||||
|
message: "Bilder hochladen.",
|
||||||
|
subtext: `${imagesToUpload.length} Bilder werden hochgeladen, bitte haben sie Geduld.`,
|
||||||
|
timeout: 0,
|
||||||
|
type: "info"
|
||||||
|
})
|
||||||
|
for (let i = 0; i < imagesToUpload.length; i++) {
|
||||||
|
const image = imagesToUpload[i];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (image.update) {
|
||||||
|
await client.v1.bilder.update.mutate({
|
||||||
|
uid: image.uid as string,
|
||||||
|
base64: image.base64,
|
||||||
|
kategorie: image.kategorie as Enums.BilderKategorie
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const response = await client.v1.bilder.upload.mutate({
|
||||||
|
base64: image.base64,
|
||||||
|
kategorie: image.kategorie as Enums.BilderKategorie,
|
||||||
|
gebaeude_uid
|
||||||
|
})
|
||||||
|
|
||||||
|
image.uid = response.uid
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNotification(notification, {
|
||||||
|
dismissable: true,
|
||||||
|
message: "Bild hochgeladen.",
|
||||||
|
subtext: `${i + 1}/${imagesToUpload.length} Bildern wurden erfolgreich hochgeladen.`,
|
||||||
|
timeout: 3000
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
updateNotification(notification, {
|
||||||
|
dismissable: true,
|
||||||
|
message: "Bild konnte nicht hochgeladen werden.",
|
||||||
|
subtext: `Eines ihrer Bilder konnte nicht hochgeladen werden. Wir haben bereits ein Ticket erstellt und melden uns so schnell wie möglich bei ihnen.`,
|
||||||
|
timeout: 15000,
|
||||||
|
type: "error"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images;
|
||||||
|
}
|
||||||
86
src/client/lib/verbrauchsausweisWohnenSpeichern.ts
Normal file
86
src/client/lib/verbrauchsausweisWohnenSpeichern.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import {
|
||||||
|
BenutzerClient,
|
||||||
|
GebaeudeAufnahmeClient,
|
||||||
|
GebaeudeClient,
|
||||||
|
UploadedGebaeudeBild,
|
||||||
|
VerbrauchsausweisWohnenClient,
|
||||||
|
} from "#components/Ausweis/types";
|
||||||
|
|
||||||
|
import { exclude } from "#lib/exclude";
|
||||||
|
import { client } from "src/trpc";
|
||||||
|
import { bilderHochladen } from "./bilderHochladen";
|
||||||
|
import { addNotification } from "@ibcornelsen/ui";
|
||||||
|
|
||||||
|
export async function verbrauchsausweisWohnenSpeichern(
|
||||||
|
ausweis: VerbrauchsausweisWohnenClient,
|
||||||
|
gebaeude: GebaeudeClient,
|
||||||
|
gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient,
|
||||||
|
images: (UploadedGebaeudeBild & { base64?: string })[],
|
||||||
|
user: BenutzerClient
|
||||||
|
) {
|
||||||
|
if (ausweis.uid) {
|
||||||
|
// Anscheinend wurde der Ausweis bereits erstellt und hat eine UID.
|
||||||
|
// Jetzt müssen wir ihn nun nur noch abspeichern.
|
||||||
|
try {
|
||||||
|
await client.v1.verbrauchsausweisWohnen[2016].speichern.mutate({
|
||||||
|
...ausweis,
|
||||||
|
gebaeude_aufnahme_allgemein: {
|
||||||
|
...exclude(
|
||||||
|
gebaeude_aufnahme_allgemein,
|
||||||
|
["erstellungsdatum", "events", "ausstellungsdatum", "rechnungen"]
|
||||||
|
),
|
||||||
|
gebaeude_stammdaten: {
|
||||||
|
...exclude(gebaeude, [
|
||||||
|
"gebaeude_bilder",
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
images = await bilderHochladen(images, gebaeude.uid);
|
||||||
|
|
||||||
|
return { uid: ausweis.uid, gebaeude_uid: gebaeude.uid, gebaeude_aufnahme_uid: gebaeude_aufnahme_allgemein.uid };
|
||||||
|
} catch (e) {
|
||||||
|
// TODO: Ticket mit Fehldermeldung abschicken.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Wir speichern den Ausweis ab und leiten auf die "ausweis-gespeichert" Seite weiter.
|
||||||
|
try {
|
||||||
|
const response =
|
||||||
|
await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
|
||||||
|
...ausweis,
|
||||||
|
gebaeude_aufnahme_allgemein: {
|
||||||
|
...gebaeude_aufnahme_allgemein,
|
||||||
|
gebaeude_stammdaten: {
|
||||||
|
...gebaeude,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
images = await bilderHochladen(images, response.gebaeude_uid);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (e: any) {
|
||||||
|
await client.v1.tickets.erstellen.mutate({
|
||||||
|
titel: "Ausweis konnte nicht gespeichert werden",
|
||||||
|
beschreibung: e.stack,
|
||||||
|
email: user.email ?? "",
|
||||||
|
metadata: JSON.stringify({
|
||||||
|
ausweis,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
// TODO: Ticket mit Fehldermeldung abschicken.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addNotification({
|
||||||
|
dismissable: false,
|
||||||
|
message:
|
||||||
|
"Ausweis konnte nicht gespeichert werden, bitte versuchen sie es erneut.",
|
||||||
|
subtext:
|
||||||
|
"Sollte das Problem weiterhin bestehen, kontaktieren sie bitte den Support.",
|
||||||
|
timeout: 6000,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@@ -1,17 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { BedarfsausweisWohnen, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
|
|
||||||
import { Buffer } from "buffer";
|
import { Buffer } from "buffer";
|
||||||
import { GebaeudeClient, VerbrauchsausweisWohnenClient } from "./Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "./Ausweis/types";
|
||||||
|
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
export let gebaeude: GebaeudeClient;
|
|
||||||
|
|
||||||
let base64: string = "";
|
$: base64 = Buffer.from(JSON.stringify(ausweis), "utf-8").toString("base64")
|
||||||
$: {
|
|
||||||
if (ausweis && gebaeude) {
|
|
||||||
base64 = Buffer.from(JSON.stringify({...ausweis, gebaeude_stammdaten: gebaeude}), "utf-8").toString("base64");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/ansichtsausweis?base64={base64}">
|
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/ansichtsausweis?base64={base64}">
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
import ImageGrid from "../ImageGrid.svelte";
|
import ImageGrid from "../ImageGrid.svelte";
|
||||||
import {
|
import {
|
||||||
Enums,
|
Enums,
|
||||||
type BedarfsausweisWohnen,
|
|
||||||
type VerbrauchsausweisGewerbe,
|
|
||||||
} from "@ibcornelsen/database/client";
|
} from "@ibcornelsen/database/client";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -15,12 +13,8 @@
|
|||||||
VerbrauchsausweisWohnenClient,
|
VerbrauchsausweisWohnenClient,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export let ausweis:
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
| VerbrauchsausweisWohnenClient
|
|
||||||
| VerbrauchsausweisGewerbe
|
|
||||||
| BedarfsausweisWohnen;
|
|
||||||
export let gebaeude: GebaeudeClient;
|
export let gebaeude: GebaeudeClient;
|
||||||
|
|
||||||
export let images: UploadedGebaeudeBild[] = [];
|
export let images: UploadedGebaeudeBild[] = [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -53,8 +47,8 @@
|
|||||||
<hr class="trenner_form_100" />
|
<hr class="trenner_form_100" />
|
||||||
|
|
||||||
<div class="flex flex-row gap-4">
|
<div class="flex flex-row gap-4">
|
||||||
<AnsichtsausweisButton {ausweis} {gebaeude} />
|
<AnsichtsausweisButton {ausweis} />
|
||||||
<DatenblattButton {ausweis} {gebaeude} />
|
<DatenblattButton {ausweis} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@
|
|||||||
required
|
required
|
||||||
bind:value={gebaeude_aufnahme_allgemein.saniert}
|
bind:value={gebaeude_aufnahme_allgemein.saniert}
|
||||||
>
|
>
|
||||||
<option disabled>Bitte auswählen</option>
|
<option disabled selected value={false}>Bitte auswählen</option>
|
||||||
<option value={true}>saniert</option>
|
<option value={true}>saniert</option>
|
||||||
<option value={false}>unsaniert</option>
|
<option value={false}>unsaniert</option>
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -5,10 +5,6 @@
|
|||||||
import DaemmungImage from "./DaemmungImage.svelte";
|
import DaemmungImage from "./DaemmungImage.svelte";
|
||||||
import FensterImage from "./FensterImage.svelte";
|
import FensterImage from "./FensterImage.svelte";
|
||||||
import Label from "../Label.svelte";
|
import Label from "../Label.svelte";
|
||||||
import type {
|
|
||||||
BedarfsausweisWohnen,
|
|
||||||
VerbrauchsausweisGewerbe,
|
|
||||||
} from "@ibcornelsen/database/client";
|
|
||||||
import {
|
import {
|
||||||
GebaeudeAufnahmeClient,
|
GebaeudeAufnahmeClient,
|
||||||
GebaeudeClient,
|
GebaeudeClient,
|
||||||
@@ -18,10 +14,7 @@
|
|||||||
|
|
||||||
export let gebaeude: GebaeudeClient;
|
export let gebaeude: GebaeudeClient;
|
||||||
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
|
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
|
||||||
export let ausweis:
|
export let ausweis: VerbrauchsausweisWohnenClient
|
||||||
| VerbrauchsausweisWohnenClient
|
|
||||||
| VerbrauchsausweisGewerbe
|
|
||||||
| BedarfsausweisWohnen;
|
|
||||||
export let images: UploadedGebaeudeBild[];
|
export let images: UploadedGebaeudeBild[];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -388,4 +381,4 @@
|
|||||||
als PDF anschauen</Label
|
als PDF anschauen</Label
|
||||||
>
|
>
|
||||||
|
|
||||||
<AusweisPreviewContainer {ausweis} {gebaeude} />
|
<AusweisPreviewContainer bind:images bind:ausweis bind:gebaeude />
|
||||||
|
|||||||
@@ -1,17 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||||
import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte";
|
import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte";
|
||||||
import { BedarfsausweisWohnenClient, GebaeudeAufnahmeClient, GebaeudeClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "./types";
|
import {
|
||||||
|
BedarfsausweisWohnenClient,
|
||||||
|
GebaeudeAufnahmeClient,
|
||||||
|
GebaeudeClient,
|
||||||
|
VerbrauchsausweisGewerbeClient,
|
||||||
|
VerbrauchsausweisWohnenClient,
|
||||||
|
} from "./types";
|
||||||
import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte";
|
import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte";
|
||||||
|
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
|
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
|
||||||
|
export let gebaeude: GebaeudeClient;
|
||||||
|
|
||||||
let maxPerformance = 250;
|
let maxPerformance = 250;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We use linear interpolation to scale the value between the given boundaries.
|
* We use linear interpolation to scale the value between the given boundaries.
|
||||||
*/
|
*/
|
||||||
function centerValueBetweenBoundaries(value: number, newMinimum: number, newMaximum: number, oldMinimum: number = 0, oldMaximum: number = 100): number {
|
function centerValueBetweenBoundaries(
|
||||||
|
value: number,
|
||||||
|
newMinimum: number,
|
||||||
|
newMaximum: number,
|
||||||
|
oldMinimum: number = 0,
|
||||||
|
oldMaximum: number = 100
|
||||||
|
): number {
|
||||||
// Calculate the center point of the current range
|
// Calculate the center point of the current range
|
||||||
const center = (oldMinimum + oldMaximum) / 2;
|
const center = (oldMinimum + oldMaximum) / 2;
|
||||||
|
|
||||||
@@ -31,33 +45,62 @@
|
|||||||
const scaledValue = shiftedValue * scalingFactor;
|
const scaledValue = shiftedValue * scalingFactor;
|
||||||
|
|
||||||
// Shift the scaled value back to the center of the new range
|
// Shift the scaled value back to the center of the new range
|
||||||
const centeredValue = scaledValue + ((newMaximum + newMinimum) / 2);
|
const centeredValue = scaledValue + (newMaximum + newMinimum) / 2;
|
||||||
|
|
||||||
return centeredValue;
|
return centeredValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let translation_1 = 0;
|
let translation_1 = 0;
|
||||||
let translation_2 = 0;
|
let translation_2 = 0;
|
||||||
$: {
|
$: {
|
||||||
(async () => {
|
(async () => {
|
||||||
const result = (await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis));
|
const result = await endEnergieVerbrauchVerbrauchsausweis_2016({
|
||||||
|
...ausweis,
|
||||||
|
gebaeude_aufnahme_allgemein: {
|
||||||
|
...gebaeude_aufnahme_allgemein,
|
||||||
|
gebaeude_stammdaten: gebaeude,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(result, ausweis);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
//const primaerEnergieVerbrauch = (await ausweis.primaerEnergieBedarf);
|
translation_1 = Math.max(
|
||||||
translation_1 = Math.max(0, Math.min(100, result.endEnergieVerbrauchGesamt / maxPerformance * 100))
|
0,
|
||||||
//translation_2 = Math.max(0, Math.min(100, primaerEnergieVerbrauch / maxPerformance * 100))
|
Math.min(
|
||||||
})()
|
100,
|
||||||
|
(result.endEnergieVerbrauchGesamt / maxPerformance) * 100
|
||||||
|
)
|
||||||
|
);
|
||||||
|
translation_2 = Math.max(0, Math.min(100, result.primaerEnergieVerbrauchGesamt / maxPerformance * 100))
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full rounded-lg border-[#ffcc03] border-2 relative p-2">
|
<div class="w-full rounded-lg border-[#ffcc03] border-2 relative p-2">
|
||||||
<img src="/images/SKALA-910.png" alt="Energieeffizienz Skala">
|
<img src="/images/SKALA-910.png" alt="Energieeffizienz Skala" />
|
||||||
<ThickArrowDown size={28} class="fill-base-content absolute top-1 transition-left duration-1000 ease-in-out"
|
<ThickArrowDown
|
||||||
style="left: {translation_1}%; transform: translateX({centerValueBetweenBoundaries(translation_1, 50, -150, 0, 100)}%)" />
|
size={28}
|
||||||
<ThickArrowUp size={28} class="fill-base-content absolute bottom-1 transition-left duration-1000 ease-in-out"
|
class="fill-base-content absolute top-1 transition-left duration-1000 ease-in-out"
|
||||||
style="left: {translation_2}%; transform: translateX({centerValueBetweenBoundaries(translation_2, 50, -150, 0, 100)}%)" />
|
style="left: {translation_1}%; transform: translateX({centerValueBetweenBoundaries(
|
||||||
|
translation_1,
|
||||||
|
50,
|
||||||
|
-150,
|
||||||
|
0,
|
||||||
|
100
|
||||||
|
)}%)"
|
||||||
|
/>
|
||||||
|
<ThickArrowUp
|
||||||
|
size={28}
|
||||||
|
class="fill-base-content absolute bottom-1 transition-left duration-1000 ease-in-out"
|
||||||
|
style="left: {translation_2}%; transform: translateX({centerValueBetweenBoundaries(
|
||||||
|
translation_2,
|
||||||
|
50,
|
||||||
|
-150,
|
||||||
|
0,
|
||||||
|
100
|
||||||
|
)}%)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -4,13 +4,20 @@
|
|||||||
import Label from "../Label.svelte";
|
import Label from "../Label.svelte";
|
||||||
import fuelList from "./brennstoffListe";
|
import fuelList from "./brennstoffListe";
|
||||||
import { auditVerbrauchAbweichung } from "../Verbrauchsausweis/audits/VerbrauchAbweichung";
|
import { auditVerbrauchAbweichung } from "../Verbrauchsausweis/audits/VerbrauchAbweichung";
|
||||||
import type { VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
|
|
||||||
import { GebaeudeAufnahmeClient, GebaeudeClient, VerbrauchsausweisWohnenClient } from "./types";
|
import { GebaeudeAufnahmeClient, GebaeudeClient, VerbrauchsausweisWohnenClient } from "./types";
|
||||||
|
|
||||||
let availableYears = [
|
export let gebaeude: GebaeudeClient;
|
||||||
2018, 2019,
|
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
|
||||||
];
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
let availableMonths = [
|
// Wir dürfen bis zu 4.5 Jahre alte Klimafaktoren benutzen, also nehmen wir alle Monate seitdem und generieren daraus die Auswahl.
|
||||||
|
// Allerdings müssen wir auch berücksichtigen, dass wir drei folgende Jahre brauchen, also
|
||||||
|
// kann der Nutzer nur 36 + 18 Monate zurückgehen.
|
||||||
|
let availableDates: {
|
||||||
|
year: number;
|
||||||
|
month: number;
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
|
let monthNames = [
|
||||||
"Januar",
|
"Januar",
|
||||||
"Februar",
|
"Februar",
|
||||||
"März",
|
"März",
|
||||||
@@ -25,9 +32,15 @@
|
|||||||
"Dezember",
|
"Dezember",
|
||||||
];
|
];
|
||||||
|
|
||||||
export let gebaeude: GebaeudeClient;
|
const startDate = moment(ausweis.gebaeude_aufnahme_allgemein.erstellungsdatum || Date.now()).subtract(4, "years").subtract(6, "months");
|
||||||
export let gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient;
|
const endDate = moment(ausweis.gebaeude_aufnahme_allgemein.erstellungsdatum || Date.now()).subtract(3, "years");
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe;
|
|
||||||
|
for (let m = moment(startDate); m.isBefore(endDate); m.add(1, "month")) {
|
||||||
|
availableDates.push({
|
||||||
|
year: m.year(),
|
||||||
|
month: m.month(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const fuelMap: Record<string, string[]> = {};
|
const fuelMap: Record<string, string[]> = {};
|
||||||
for (const fuel of fuelList) {
|
for (const fuel of fuelList) {
|
||||||
@@ -36,14 +49,15 @@
|
|||||||
fuelMap[fuel[0]].push(fuel[1]);
|
fuelMap[fuel[0]].push(fuel[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let month: string = "01";
|
|
||||||
let year: string = "2018";
|
let month = ausweis.startdatum?.getMonth() || null;
|
||||||
|
let year = ausweis.startdatum?.getFullYear() || null;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (month && year) {
|
if (typeof month === "number" && typeof year === "number") {
|
||||||
ausweis.startdatum = moment(`${month}.01.${year}`).toDate();
|
// Wir addieren einfach 2 Tage auf das Datum, falls der Nutzer außerhalb Deutschlands und in einer anderen Zeitzone ist.
|
||||||
console.log(ausweis.startdatum);
|
// NOTE: Das ist eine grauenvolle Lösung aber alle anderen funktionieren irgendwie nicht...
|
||||||
|
ausweis.startdatum = moment().set("month", month).set("year", year).startOf("month").add(2, "days").toDate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,9 +184,18 @@
|
|||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option>auswählen</option>
|
<option>auswählen</option>
|
||||||
{#each availableMonths as m, i}
|
{#if year !== null}
|
||||||
<option value={i + 1}>{m}</option>
|
{#each availableDates.filter(date => date.year == year) as date}
|
||||||
|
<option value={date.month}>{monthNames[date.month]}</option>
|
||||||
{/each}
|
{/each}
|
||||||
|
{:else}
|
||||||
|
{#each Array.from(availableDates.reduce((a,c) => {
|
||||||
|
a.add(c.month);
|
||||||
|
return a;
|
||||||
|
}, new Set())) as month}
|
||||||
|
<option value={month}>{monthNames[month]}</option>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
@@ -182,8 +205,11 @@
|
|||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option>auswählen</option>
|
<option>auswählen</option>
|
||||||
{#each availableYears as y}
|
{#each Array.from(availableDates.reduce((a,c) => {
|
||||||
<option value={y}>{y}</option>
|
a.add(c.year);
|
||||||
|
return a;
|
||||||
|
}, new Set())) as year}
|
||||||
|
<option value={year}>{year}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,7 +268,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch *</span>
|
||||||
<input
|
<input
|
||||||
name="verbrauch_1"
|
name="verbrauch_1"
|
||||||
type="number"
|
type="number"
|
||||||
@@ -252,7 +278,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch *</span>
|
||||||
<input
|
<input
|
||||||
name="verbrauch_2"
|
name="verbrauch_2"
|
||||||
type="number"
|
type="number"
|
||||||
@@ -262,7 +288,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<span>Verbrauch</span>
|
<span>Verbrauch *</span>
|
||||||
<input
|
<input
|
||||||
name="verbrauch_3"
|
name="verbrauch_3"
|
||||||
type="number"
|
type="number"
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ import { AppRouter } from "@ibcornelsen/api";
|
|||||||
import { Benutzer, GebaeudeBilder } from "@ibcornelsen/database/client";
|
import { Benutzer, GebaeudeBilder } from "@ibcornelsen/database/client";
|
||||||
import { inferProcedureInput, inferProcedureOutput } from "@trpc/server";
|
import { inferProcedureInput, inferProcedureOutput } from "@trpc/server";
|
||||||
|
|
||||||
export type UploadedGebaeudeBild = Omit<
|
export type UploadedGebaeudeBild = inferProcedureOutput<
|
||||||
GebaeudeBilder,
|
AppRouter["v1"]["verbrauchsausweisWohnen"]["get"]
|
||||||
"id" | "gebaeude_stammdaten_id" | "uid"
|
>["gebaeude_aufnahme_allgemein"]["gebaeude_stammdaten"]["gebaeude_bilder"][0] & { base64?: string, update?: boolean };
|
||||||
> &
|
|
||||||
({ base64: string; uid?: string });
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,23 +6,23 @@
|
|||||||
} from "./Ausweis/types.js";
|
} from "./Ausweis/types.js";
|
||||||
import AusweisPruefenTooltip from "./AusweisPruefenTooltip.svelte";
|
import AusweisPruefenTooltip from "./AusweisPruefenTooltip.svelte";
|
||||||
import { addNotification } from "./NotificationProvider/shared";
|
import { addNotification } from "./NotificationProvider/shared";
|
||||||
|
import { CheckCircled, CrossCircled, Image } from "radix-svelte-icons";
|
||||||
|
import ChevronDown from "radix-svelte-icons/src/lib/icons/ChevronDown.svelte";
|
||||||
|
|
||||||
|
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
export let calculations: Awaited<
|
export let calculations: Awaited<
|
||||||
ReturnType<typeof endEnergieVerbrauchVerbrauchsausweis_2016>
|
ReturnType<typeof endEnergieVerbrauchVerbrauchsausweis_2016>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
console.log(ausweis);
|
||||||
|
|
||||||
const gebaeude_aufnahme_allgemein = ausweis.gebaeude_aufnahme_allgemein
|
const gebaeude_aufnahme_allgemein = ausweis.gebaeude_aufnahme_allgemein
|
||||||
|
|
||||||
|
|
||||||
const ausweisArt = "VA"; // TODO: Das ist ein Platzhalter, hier muss die Ausweisart aus dem Ausweisobjekt kommen
|
const ausweisArt = "VA"; // TODO: Das ist ein Platzhalter, hier muss die Ausweisart aus dem Ausweisobjekt kommen
|
||||||
|
|
||||||
|
const images = ausweis.gebaeude_aufnahme_allgemein.gebaeude_stammdaten.gebaeude_bilder;
|
||||||
|
|
||||||
try {
|
|
||||||
// TODO: In Zukunft sollen die Bilder von unserer API kommen, das ist allerdings noch nicht ganz fertig.
|
|
||||||
// images = JSON.parse(ausweis.images)
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
let verbrauchWWGesamt_1 = "";
|
let verbrauchWWGesamt_1 = "";
|
||||||
let verbrauchWWGesamt_2 = "";
|
let verbrauchWWGesamt_2 = "";
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
|
|
||||||
tooltip3Z1 = "Wohnfläche in m²";
|
tooltip3Z1 = "Wohnfläche in m²";
|
||||||
tooltip3Z2 =
|
tooltip3Z2 =
|
||||||
gebaeude_aufnahme_allgemein.faktorKeller +
|
ausweis.faktorKeller +
|
||||||
" x " +
|
" x " +
|
||||||
gebaeude_aufnahme_allgemein.flaeche +
|
gebaeude_aufnahme_allgemein.flaeche +
|
||||||
" m² Energetische Nutzfläche (Keller " +
|
" m² Energetische Nutzfläche (Keller " +
|
||||||
@@ -448,17 +448,32 @@
|
|||||||
|
|
||||||
ausweis = ausweis;
|
ausweis = ausweis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let bilderModal: HTMLDialogElement;
|
||||||
|
let infoVisible = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<table class="table table-row border">
|
<div class="border rounded-box">
|
||||||
|
<table class="table table-row">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td width="30px"
|
<td><button on:click={() => infoVisible = !infoVisible}><ChevronDown size={22} class="transition-all {infoVisible ? "" : "rotate-180"}"></ChevronDown></button></td>
|
||||||
><img
|
<td class="w-6 px-2"
|
||||||
src="{StatusIcon}"
|
>
|
||||||
alt="Status"
|
{#if gebaeude_aufnahme_allgemein.erledigt}
|
||||||
class="w-8 h-8 max-w-8 max-h-8"
|
<div class="tooltip" data-tip="Ausweis wurde ausgestellt">
|
||||||
/>{zurueckGestellt}</td
|
<div class="rounded-full w-6 h-6 bg-success"></div>
|
||||||
|
</div>
|
||||||
|
{:else if gebaeude_aufnahme_allgemein.bestellt}
|
||||||
|
<div class="tooltip" data-tip="Ausweis wurde bestellt">
|
||||||
|
<div class="rounded-full w-6 h-6 bg-warning"></div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="tooltip" data-tip="Ausweis ist in Bearbeitung">
|
||||||
|
<div class="rounded-full w-6 h-6 bg-error"></div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</td
|
||||||
>
|
>
|
||||||
<td width="150px"
|
<td width="150px"
|
||||||
>
|
>
|
||||||
@@ -468,7 +483,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<span>{gebaeude_aufnahme_allgemein.gebaeudetyp}, Einheiten: {gebaeude_aufnahme_allgemein.einheiten}</span>
|
<span>{gebaeude_aufnahme_allgemein.gebaeudetyp}, Einheiten: {gebaeude_aufnahme_allgemein.einheiten}</span>
|
||||||
</div>
|
</div>
|
||||||
<span>{ausweisArt} - {ausweis.uid.split("-")[0]}</span>
|
<span>{ausweisArt} - {gebaeude_aufnahme_allgemein.id}</span>
|
||||||
<span>{moment(gebaeude_aufnahme_allgemein.erstellungsdatum).format("DD.MM.YYYY")}</span>
|
<span>{moment(gebaeude_aufnahme_allgemein.erstellungsdatum).format("DD.MM.YYYY")}</span>
|
||||||
</AusweisPruefenTooltip></td
|
</AusweisPruefenTooltip></td
|
||||||
>
|
>
|
||||||
@@ -491,7 +506,7 @@
|
|||||||
<div slot="tooltip">
|
<div slot="tooltip">
|
||||||
<span>Wohnfläche in m²</span>
|
<span>Wohnfläche in m²</span>
|
||||||
<br>
|
<br>
|
||||||
<span>{gebaeude_aufnahme_allgemein.faktorKeller} x {gebaeude_aufnahme_allgemein.flaeche}m² Energetische Nutzfläche (Keller {gebaeude_aufnahme_allgemein.keller}) in m²</span>
|
<span>{ausweis.faktorKeller} x {gebaeude_aufnahme_allgemein.flaeche}m² Energetische Nutzfläche (Keller {gebaeude_aufnahme_allgemein.keller}) in m²</span>
|
||||||
</div>
|
</div>
|
||||||
<span>{gebaeude_aufnahme_allgemein.flaeche}</span>
|
<span>{gebaeude_aufnahme_allgemein.flaeche}</span>
|
||||||
<span><strong>{calculations?.energetische_nutzfläche}</strong></span>
|
<span><strong>{calculations?.energetische_nutzfläche}</strong></span>
|
||||||
@@ -662,31 +677,44 @@
|
|||||||
</AusweisPruefenTooltip>
|
</AusweisPruefenTooltip>
|
||||||
</td
|
</td
|
||||||
>
|
>
|
||||||
<td title="Gebäudebilder anzeigen" width="35px"
|
<td title="Gebäudebilder anzeigen"
|
||||||
><div
|
><!-- Open the modal using ID.showModal() method -->
|
||||||
class="imagePreview"
|
<button class="btn btn-square" on:click={() => bilderModal.showModal()}><Image size={22}></Image></button>
|
||||||
data-imagePreview="{imagePreview}"
|
<dialog bind:this={bilderModal} class="modal">
|
||||||
>
|
<div class="modal-box flex flex-row gap-4 items-center justify-center">
|
||||||
<img
|
{#if images.length === 0}
|
||||||
src="/images/dashboard/SymbolBilder.svg"
|
<div class="flex flex-col gap-4 items-center justify-center">
|
||||||
alt="Gebäudebilder"
|
<p>Für diesen Ausweis sind noch keine Bilder vorhanden.</p>
|
||||||
width="35"
|
<button class="btn btn-primary" tabindex="0">Erinnerung Verschicken</button>
|
||||||
height="35"
|
|
||||||
/>
|
|
||||||
</div></td
|
|
||||||
>
|
|
||||||
<td width="30px"
|
|
||||||
><div class="checkTextPreviewButton">
|
|
||||||
<img src="{symbolPruefung}" alt="Boxpruefung" />
|
|
||||||
<div
|
|
||||||
class="checkTextPreview"
|
|
||||||
style="display:none; position: absolute; background-color: black; color: white; padding: 10px; border-radius: 5px; max-width: 450px; z-index:9999;"
|
|
||||||
>
|
|
||||||
{gebaeude_aufnahme_allgemein.prueftext}
|
|
||||||
</div>
|
</div>
|
||||||
</div></td
|
{:else}
|
||||||
|
{#each images as image}
|
||||||
|
<div>
|
||||||
|
<h2 class="text-lg mb-4 font-bold">{image.kategorie}</h2>
|
||||||
|
<img src="/bilder/{image.uid}.webp">
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<form method="dialog" class="modal-backdrop">
|
||||||
|
<button>close</button>
|
||||||
|
</form>
|
||||||
|
</dialog></td
|
||||||
>
|
>
|
||||||
<td title="Ausweis anzeigen" width="50px"
|
<td class="w-[30px]"
|
||||||
|
>
|
||||||
|
<AusweisPruefenTooltip>
|
||||||
|
<div slot="tooltip">
|
||||||
|
<span>{gebaeude_aufnahme_allgemein.prueftext}</span>
|
||||||
|
</div>
|
||||||
|
{#if gebaeude_aufnahme_allgemein.boxpruefung}
|
||||||
|
<CheckCircled size={22}></CheckCircled>
|
||||||
|
{:else}
|
||||||
|
<CrossCircled size={22}></CrossCircled>
|
||||||
|
{/if}
|
||||||
|
</AusweisPruefenTooltip></td
|
||||||
|
>
|
||||||
|
<td title="Ausweis anzeigen" class="w-[50px]"
|
||||||
><a
|
><a
|
||||||
class="energieausweis-img"
|
class="energieausweis-img"
|
||||||
href="/pdf/ansichtsausweis?uid={ausweis.uid}"
|
href="/pdf/ansichtsausweis?uid={ausweis.uid}"
|
||||||
@@ -694,6 +722,7 @@
|
|||||||
><img
|
><img
|
||||||
src="/images/dashboard/ausweis.jpg"
|
src="/images/dashboard/ausweis.jpg"
|
||||||
alt="Energieausweis"
|
alt="Energieausweis"
|
||||||
|
class="w-full h-8"
|
||||||
/></a
|
/></a
|
||||||
></td
|
></td
|
||||||
>
|
>
|
||||||
@@ -772,4 +801,76 @@
|
|||||||
: ""}
|
: ""}
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class:hidden={!infoVisible} class:block={infoVisible} class="py-4 border-t">
|
||||||
|
<div class="grid grid-cols-[2fr_1fr] prose max-w-full">
|
||||||
|
<div class="border-r px-8">
|
||||||
|
<h3 class="mt-0">Wichtige Daten</h3>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Angewendete Berechnungsformel</td>
|
||||||
|
<td><strong>EnEV 2016</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Berechnungsergebnis</td>
|
||||||
|
<td>{calculations?.endEnergieVerbrauchGesamt}kWh/m2/A - Energieeffizienzklasse <strong>{calculations?.energieEffizienzKlasse}</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Informationen des Nutzers</td>
|
||||||
|
<td>{gebaeude_aufnahme_allgemein.boxpruefung}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UID</td>
|
||||||
|
<td><strong><pre>{ausweis.uid}</pre></strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="px-8">
|
||||||
|
<h3 class="mt-0">Ereignisse</h3>
|
||||||
|
<ul class="timeline timeline-snap-icon max-md:timeline-compact timeline-vertical">
|
||||||
|
<li>
|
||||||
|
<div class="timeline-middle">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-start md:text-end mb-10">
|
||||||
|
<time class="font-mono italic">{moment(ausweis.erstellungsdatum).format("DD.MM.YYYY - HH:mm")} Uhr</time>
|
||||||
|
<div class="text-lg font-black">Ausweis erstellt</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
</li>
|
||||||
|
{#each ausweis.gebaeude_aufnahme_allgemein.events as event, i}
|
||||||
|
<li>
|
||||||
|
<hr />
|
||||||
|
<div class="timeline-middle">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10" class:timeline-end={i % 2 == 0} class:timeline-start={i % 2 == 1}>
|
||||||
|
<time class="font-mono italic">{moment(event.date).format("DD.MM.YYYY - HH:mm")} Uhr</time>
|
||||||
|
<div class="text-lg font-black">{event.title}</div>
|
||||||
|
{event.description || ""}
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
{#if ausweis.erledigt}
|
||||||
|
<li>
|
||||||
|
<hr />
|
||||||
|
<div class="timeline-middle">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
|
||||||
|
</div>
|
||||||
|
<div class="mb-10 timeline-end">
|
||||||
|
<time class="font-mono italic">{moment(ausweis.ausstellungsdatum).format("DD.MM.YYYY - HH:mm")} Uhr</time>
|
||||||
|
<div class="text-lg font-black">Ausweis ausgestellt</div>
|
||||||
|
{ausweis.registriernummer ? `Registriernummer: ${ausweis.registriernummer}` : ""}
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
} from "radix-svelte-icons";
|
} from "radix-svelte-icons";
|
||||||
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||||
import { client } from "src/trpc";
|
import { client } from "src/trpc";
|
||||||
import { verbrauchsausweisWohnenCalculateFormProgress } from "#lib/VerbrauchsausweisWohnen/calculateFormProgress";
|
|
||||||
import { number } from "zod";
|
|
||||||
|
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
export let progress: number;
|
export let progress: number;
|
||||||
@@ -62,7 +60,7 @@
|
|||||||
<div class="card lg:card-side bg-base-200 card-bordered border-base-300">
|
<div class="card lg:card-side bg-base-200 card-bordered border-base-300">
|
||||||
{#if ausweis.gebaeude_aufnahme_allgemein.storniert}
|
{#if ausweis.gebaeude_aufnahme_allgemein.storniert}
|
||||||
<div class="absolute top-0 left-0 w-full h-full bg-[rgba(0,0,0,0.7)] z-[5] rounded-lg select-none">
|
<div class="absolute top-0 left-0 w-full h-full bg-[rgba(0,0,0,0.7)] z-[5] rounded-lg select-none">
|
||||||
<h1 class="absolute -rotate-[25deg] text-7xl tracking-wide uppercase text-red-500 border-4 border-red-500 rounded-lg top-[50%] translate-y-[-50%] left-[50%] translate-x-[-50%]">Storniert</h1>
|
<h1 class="absolute -rotate-[25deg] text-5xl md:text-7xl tracking-wide uppercase text-red-500 border-4 border-red-500 rounded-lg top-[50%] translate-y-[-50%] left-[50%] translate-x-[-50%]">Storniert</h1>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<figure class="lg:w-1/2">
|
<figure class="lg:w-1/2">
|
||||||
@@ -78,7 +76,7 @@
|
|||||||
<DotsVertical size={15} />
|
<DotsVertical size={15} />
|
||||||
</button>
|
</button>
|
||||||
<ul
|
<ul
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-64 gap-2"
|
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-64 gap-2"
|
||||||
>
|
>
|
||||||
<li>
|
<li>
|
||||||
@@ -97,15 +95,15 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row flex-wrap gap-2">
|
<div class="flex flex-row flex-wrap gap-2">
|
||||||
{#if ausweis.ausweisart == "VerbrauchsausweisWohnen"}
|
{#if ausweis.gebaeude_aufnahme_allgemein.ausweisart == "VerbrauchsausweisWohnen"}
|
||||||
<div class="badge badge-accent font-semibold">
|
<div class="badge badge-accent font-semibold">
|
||||||
Verbrauchsausweis Wohnen
|
Verbrauchsausweis Wohnen
|
||||||
</div>
|
</div>
|
||||||
{:else if ausweis.ausweisart == "BedarfsausweisWohnen"}
|
{:else if ausweis.gebaeude_aufnahme_allgemein.ausweisart == "BedarfsausweisWohnen"}
|
||||||
<div class="badge badge-accent font-semibold">
|
<div class="badge badge-accent font-semibold">
|
||||||
Bedarfsausweis Wohnen
|
Bedarfsausweis Wohnen
|
||||||
</div>
|
</div>
|
||||||
{:else if ausweis.ausweisart == "VerbrauchsausweisGewerbe"}
|
{:else if ausweis.gebaeude_aufnahme_allgemein.ausweisart == "VerbrauchsausweisGewerbe"}
|
||||||
<div class="badge badge-accent font-semibold">
|
<div class="badge badge-accent font-semibold">
|
||||||
Verbrauchsausweis Gewerbe
|
Verbrauchsausweis Gewerbe
|
||||||
</div>
|
</div>
|
||||||
@@ -159,6 +157,12 @@
|
|||||||
: "N/A"}</span
|
: "N/A"}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-row justify-between">
|
||||||
|
<span>ID</span>
|
||||||
|
<span class="font-bold text-base-content"
|
||||||
|
>{ausweis.uid.split("-")[0]}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/await}
|
{/await}
|
||||||
<div class="card-actions justify-end mt-8">
|
<div class="card-actions justify-end mt-8">
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ripple } from "svelte-ripple-action";
|
import { ripple } from "svelte-ripple-action";
|
||||||
import type { RippleOptions } from "svelte-ripple-action/dist/constants";
|
import type { RippleOptions } from "svelte-ripple-action/dist/constants";
|
||||||
import { Home, Reader, EnvelopeClosed, Cube, Bell, Gear, LockClosed } from "radix-svelte-icons"
|
import { Home, Reader, EnvelopeClosed, Cube, Bell, Gear, LockClosed, HamburgerMenu } from "radix-svelte-icons"
|
||||||
import NotificationProvider from "#components/NotificationProvider/NotificationProvider.svelte";
|
import NotificationProvider from "#components/NotificationProvider/NotificationProvider.svelte";
|
||||||
import DashboardNotification from "./DashboardNotification.svelte";
|
import DashboardNotification from "./DashboardNotification.svelte";
|
||||||
import { notifications } from "#components/NotificationProvider/shared";
|
import { notifications } from "#components/NotificationProvider/shared";
|
||||||
import ThemeController from "#components/ThemeController.svelte";
|
import ThemeController from "#components/ThemeController.svelte";
|
||||||
import { BenutzerClient } from "#components/Ausweis/types";
|
import { BenutzerClient } from "#components/Ausweis/types";
|
||||||
|
import Cross1 from "radix-svelte-icons/src/lib/icons/Cross1.svelte";
|
||||||
|
|
||||||
export let lightTheme: boolean;
|
export let lightTheme: boolean;
|
||||||
export let benutzer: BenutzerClient;
|
export let benutzer: BenutzerClient;
|
||||||
@@ -15,10 +16,29 @@
|
|||||||
center: false,
|
center: false,
|
||||||
color: lightTheme ? "rgba(233,233,233,0.1)" : "rgba(113, 128, 150, 0.1)",
|
color: lightTheme ? "rgba(233,233,233,0.1)" : "rgba(113, 128, 150, 0.1)",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let headerOpen = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<aside class="hidden md:flex bg-base-100 border-r border-r-base-300 flex-col py-8">
|
<header class="fixed top-0 left-0 w-full h-16 flex items-center justify-between px-4 border-b z-20">
|
||||||
<a href="/" class="px-8"
|
<button on:click={() => headerOpen = !headerOpen}>
|
||||||
|
{#if headerOpen}
|
||||||
|
<Cross1 size={28}></Cross1>
|
||||||
|
{:else}
|
||||||
|
<HamburgerMenu size={28}></HamburgerMenu>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
<a href="/" class="block md:hidden"
|
||||||
|
><img
|
||||||
|
src="/images/header/logo-big.svg"
|
||||||
|
class="w-24"
|
||||||
|
alt="IBCornelsen - Logo"
|
||||||
|
/></a
|
||||||
|
>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<aside class:hidden={!headerOpen} class="fixed left-0 top-16 w-full h-[calc(100%-4rem)] flex z-30 md:relative md:h-auto md:w-auto md:top-0 md:flex bg-base-100 border-r border-r-base-300 flex-col py-8">
|
||||||
|
<a href="/" class="px-8 hidden md:block"
|
||||||
><img
|
><img
|
||||||
src="/images/header/logo-big.svg"
|
src="/images/header/logo-big.svg"
|
||||||
class="w-36"
|
class="w-36"
|
||||||
@@ -26,7 +46,7 @@
|
|||||||
/></a
|
/></a
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="menu flex flex-col gap-2 mt-12 px-0">
|
<div class="menu flex flex-col gap-2 mt-0 md:mt-12 px-0">
|
||||||
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard">
|
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard">
|
||||||
<Home width={22} height={22} />
|
<Home width={22} height={22} />
|
||||||
Home
|
Home
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { BedarfsausweisWohnen, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
|
|
||||||
import { Buffer } from "buffer";
|
import { Buffer } from "buffer";
|
||||||
import { GebaeudeClient, VerbrauchsausweisWohnenClient } from "./Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "./Ausweis/types";
|
||||||
|
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
export let gebaeude: GebaeudeClient;
|
|
||||||
|
|
||||||
let base64: string = "";
|
$: base64 = Buffer.from(JSON.stringify(ausweis), "utf-8").toString("base64");
|
||||||
$: {
|
|
||||||
if (ausweis && gebaeude) {
|
|
||||||
base64 = Buffer.from(JSON.stringify({...ausweis, gebaeude_stammdaten: gebaeude}), "utf-8").toString("base64");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/datenblatt?base64={base64}">
|
<a class="border-2 rounded-lg w-[30%] bg-white text-center hover:shadow-md no-underline p-6 cursor-pointer" target="_blank" href="/pdf/datenblatt?base64={base64}">
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import UploadImages from "./UploadImages.svelte";
|
import UploadImages from "./UploadImages.svelte";
|
||||||
import type { BedarfsausweisWohnen, Enums, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
|
import type { BedarfsausweisWohnen, Enums, VerbrauchsausweisGewerbe } from "@ibcornelsen/database/client";
|
||||||
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./Ausweis/types";
|
import { GebaeudeClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "./Ausweis/types";
|
||||||
|
import { RotateCounterClockwise, Trash } from "radix-svelte-icons";
|
||||||
|
|
||||||
export let images: UploadedGebaeudeBild[] = [];
|
export let images: UploadedGebaeudeBild[] = [];
|
||||||
export let max: number = 4;
|
export let max: number = 4;
|
||||||
@@ -9,6 +10,25 @@
|
|||||||
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
|
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
|
||||||
export let gebaeude: GebaeudeClient;
|
export let gebaeude: GebaeudeClient;
|
||||||
export let kategorie: Enums.BilderKategorie
|
export let kategorie: Enums.BilderKategorie
|
||||||
|
|
||||||
|
async function rotateImage(image: UploadedGebaeudeBild): Promise<UploadedGebaeudeBild> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let img = new Image();
|
||||||
|
img.src = image.base64 ? image.base64 : `/bilder/${image.uid}.webp`;
|
||||||
|
img.onload = () => {
|
||||||
|
let canvas = document.createElement("canvas");
|
||||||
|
let ctx = canvas.getContext("2d");
|
||||||
|
canvas.width = img.height;
|
||||||
|
canvas.height = img.width;
|
||||||
|
ctx?.translate(img.height / 2, img.width / 2);
|
||||||
|
ctx?.rotate((-90 * Math.PI) / 180);
|
||||||
|
ctx?.drawImage(img, -img.width / 2, -img.height / 2);
|
||||||
|
image.base64 = canvas.toDataURL("image/webp");
|
||||||
|
image.update = true;
|
||||||
|
resolve(image)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
@@ -18,20 +38,33 @@
|
|||||||
{#if image.kategorie == kategorie}
|
{#if image.kategorie == kategorie}
|
||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<img
|
<img
|
||||||
src="/bilder/{image.uid}.webp"
|
src={image.base64 ? image.base64 : `/bilder/${image.uid}.webp`}
|
||||||
alt={kategorie}
|
alt={kategorie}
|
||||||
class="h-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all"
|
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all"
|
||||||
/>
|
/>
|
||||||
|
<div class="invisible group-hover:visible absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-row gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="invisible group-hover:visible absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] rounded-full w-[30px] h-[30px] p-2 bg-[rgba(0,0,0,0.4)]"
|
class="rounded-full w-[30px] h-[30px] flex items-center justify-center p-0 bg-[rgba(0,0,0,0.4)]"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
delete images[i];
|
delete images[i];
|
||||||
images = images.filter((x) => x);
|
images = images.filter((x) => x);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
R
|
<Trash size={20} color="#fff"></Trash>
|
||||||
</button>
|
</button>
|
||||||
|
<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={async () => {
|
||||||
|
let image = await rotateImage(images[i]);
|
||||||
|
images[i] = image;
|
||||||
|
images = images
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RotateCounterClockwise size={20} color="#fff"></RotateCounterClockwise>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<div class="nav-card">
|
<div class="nav-card">
|
||||||
<div class="card-menu-option dropdown dropdown-right dropdown-hover">
|
<div class="card-menu-option dropdown dropdown-right dropdown-hover">
|
||||||
<a href="/energieausweis-erstellen"
|
<a href="/energieausweis-erstellen/verbrauchsausweis-wohnen"
|
||||||
>Energieausweis erstellen</a
|
>Energieausweis erstellen</a
|
||||||
>
|
>
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
|
|||||||
41
src/components/Tickets/TicketButton.svelte
Normal file
41
src/components/Tickets/TicketButton.svelte
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { dialogs } from "svelte-dialogs";
|
||||||
|
import TicketPopup from "./TicketPopup.svelte";
|
||||||
|
import { addNotification } from "@ibcornelsen/ui";
|
||||||
|
|
||||||
|
async function showTicketPopup() {
|
||||||
|
const success = await dialogs.modal(TicketPopup);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
dialogs.alert({
|
||||||
|
title: "Ticket erstellt",
|
||||||
|
text: "Ihr Support Ticket wurde erfolgreich erstellt. Wir werden uns schnellstmöglich um ihre Angelegenheit kümmern. Vielen Dank für ihre Geduld.",
|
||||||
|
dismissButtonText: "Schließen",
|
||||||
|
dismissButtonClass: "btn btn-primary",
|
||||||
|
dialogClass: "modal-box",
|
||||||
|
headerClass: "bg-base-100 text-center",
|
||||||
|
titleClass: "text-base-content text-xl font-medium",
|
||||||
|
dividerClass: "hidden",
|
||||||
|
footerClass: "bg-base-100 justify-center gap-4 mt-4",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
dialogs.alert({
|
||||||
|
title: "Ticket erstellen fehlgeschlagen",
|
||||||
|
text: "Leider ist beim erstellen des Tickets ein Fehler aufgetreten. Bitte versuchen sie es später erneut oder kontaktieren sie uns direkt per email unter info@ib-cornelsen.de.",
|
||||||
|
dismissButtonText: "Schließen",
|
||||||
|
dismissButtonClass: "btn btn-error",
|
||||||
|
dialogClass: "modal-box",
|
||||||
|
headerClass: "bg-base-100 text-center",
|
||||||
|
titleClass: "text-base-content text-xl font-medium",
|
||||||
|
dividerClass: "hidden",
|
||||||
|
footerClass: "bg-base-100 justify-center gap-4 mt-4",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn btn-primary fixed bottom-0 right-8 rounded-b-none rounded-t-xl w-48 h-12 text-xl hover:h-14 transition-all"
|
||||||
|
on:click={showTicketPopup}
|
||||||
|
>Support Ticket</button
|
||||||
|
>
|
||||||
104
src/components/Tickets/TicketPopup.svelte
Normal file
104
src/components/Tickets/TicketPopup.svelte
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { addNotification } from "#components/Notifications/shared";
|
||||||
|
import { client } from "src/trpc";
|
||||||
|
import { getClose } from "svelte-dialogs";
|
||||||
|
|
||||||
|
const close = getClose();
|
||||||
|
|
||||||
|
async function createTicket(e: SubmitEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
await client.v1.tickets.erstellen.mutate({
|
||||||
|
beschreibung: description,
|
||||||
|
email: email,
|
||||||
|
metadata: {
|
||||||
|
category: category,
|
||||||
|
phone: phone,
|
||||||
|
},
|
||||||
|
titel: title,
|
||||||
|
})
|
||||||
|
// Ticket wurde erfolgreich erstellt
|
||||||
|
close(true)
|
||||||
|
} catch (e) {
|
||||||
|
// Beim erstellen des Tickets ist ein Fehler aufgetreten, das ist ja mal ironisch...
|
||||||
|
close(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let category = "";
|
||||||
|
let title = "";
|
||||||
|
let description = "";
|
||||||
|
let email = "";
|
||||||
|
let phone = "";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form class="max-w-lg" on:submit={createTicket}>
|
||||||
|
<h1 class="text-2xl font-semibold mb-6">Ticket erstellen</h1>
|
||||||
|
<p class="mb-6">
|
||||||
|
Vielen Dank, dass sie sich die Zeit nehmen ein Support Ticket zu
|
||||||
|
erstellen. Wir werden uns schnellstmöglich um ihre Angelegenheit
|
||||||
|
kümmern. Hier können sie alle Details eintragen und uns ihr Problem
|
||||||
|
schildern.
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div>
|
||||||
|
<h4>Kategorie *</h4>
|
||||||
|
<select class="select select-bordered" bind:value={category}>
|
||||||
|
<option value="" disabled selected>Bitte Auswählen</option>
|
||||||
|
<option value="Verständnisproblem">Verständnisproblem</option>
|
||||||
|
<option value="Technischer Fehler">Technischer Fehler</option>
|
||||||
|
<option value="Feature anfordern">Feature anfordern</option>
|
||||||
|
<option value="Fehlende Funktionalität"
|
||||||
|
>Fehlende Funktionalität</option
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Überschrift *</h4>
|
||||||
|
<input
|
||||||
|
class="input input-bordered"
|
||||||
|
type="text"
|
||||||
|
placeholder="Überschrift in einem Satz"
|
||||||
|
name="title"
|
||||||
|
bind:value={title}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Beschreibung *</h4>
|
||||||
|
<textarea
|
||||||
|
cols="10"
|
||||||
|
rows="5"
|
||||||
|
class="textarea textarea-bordered"
|
||||||
|
placeholder="Schildern sie hier ihre Erfahrung"
|
||||||
|
bind:value={description}
|
||||||
|
required
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row gap-4">
|
||||||
|
<div class="w-full">
|
||||||
|
<h4>Email Adresse *</h4>
|
||||||
|
<input
|
||||||
|
class="input input-bordered"
|
||||||
|
type="email"
|
||||||
|
placeholder="Ihre Email Adresse"
|
||||||
|
name="email"
|
||||||
|
bind:value={email}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="w-full">
|
||||||
|
<h4>Telefonnummer</h4>
|
||||||
|
<input
|
||||||
|
class="input input-bordered"
|
||||||
|
type="tel"
|
||||||
|
placeholder="Ihre Telefonnumer"
|
||||||
|
name="phone"
|
||||||
|
bind:value={phone}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Abschicken</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
10
src/components/UMBE_Footer.astro
Normal file
10
src/components/UMBE_Footer.astro
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
---
|
||||||
|
|
||||||
|
<footer class="max-w-[1920px] w-full">
|
||||||
|
<div class="flex flex-row justify-between px-4 items-center bg-primary py-2 mt-auto">
|
||||||
|
<a class="text-white font-medium text-lg" href="/impressum">Impressum und Datenschutz</a>
|
||||||
|
<a class="text-white font-medium text-lg" href="/">© {currentYear} IB Cornelsen Hamburg.</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
45
src/components/UMBE_Header.astro
Normal file
45
src/components/UMBE_Header.astro
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<header class="max-w-[1920px] w-full relative">
|
||||||
|
<a class="hidden md:block w-full h-48 bg-base-200" href="/">
|
||||||
|
<img
|
||||||
|
src="/images/header/header-bg.jpg"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
alt="Hintergrund - Rollen Architektenpapier"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="/images/header/logo-big.svg"
|
||||||
|
class="absolute top-4 right-0 w-[464px]"
|
||||||
|
alt="IBCornelsen - Logo"
|
||||||
|
/>
|
||||||
|
<h2
|
||||||
|
class="text-secondary font-semibold text-2xl absolute top-8 right-4"
|
||||||
|
>
|
||||||
|
Energieausweis online erstellen
|
||||||
|
</h2>
|
||||||
|
<h2
|
||||||
|
class="text-primary font-semibold text-xl absolute top-16 right-4"
|
||||||
|
>
|
||||||
|
Energieausweise nach aktueller GEG
|
||||||
|
</h2>
|
||||||
|
</a>
|
||||||
|
<div class="px-4 flex flex-row w-full md:justify-end items-center bg-primary">
|
||||||
|
<a
|
||||||
|
class="header-button hidden md:block"
|
||||||
|
href="/energieausweis-erstellen/verbrauchsausweis-erstellen"
|
||||||
|
>Energieausweis erstellen</a
|
||||||
|
>
|
||||||
|
<a class="header-button hidden md:block" href="/kontakt"
|
||||||
|
>Kontakt</a
|
||||||
|
>
|
||||||
|
<a class="header-button hidden md:block" href="/agb">AGB</a>
|
||||||
|
|
||||||
|
<a class="hamburger_menu"
|
||||||
|
><img src="/images/hamburger.png" width="22" alt="hamburger" /></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.header-button {
|
||||||
|
@apply px-4 py-2 text-primary-content font-medium text-lg tracking-normal hover:bg-secondary h-full;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
src/components/UMBE_SidebarLeft.astro
Normal file
9
src/components/UMBE_SidebarLeft.astro
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
import Navigation from "../components/UMBE_navcard.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-6 bg-slate-200 grow">
|
||||||
|
|
||||||
|
<Navigation>
|
||||||
|
|
||||||
|
</div>
|
||||||
3
src/components/UMBE_SidebarRight.astro
Normal file
3
src/components/UMBE_SidebarRight.astro
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="flex flex-col gap-4 bg-slate-200 grow">
|
||||||
|
|
||||||
|
</div>
|
||||||
100
src/components/UMBE_navcard.astro
Normal file
100
src/components/UMBE_navcard.astro
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<ul id="main-navigation">
|
||||||
|
<a class="nav-element-link">
|
||||||
|
<li class="dropdown dropdown-right dropdown-hover nav-element w-full">Energieausweis erstellen<span>❯</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<ul tabindex="0" class="nav-list dropdown-content z-[1] w-full">
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Verbrauchsausweis erstellen</a></li>
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Bedarfsausweis erstellen</a></li>
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Verbrauchsausweis Gewerbe erstellen</a></li>
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Bedarfsausweis Gewerbe erstellen</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="no-dropdown nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Welcher Energieausweis</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dropdown lg:dropdown-bottom xl:dropdown-right dropdown-hover nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Verbrauchsausweis<span>❯</span></a>
|
||||||
|
<ul tabindex="0" class="nav-list dropdown-content z-[1] w-full">
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Item 1</a></li>
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Item 2</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dropdown dropdown-right dropdown-hover nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Bedarfsausweis<span>❯</span></a>
|
||||||
|
<ul tabindex="0" class="nav-list dropdown-content z-[1] w-full">
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Item 1</a></li>
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Item 2</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dropdown dropdown-right dropdown-hover nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Energieausweis<span>❯</span></a>
|
||||||
|
<ul tabindex="0" class="nav-list dropdown-content z-[1] w-full">
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Item 1</a></li>
|
||||||
|
<li class="nav-second"><a class="nav-element-link">Item 2</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="no-dropdown nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">EnEV Zusammenfassung - Archiv</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="no-dropdown nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Energieausweis Aussteller</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="no-dropdown nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Kundenbewertungen</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="no-dropdown nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">FAQ</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="no-dropdown nav-element w-full">
|
||||||
|
<a class="nav-element-link" href="">Für Entwickler</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
#main-navigation, .nav-list{border-top: 1px solid #ccc;}
|
||||||
|
#main-navigation li{border-bottom: 1px solid #ccc;border-left: 1px solid #ccc;border-right: 1px solid #ccc;}
|
||||||
|
|
||||||
|
.nav-element{
|
||||||
|
@apply p-2 bg-white font-normal text-lg hover:bg-primary hover:text-white
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-second{
|
||||||
|
@apply p-2 bg-white font-normal text-lg hover:bg-secondary hover:text-white
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-element-link{
|
||||||
|
@apply text-black no-underline hover:no-underline hover:text-white
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-element-link span{
|
||||||
|
position:absolute;right:15px;top:0.65rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-element:hover > .nav-element-link, .nav-second:hover > .nav-element-link{
|
||||||
|
@apply text-white
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-element ul{margin: -1px 0;}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
import { GebaeudeAufnahmeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { GebaeudeAufnahmeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
|
||||||
export function auditBedarfsausweisBenoetigt(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeAufnahmeClient): boolean {
|
export function auditBedarfsausweisBenoetigt(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeAufnahmeClient): boolean {
|
||||||
|
if (ausweis.ausstellgrund == "Neubau" || ausweis.ausstellgrund == "Modernisierung") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gebaeude.saniert == true && ( gebaeude.dachgeschoss_gedaemmt == false || gebaeude.oberste_geschossdecke_gedaemmt == false)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (gebaeude.baujahr_gebaeude && gebaeude.baujahr_gebaeude.length > 0) {
|
if (gebaeude.baujahr_gebaeude && gebaeude.baujahr_gebaeude.length > 0) {
|
||||||
return (
|
return (
|
||||||
(gebaeude.baujahr_gebaeude[0] < 1978 &&
|
(gebaeude.baujahr_gebaeude[0] < 1978 &&
|
||||||
(gebaeude.einheiten || 0) <= 4 &&
|
(gebaeude.einheiten || 0) <= 4 &&
|
||||||
gebaeude.saniert == false &&
|
(gebaeude.saniert == false ) &&
|
||||||
(ausweis.ausstellgrund == "Vermietung" ||
|
(ausweis.ausstellgrund == "Vermietung" ||
|
||||||
ausweis.ausstellgrund == "Sonstiges" ||
|
ausweis.ausstellgrund == "Sonstiges" ||
|
||||||
ausweis.ausstellgrund == "Verkauf")) ||
|
ausweis.ausstellgrund == "Verkauf"))
|
||||||
ausweis.ausstellgrund == "Neubau" ||
|
|
||||||
ausweis.ausstellgrund == "Modernisierung"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
src/components/Verbrauchsausweis/audits/EndEnergie.ts
Normal file
27
src/components/Verbrauchsausweis/audits/EndEnergie.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { GebaeudeClient, VerbrauchsausweisWohnenClient, GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||||
|
import { AuditType, hidden } from "./hidden";
|
||||||
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||||
|
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
||||||
|
|
||||||
|
export async function auditEndEnergie(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeClient, gebaeude_aufnahme_allgemein: GebaeudeAufnahmeClient): Promise<boolean> {
|
||||||
|
if (hidden.has(AuditType.END_ENERGIE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//sobald Fläche, Klimafaktoren und alle Verbrauchsjahre eingegeben wurden.
|
||||||
|
if (gebaeude_aufnahme_allgemein){
|
||||||
|
if (gebaeude_aufnahme_allgemein.flaeche && ausweis.verbrauch_1 && ausweis.verbrauch_2 && ausweis.verbrauch_3) {
|
||||||
|
try {
|
||||||
|
const response = await getKlimafaktoren(ausweis.startdatum, gebaeude.plz);
|
||||||
|
// Alle Klimfaktoren konnten abgefragt werden.
|
||||||
|
const eevva = await endEnergieVerbrauchVerbrauchsausweis_2016({...ausweis, gebaeude_aufnahme_allgemein: {...gebaeude_aufnahme_allgemein, gebaeude_stammdaten: gebaeude}});
|
||||||
|
if (eevva){
|
||||||
|
if (eevva?.endEnergieVerbrauchGesamt <= 45 || eevva?.endEnergieVerbrauchGesamt >= 500) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||||
|
import { AuditType, hidden } from "../audits/hidden";
|
||||||
|
|
||||||
export function auditHeizungJuengerDreiJahre(gebaeude: GebaeudeAufnahmeClient ): boolean {
|
export function auditHeizungJuengerDreiJahre(gebaeude: GebaeudeAufnahmeClient): boolean {
|
||||||
|
|
||||||
if (gebaeude.baujahr_heizung && gebaeude.baujahr_heizung.length > 0) {
|
if (gebaeude.baujahr_heizung && gebaeude.baujahr_heizung.length > 0) {
|
||||||
|
if (!hidden.has(AuditType.HEIZUNG_JUENGER_DREI_JAHRE)) {
|
||||||
return (
|
return (
|
||||||
(gebaeude.baujahr_heizung.sort()[0] >= (new Date().getFullYear())-3)
|
(gebaeude.baujahr_heizung.sort()[0] >= (new Date().getFullYear()) - 3)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { GebaeudeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { GebaeudeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
import { AuditType, hidden } from "./hidden";
|
import { AuditType, hidden } from "./hidden";
|
||||||
import { prisma } from "@ibcornelsen/database/server";
|
|
||||||
import { client } from "src/trpc";
|
|
||||||
import moment from "moment";
|
|
||||||
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
||||||
|
|
||||||
export async function auditKlimaFaktoren(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeClient): Promise<boolean> {
|
export async function auditKlimaFaktoren(ausweis: VerbrauchsausweisWohnenClient, gebaeude: GebaeudeClient): Promise<boolean> {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||||
|
import { AuditType, hidden } from "./hidden";
|
||||||
|
|
||||||
export function auditLeerStand(gebaeude: GebaeudeAufnahmeClient ): boolean {
|
export function auditLeerStand(gebaeude: GebaeudeAufnahmeClient): boolean {
|
||||||
if (gebaeude.leerstand ) {
|
if (gebaeude.leerstand && !hidden.has(AuditType.LEER_STAND)) {
|
||||||
return (
|
return (
|
||||||
(gebaeude.leerstand > 30)
|
(gebaeude.leerstand > 30)
|
||||||
);
|
);
|
||||||
|
|||||||
22
src/components/Verbrauchsausweis/audits/PlzNichtErkannt.ts
Normal file
22
src/components/Verbrauchsausweis/audits/PlzNichtErkannt.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||||
|
import { client } from "src/trpc";
|
||||||
|
import { memoize } from "src/lib/Memoization";
|
||||||
|
import { AuditType, hidden } from "../audits/hidden";
|
||||||
|
|
||||||
|
export const auditPlzNichtErkannt = memoize(async (gebaeude: GebaeudeAufnahmeClient) => {
|
||||||
|
if (gebaeude.plz) {
|
||||||
|
if (gebaeude.plz.length == 5) {
|
||||||
|
try {
|
||||||
|
const result = await client.v1.postleitzahlen.query({ plz: gebaeude.plz, limit: 1 });
|
||||||
|
if (result.length > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (!hidden.has(AuditType.PLZ_NICHT_ERKANNT)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
});
|
||||||
@@ -10,19 +10,19 @@ export function auditVerbrauchAbweichung(ausweis: VerbrauchsausweisWohnenClient,
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getAbweichung(ausweis.verbrauch_1 || 0, ausweis.verbrauch_2 || 0) > 0.25) {
|
if (getAbweichung(ausweis.verbrauch_1 || 0, ausweis.verbrauch_2 || 0) > 0.30) {
|
||||||
return [1, 2];
|
return [1, 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getAbweichung(ausweis.verbrauch_2 || 0, ausweis.verbrauch_3 || 0) > 0.25) {
|
if (getAbweichung(ausweis.verbrauch_2 || 0, ausweis.verbrauch_3 || 0) > 0.30) {
|
||||||
return [2, 3];
|
return [2, 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getAbweichung(ausweis.verbrauch_4 || 0, ausweis.verbrauch_5 || 0) > 0.25) {
|
if (getAbweichung(ausweis.verbrauch_4 || 0, ausweis.verbrauch_5 || 0) > 0.30) {
|
||||||
return [4, 5];
|
return [4, 5];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getAbweichung(ausweis.verbrauch_5 || 0, ausweis.verbrauch_6 || 0) > 0.25) {
|
if (getAbweichung(ausweis.verbrauch_5 || 0, ausweis.verbrauch_6 || 0) > 0.30) {
|
||||||
return [5, 6];
|
return [5, 6];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { AuditType, hidden } from "./hidden";
|
||||||
|
|
||||||
export function auditWarmWasser(ausweis: VerbrauchsausweisWohnenClient): boolean {
|
export function auditWarmWasser(ausweis: VerbrauchsausweisWohnenClient): boolean {
|
||||||
|
|
||||||
if (ausweis.warmwasser_anteil_bekannt && ausweis.warmwasser_enthalten && ausweis.anteil_warmwasser_1) {
|
if (ausweis.warmwasser_anteil_bekannt && ausweis.warmwasser_enthalten && ausweis.anteil_warmwasser_1) {
|
||||||
|
if (!hidden.has(AuditType.WARM_WASSER)){
|
||||||
return (
|
return (
|
||||||
ausweis.anteil_warmwasser_1 <= 6 || ausweis.anteil_warmwasser_1 >= 35
|
ausweis.anteil_warmwasser_1 <= 6 || ausweis.anteil_warmwasser_1 >= 35
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||||
|
import { AuditType, hidden } from "./hidden";
|
||||||
|
|
||||||
export function auditWohnFlaeche(gebaeude: GebaeudeAufnahmeClient ): boolean {
|
export function auditWohnFlaeche(gebaeude: GebaeudeAufnahmeClient ): boolean {
|
||||||
if (gebaeude.einheiten && gebaeude.flaeche ) {
|
if (gebaeude.einheiten && gebaeude.flaeche ) {
|
||||||
|
if (!hidden.has(AuditType.WOHN_FLAECHE)){
|
||||||
return (
|
return (
|
||||||
(gebaeude.flaeche < gebaeude.einheiten * 30)
|
(gebaeude.flaeche < gebaeude.einheiten * 30)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { GebaeudeAufnahmeClient } from "#components/Ausweis/types";
|
||||||
|
import { AuditType, hidden } from "../audits/hidden";
|
||||||
|
|
||||||
|
export function auditWohnflaecheGroesserGesamtflaeche(gebaeude: GebaeudeAufnahmeClient ): boolean {
|
||||||
|
if (gebaeude.flaeche && gebaeude.nutzflaeche){
|
||||||
|
return (gebaeude.flaeche > gebaeude.nutzflaeche && !hidden.has(AuditType.WOHNFLAECHE_GROESSER_GESAMTFLAECHE));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -8,5 +8,8 @@ export enum AuditType {
|
|||||||
KLIMA_FAKTOREN,
|
KLIMA_FAKTOREN,
|
||||||
WOHN_FLAECHE,
|
WOHN_FLAECHE,
|
||||||
WARM_WASSER,
|
WARM_WASSER,
|
||||||
LEER_STAND
|
LEER_STAND,
|
||||||
|
PLZ_NICHT_ERKANNT,
|
||||||
|
END_ENERGIE,
|
||||||
|
WOHNFLAECHE_GROESSER_GESAMTFLAECHE
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ import * as fs from "fs";
|
|||||||
|
|
||||||
const start = moment().set("year", 2019).set("month", 8).set("date", 1);
|
const start = moment().set("year", 2019).set("month", 8).set("date", 1);
|
||||||
|
|
||||||
const end = moment().set("year", 2022).set("month", 10).set("date", 1);
|
const end = moment().set("year", 2023).set("month", 1).set("date", 1);
|
||||||
|
|
||||||
let current = start.clone();
|
let current = start.clone();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@ import Header from "../components/Header.astro";
|
|||||||
import SidebarLeft from "../components/SidebarLeft.astro";
|
import SidebarLeft from "../components/SidebarLeft.astro";
|
||||||
import SidebarRight from "../components/SidebarRight.astro";
|
import SidebarRight from "../components/SidebarRight.astro";
|
||||||
import { NotificationWrapper } from "@ibcornelsen/ui";
|
import { NotificationWrapper } from "@ibcornelsen/ui";
|
||||||
import HeaderAlternative from "#components/HeaderAlternative.svelte";
|
import TicketPopup from "../components/Tickets/TicketButton.svelte"
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -105,6 +105,7 @@ const schema = JSON.stringify({
|
|||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
<NotificationWrapper client:load />
|
<NotificationWrapper client:load />
|
||||||
|
<TicketPopup client:load />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
96
src/layouts/UMBE_Layout.astro
Normal file
96
src/layouts/UMBE_Layout.astro
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
import "../style/UMBE_global.css";
|
||||||
|
import "../../svelte-dialogs.config"
|
||||||
|
import Footer from "../components/UMBE_Footer.astro";
|
||||||
|
import Header from "../components/UMBE_Header.astro";
|
||||||
|
import SidebarLeft from "../components/UMBE_SidebarLeft.astro";
|
||||||
|
import SidebarRight from "../components/UMBE_SidebarRight.astro";
|
||||||
|
import { NotificationWrapper } from "@ibcornelsen/ui";
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = Astro.props;
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang={i18next.language}>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.jpg" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="✅ Jetzt Ihren Energieausweis online erstellen. Erhalten Sie Ihren online Energieausweis rechtssicher und nach aktueller GEG (vormals EnEV) vom Diplom Ingenieur geprüft."
|
||||||
|
/>
|
||||||
|
<title>
|
||||||
|
{title || "Energieausweis online erstellen - Online Energieausweis"}
|
||||||
|
</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<container class="max-w-[1920px] w-full mx-auto bg-slate-600 grid border-solid border-grey-200 border">
|
||||||
|
<Header />
|
||||||
|
<main
|
||||||
|
class="lg:grid gap-6 md:p-6 lg:grid-cols-[2fr,6fr,2fr] max-w-[1920px] w-full bg-base-100"
|
||||||
|
>
|
||||||
|
<SidebarLeft />
|
||||||
|
<article class="w-full max-w-full bg-base-200 border border-base-300">
|
||||||
|
<slot />
|
||||||
|
</article>
|
||||||
|
<SidebarRight />
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
<NotificationWrapper client:load />
|
||||||
|
</container>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style is:global lang="scss">
|
||||||
|
|
||||||
|
:root {
|
||||||
|
@apply bg-base-100 text-base-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
@apply rounded-lg w-full shadow-md border;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainContent {
|
||||||
|
p, h1, h2, h3, h4, h5, h6 {
|
||||||
|
@apply text-base-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
@apply px-8 py-2 bg-secondary rounded-lg text-white font-medium hover:shadow-lg transition-all hover:underline active:bg-blue-900 text-center cursor-pointer;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@apply text-xl font-medium mt-6 mb-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
@apply py-1.5 px-4 w-full rounded-lg outline-none text-lg text-slate-700 border bg-gray-50 transition-colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover,
|
||||||
|
input:focus {
|
||||||
|
@apply bg-gray-100;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
@apply text-base font-semibold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -103,7 +103,7 @@ let lightTheme = Astro.cookies.get("theme").value === "light";
|
|||||||
|
|
||||||
<body class="min-h-screen grid md:grid-cols-[300px_1fr]">
|
<body class="min-h-screen grid md:grid-cols-[300px_1fr]">
|
||||||
<DashboardSidebar lightTheme={lightTheme} benutzer={benutzer} client:load></DashboardSidebar>
|
<DashboardSidebar lightTheme={lightTheme} benutzer={benutzer} client:load></DashboardSidebar>
|
||||||
<main class="p-8 overflow-auto h-screen bg-base-100">
|
<main class="p-4 md:p-8 overflow-auto h-screen bg-base-100 pt-20 md:!pt-24">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,17 +1,42 @@
|
|||||||
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { verbrauchsausweisWohnenPDFValidator } from "./validators/verbrauchsausweis-wohnen-pdf-validator";
|
||||||
|
|
||||||
export function convertAusweisData(
|
export function convertAusweisData(
|
||||||
inputs: VerbrauchsausweisWohnenClient
|
inputs: Partial<VerbrauchsausweisWohnenClient>
|
||||||
): Record<string, string> {
|
): Record<string, string> {
|
||||||
return {
|
// Wir wollen alle Werte zu einem Flachen Objekt umwandeln, sodass wir dass später benutzen können.
|
||||||
"gebaeude_stammdaten.adresse": inputs.gebaeude_aufnahme_allgemein.adresse || "",
|
// Dazu kommen noch einige wichtige Eigenschaften die man im PDF brauchen könnte.
|
||||||
"gebaeude_stammdaten.gebaeudetyp":
|
let pdfInputs: z.infer<typeof verbrauchsausweisWohnenPDFValidator> = {
|
||||||
inputs.gebaeude_aufnahme_allgemein.gebaeudetyp || "",
|
...inputs,
|
||||||
"gebaeude_stammdaten.baujahr_gebaeude":
|
pdf: {
|
||||||
inputs.gebaeude_aufnahme_allgemein.baujahr_gebaeude.join(", ") || "",
|
"brennstoff": [inputs.gebaeude_aufnahme_allgemein?.brennstoff_1, inputs.gebaeude_aufnahme_allgemein?.brennstoff_2].filter(x => x).join(", ")
|
||||||
"gebaeude_stammdaten.baujahr_heizung":
|
}
|
||||||
inputs.gebaeude_aufnahme_allgemein.baujahr_heizung.join(", ") || "",
|
}
|
||||||
"gebaeude_stammdaten.plz": inputs.gebaeude_aufnahme_allgemein.plz || "",
|
let result = recursiveFlatten(inputs, "");
|
||||||
"gebaeude_stammdaten.ort": inputs.gebaeude_aufnahme_allgemein.ort || "",
|
// Außerdem müssen wir alle Werte zu strings umwandeln.
|
||||||
};
|
for (const key in result) {
|
||||||
|
result[key] = String(result[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function recursiveFlatten(obj: any, parentKey = ""): Record<string, string> {
|
||||||
|
const result: Record<string, string> = {};
|
||||||
|
|
||||||
|
for (const key in obj) {
|
||||||
|
const value = obj[key];
|
||||||
|
|
||||||
|
const newKey = parentKey ? `${parentKey}.${key}` : key;
|
||||||
|
|
||||||
|
if (typeof value === "object") {
|
||||||
|
Object.assign(result, recursiveFlatten(value, newKey));
|
||||||
|
} else {
|
||||||
|
result[newKey] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
import { getKlimafaktoren } from "#lib/Klimafaktoren";
|
||||||
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor";
|
||||||
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|
||||||
export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
|
export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
|
||||||
@@ -11,14 +12,15 @@ export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let faktorKeller = 1.2;
|
let faktorKeller = 1.2;
|
||||||
if (ausweis.keller_beheizt && (ausweis.gebaeude_aufnahme_allgemein.einheiten || 1) <= 2) {
|
// Falls das Gebäude einen Keller besitzt der Beheizt ist erhöhen wir die Nutzfläche um 15%
|
||||||
|
if (ausweis.gebaeude_aufnahme_allgemein.keller == Enums.Heizungsstatus.BEHEIZT && (ausweis.gebaeude_aufnahme_allgemein.einheiten || 1) <= 2) {
|
||||||
faktorKeller = 1.35;
|
faktorKeller = 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ausweis.gebaeude_aufnahme_allgemein.nutzflaeche || 0) > 0) {
|
if ((ausweis.gebaeude_aufnahme_allgemein.nutzflaeche || 0) > 0) {
|
||||||
return ausweis.gebaeude_aufnahme_allgemein.nutzflaeche || 0;
|
return ausweis.gebaeude_aufnahme_allgemein.nutzflaeche || 0;
|
||||||
} else {
|
} else {
|
||||||
return (ausweis.gebaeude_aufnahme_allgemein.flaeche || 1) * faktorKeller;
|
return (ausweis.gebaeude_aufnahme_allgemein.flaeche || 0) * faktorKeller;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +131,10 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
|
|||||||
let energieVerbrauchHeizung_1 = energieVerbrauchGesamt_1;
|
let energieVerbrauchHeizung_1 = energieVerbrauchGesamt_1;
|
||||||
let energieVerbrauchHeizung_2 = energieVerbrauchGesamt_2;
|
let energieVerbrauchHeizung_2 = energieVerbrauchGesamt_2;
|
||||||
|
|
||||||
|
// TODO: Im aktuellen Skript vom Live System kommt hier etwas anderes raus,
|
||||||
|
// vielleicht ist da etwas kaputt? Da scheint es so, als wäre
|
||||||
|
// warmwasser_enthalten immer true...
|
||||||
|
// NOTE: Das hier müsste die richtige Version sein...
|
||||||
if (ausweis.warmwasser_enthalten) {
|
if (ausweis.warmwasser_enthalten) {
|
||||||
energieVerbrauchHeizung_1 -= energieVerbrauchWarmwasser_1;
|
energieVerbrauchHeizung_1 -= energieVerbrauchWarmwasser_1;
|
||||||
energieVerbrauchHeizung_2 -= energieVerbrauchWarmwasser_2;
|
energieVerbrauchHeizung_2 -= energieVerbrauchWarmwasser_2;
|
||||||
@@ -232,6 +238,29 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
|
|||||||
co2EmissionenLeerstandsZuschlag +
|
co2EmissionenLeerstandsZuschlag +
|
||||||
co2EmissionenKuehlungsZuschlag;
|
co2EmissionenKuehlungsZuschlag;
|
||||||
|
|
||||||
|
// Energieeffizienzklasse
|
||||||
|
let energieEffizienzKlasse = "";
|
||||||
|
if (endEnergieVerbrauchGesamt < 30) {
|
||||||
|
energieEffizienzKlasse = 'A+';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 50) {
|
||||||
|
energieEffizienzKlasse = 'A';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 75) {
|
||||||
|
energieEffizienzKlasse = 'B';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 100) {
|
||||||
|
energieEffizienzKlasse = 'C';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 130) {
|
||||||
|
energieEffizienzKlasse = 'D';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 160) {
|
||||||
|
energieEffizienzKlasse = 'E';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 200) {
|
||||||
|
energieEffizienzKlasse = 'F';
|
||||||
|
}else if (endEnergieVerbrauchGesamt < 250) {
|
||||||
|
energieEffizienzKlasse = 'G';
|
||||||
|
}else if (endEnergieVerbrauchGesamt >= 250) {
|
||||||
|
energieEffizienzKlasse = 'H';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
brennstoff_1: brennstoff_1,
|
brennstoff_1: brennstoff_1,
|
||||||
brennstoff_2: brennstoff_2,
|
brennstoff_2: brennstoff_2,
|
||||||
@@ -262,7 +291,7 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
|
|||||||
(ausweis.verbrauch_6 || 0) * brennstoff_2.umrechnungsfaktor
|
(ausweis.verbrauch_6 || 0) * brennstoff_2.umrechnungsfaktor
|
||||||
),
|
),
|
||||||
|
|
||||||
energetische_nutzfläche: Math.round(energetischeNutzflaeche),
|
energetischeNutzflaeche: energetischeNutzflaeche,
|
||||||
leerstand: leerstand,
|
leerstand: leerstand,
|
||||||
leerstandsZuschlagHeizung: Math.round(leerstandsZuschlagHeizung),
|
leerstandsZuschlagHeizung: Math.round(leerstandsZuschlagHeizung),
|
||||||
leerstandsZuschlagWarmwasser: Math.round(leerstandsZuschlagWarmwasser),
|
leerstandsZuschlagWarmwasser: Math.round(leerstandsZuschlagWarmwasser),
|
||||||
@@ -308,6 +337,9 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
|
|||||||
primaerEnergieVerbrauchKuehlungsZuschlag
|
primaerEnergieVerbrauchKuehlungsZuschlag
|
||||||
),
|
),
|
||||||
|
|
||||||
|
primaerfaktorww,
|
||||||
|
primaerfaktorww_1,
|
||||||
|
|
||||||
co2Emissionen_1: co2Emissionen_1,
|
co2Emissionen_1: co2Emissionen_1,
|
||||||
co2Emissionen_2: co2Emissionen_2,
|
co2Emissionen_2: co2Emissionen_2,
|
||||||
|
|
||||||
@@ -320,5 +352,6 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
|
|||||||
primaerEnergieVerbrauchGesamt: Math.round(
|
primaerEnergieVerbrauchGesamt: Math.round(
|
||||||
primaerEnergieVerbrauchGesamt
|
primaerEnergieVerbrauchGesamt
|
||||||
),
|
),
|
||||||
|
energieEffizienzKlasse
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class AusweisBerechnungen2016 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getAusweisart() {
|
public getAusweisart() {
|
||||||
switch (this.ausweis.ausweisart.toLowerCase()) {
|
switch (this.ausweis.gebaeude_aufnahme_allgemein.ausweisart.toLowerCase()) {
|
||||||
case ('va'):
|
case ('va'):
|
||||||
return {'typ' : 'Wohngebaeude', 'art' : 'Verbrauchsausweis Wohngebäude', 'kuerzel' : 'va'};
|
return {'typ' : 'Wohngebaeude', 'art' : 'Verbrauchsausweis Wohngebäude', 'kuerzel' : 'va'};
|
||||||
case ('ba'):
|
case ('ba'):
|
||||||
@@ -73,7 +73,7 @@ export class AusweisBerechnungen2016 {
|
|||||||
public getGebaeudeTeil() {
|
public getGebaeudeTeil() {
|
||||||
if (this.gebaeude.gebaeudeteil == "Gesamtgebäude") {
|
if (this.gebaeude.gebaeudeteil == "Gesamtgebäude") {
|
||||||
return "Ganzes Gebäude";
|
return "Ganzes Gebäude";
|
||||||
} else if (this.gebaeude.gebaeudeteil == "Wohnen" && this.ausweis.ausweisart == "VANW") {
|
} else if (this.gebaeude.gebaeudeteil == "Wohnen" && this.ausweis.gebaeude_aufnahme_allgemein.ausweisart == "VANW") {
|
||||||
return "Teil des Wohngebäudes";
|
return "Teil des Wohngebäudes";
|
||||||
} else {
|
} else {
|
||||||
return "Teil des Nichtwohngebäudes";
|
return "Teil des Nichtwohngebäudes";
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
import type { GebaeudeStammdaten, VerbrauchsausweisWohnen } from "@ibcornelsen/database/client";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|
||||||
export function getEmpfehlungen(ausweis: VerbrauchsausweisWohnen, gebaeude: GebaeudeStammdaten): {
|
export function getEmpfehlungen(ausweis: VerbrauchsausweisWohnenClient): {
|
||||||
title: string,
|
title: string,
|
||||||
description: string,
|
description: string,
|
||||||
anlagenteil: string
|
anlagenteil: string
|
||||||
}[] {
|
}[] {
|
||||||
let Warmwasserrohre_gedaemmt = gebaeude.warmwasser_rohre_gedaemmt;
|
let Warmwasserrohre_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.warmwasser_rohre_gedaemmt;
|
||||||
let Heizungsrohre_gedaemmt = gebaeude.heizungsrohre_gedaemmt;
|
let Heizungsrohre_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.heizungsrohre_gedaemmt;
|
||||||
let Waermepumpe = gebaeude.waermepumpe;
|
let Waermepumpe = ausweis.gebaeude_aufnahme_allgemein.waermepumpe;
|
||||||
let Kellerwand_gedaemmt = gebaeude.keller_wand_gedaemmt;
|
let Kellerwand_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.keller_wand_gedaemmt;
|
||||||
let Keller = ausweis.keller_beheizt;
|
let Keller = ausweis.gebaeude_aufnahme_allgemein.keller;
|
||||||
let Kellerdecke_Kalraeume_gedaemmt = gebaeude.keller_decke_gedaemmt;
|
let Kellerdecke_Kalraeume_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.keller_decke_gedaemmt;
|
||||||
let Brennwertkessel = gebaeude.brennwert_kessel;
|
let Brennwertkessel = ausweis.gebaeude_aufnahme_allgemein.brennwert_kessel;
|
||||||
let baujahr_anlagesanlage = gebaeude.baujahr_heizung[0];
|
let baujahr_anlagesanlage = ausweis.gebaeude_aufnahme_allgemein.baujahr_heizung[0];
|
||||||
let Zentralheizung = gebaeude.zentralheizung;
|
let Zentralheizung = ausweis.gebaeude_aufnahme_allgemein.zentralheizung;
|
||||||
let photovoltaik = gebaeude.photovoltaik;
|
let photovoltaik = ausweis.gebaeude_aufnahme_allgemein.photovoltaik;
|
||||||
let Brennstoff = ausweis.brennstoff_1;
|
let Brennstoff = ausweis.gebaeude_aufnahme_allgemein.brennstoff_1;
|
||||||
let Aussenwand_gedaemmt = gebaeude.aussenwand_gedaemmt;
|
let Aussenwand_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.aussenwand_gedaemmt;
|
||||||
let Dachgeschoss = gebaeude.dachgeschoss;
|
let Dachgeschoss = ausweis.gebaeude_aufnahme_allgemein.dachgeschoss;
|
||||||
let Dachgeschoss_gedaemmt = gebaeude.dachgeschoss_gedaemmt;
|
let Dachgeschoss_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.dachgeschoss_gedaemmt;
|
||||||
let Oberste_Geschossdecke_gedaemmt = gebaeude.oberste_geschossdecke_gedaemmt;
|
let Oberste_Geschossdecke_gedaemmt = ausweis.gebaeude_aufnahme_allgemein.oberste_geschossdecke_gedaemmt;
|
||||||
let Einfachglas = gebaeude.einfach_verglasung;
|
let Einfachglas = ausweis.gebaeude_aufnahme_allgemein.einfach_verglasung;
|
||||||
let Doppelfenster = gebaeude.doppel_verglasung;
|
let Doppelfenster = ausweis.gebaeude_aufnahme_allgemein.doppel_verglasung;
|
||||||
let Fenster_teilw_undicht = gebaeude.fenster_teilweise_undicht;
|
let Fenster_teilw_undicht = ausweis.gebaeude_aufnahme_allgemein.fenster_teilweise_undicht;
|
||||||
|
|
||||||
let empfehlungen = [];
|
let empfehlungen = [];
|
||||||
|
|
||||||
if (gebaeude.einfach_verglasung || (Doppelfenster && Fenster_teilw_undicht)) {
|
if (ausweis.gebaeude_aufnahme_allgemein.einfach_verglasung || (Doppelfenster && Fenster_teilw_undicht)) {
|
||||||
empfehlungen.push({
|
empfehlungen.push({
|
||||||
"title" : "Erneuerung der Fenster",
|
"title" : "Erneuerung der Fenster",
|
||||||
"description" : "Alte und undichte Fenster mit Wärmeschutzfenstern auswechseln.",
|
"description" : "Alte und undichte Fenster mit Wärmeschutzfenstern auswechseln.",
|
||||||
@@ -35,13 +36,13 @@ export function getEmpfehlungen(ausweis: VerbrauchsausweisWohnen, gebaeude: Geba
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gebaeude.dachgeschoss == "Unbeheizt" && !Oberste_Geschossdecke_gedaemmt) {
|
if (ausweis.gebaeude_aufnahme_allgemein.dachgeschoss == Enums.Heizungsstatus.UNBEHEIZT && !Oberste_Geschossdecke_gedaemmt) {
|
||||||
empfehlungen.push({
|
empfehlungen.push({
|
||||||
"title" : "Zusätzliche Dämmung des Fußbodens des kalten Dachraumes",
|
"title" : "Zusätzliche Dämmung des Fußbodens des kalten Dachraumes",
|
||||||
"description" : "Beim Einbringen sollten mindestens 16cm Dämmstoff verarbeitet werden. Das Einsparpotenzial ist für jeden zusätzlichen cm Dämmung sehr hoch.",
|
"description" : "Beim Einbringen sollten mindestens 16cm Dämmstoff verarbeitet werden. Das Einsparpotenzial ist für jeden zusätzlichen cm Dämmung sehr hoch.",
|
||||||
"anlagenteil" : "Dach"
|
"anlagenteil" : "Dach"
|
||||||
});
|
});
|
||||||
} else if (Dachgeschoss == "Beheizt" && !Dachgeschoss_gedaemmt) {
|
} else if (Dachgeschoss == Enums.Heizungsstatus.BEHEIZT && !Dachgeschoss_gedaemmt) {
|
||||||
empfehlungen.push({
|
empfehlungen.push({
|
||||||
"title" : "Zusätzliche Dämmung des Daches bzw. Dachraumes",
|
"title" : "Zusätzliche Dämmung des Daches bzw. Dachraumes",
|
||||||
"description" : "Beim Einbringen sollten mindestens 16cm Dämmstoff, wenn möglich, verarbeitet werden. Das Einsparpotenzial ist für jeden zusätzlichen cm Dämmung sehr hoch.",
|
"description" : "Beim Einbringen sollten mindestens 16cm Dämmstoff, wenn möglich, verarbeitet werden. Das Einsparpotenzial ist für jeden zusätzlichen cm Dämmung sehr hoch.",
|
||||||
@@ -67,13 +68,13 @@ export function getEmpfehlungen(ausweis: VerbrauchsausweisWohnen, gebaeude: Geba
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Kellerdecke_Kalraeume_gedaemmt && Keller == "Unbeheizt") {
|
if (!Kellerdecke_Kalraeume_gedaemmt && Keller == Enums.Heizungsstatus.UNBEHEIZT) {
|
||||||
empfehlungen.push({
|
empfehlungen.push({
|
||||||
"title" : "Nachträgliche Dämmung der Kellerdecke",
|
"title" : "Nachträgliche Dämmung der Kellerdecke",
|
||||||
"description" : "Je nach Deckenhöhe, den vorhandenen Raum voll ausnutzen. Das Einsparpotenzial für jeden zusätzlichen cm Dämmung sehr hoch.",
|
"description" : "Je nach Deckenhöhe, den vorhandenen Raum voll ausnutzen. Das Einsparpotenzial für jeden zusätzlichen cm Dämmung sehr hoch.",
|
||||||
"anlagenteil" : "Kellerdecke"
|
"anlagenteil" : "Kellerdecke"
|
||||||
});
|
});
|
||||||
} else if (!Kellerwand_gedaemmt && Keller == "Beheizt") {
|
} else if (!Kellerwand_gedaemmt && Keller == Enums.Heizungsstatus.BEHEIZT) {
|
||||||
empfehlungen.push({
|
empfehlungen.push({
|
||||||
"title" : "Nachträgliche Dämmung der Kellerwände",
|
"title" : "Nachträgliche Dämmung der Kellerwände",
|
||||||
"description" : "Man sollte mit Dämmstärken ab 12cm planen. Das Einsparpotenzial für jeden zusätzlichen cm Dämmung sehr hoch.",
|
"description" : "Man sollte mit Dämmstärken ab 12cm planen. Das Einsparpotenzial für jeden zusätzlichen cm Dämmung sehr hoch.",
|
||||||
|
|||||||
133
src/lib/altes-system/import.ts
Normal file
133
src/lib/altes-system/import.ts
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { faker } from "@faker-js/faker";
|
||||||
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
export async function importVerbrauchsausweisWohnenAltesSystem(count: number = 5) {
|
||||||
|
const response = await fetch("https://online-energieausweis.org/user/ausweis-import.php", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
i: count,
|
||||||
|
offset: 0,
|
||||||
|
q: {}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
export function verbrauchsausweisWohnenImportTranslate(ausweis: Record<string, any>) {
|
||||||
|
const ausweisTranslated: VerbrauchsausweisWohnenClient = {
|
||||||
|
gebaeude_aufnahme_allgemein: {
|
||||||
|
rechnungen: null,
|
||||||
|
baujahr_gebaeude: [ausweis.baujahr_gebaeude],
|
||||||
|
baujahr_heizung: [ausweis.baujahr_anlage],
|
||||||
|
baujahr_klima: [ausweis.baujahr_klimaanlage],
|
||||||
|
adresse: ausweis.objekt_strasse,
|
||||||
|
plz: ausweis.objekt_plz,
|
||||||
|
ort: ausweis.objekt_ort,
|
||||||
|
nutzflaeche: ausweis.nutzflaeche,
|
||||||
|
einheiten: ausweis.anzahl_einheiten,
|
||||||
|
saniert: ausweis.objekt_saniert,
|
||||||
|
keller: ausweis.keller_beheizt == "Beheizt" ? Enums.Heizungsstatus.BEHEIZT : ausweis.keller_beheizt == "Unbeheizt" ? Enums.Heizungsstatus.UNBEHEIZT : Enums.Heizungsstatus.NICHT_VORHANDEN,
|
||||||
|
dachgeschoss: ausweis.dachgeschoss == "Beheizt" ? Enums.Heizungsstatus.BEHEIZT : ausweis.dachgeschoss == "Unbeheizt" ? Enums.Heizungsstatus.UNBEHEIZT : Enums.Heizungsstatus.NICHT_VORHANDEN,
|
||||||
|
flaeche: ausweis.wohnflaeche,
|
||||||
|
gebaeudetyp: ausweis.objekt_typ,
|
||||||
|
gebaeudeteil: ausweis.objekt_gebaeudeteil,
|
||||||
|
lueftung: ausweis.lueftungskonzept,
|
||||||
|
kuehlung: ausweis.wird_gekuehlt,
|
||||||
|
gebaeude_stammdaten: {
|
||||||
|
adresse: ausweis.objekt_strasse,
|
||||||
|
plz: ausweis.objekt_plz,
|
||||||
|
ort: ausweis.objekt_ort,
|
||||||
|
uid: faker.string.uuid(),
|
||||||
|
gebaeude_bilder: [],
|
||||||
|
latitude: null,
|
||||||
|
longitude: null,
|
||||||
|
},
|
||||||
|
brennstoff_1: ausweis.energietraeger_1,
|
||||||
|
brennstoff_2: ausweis.energietraeger_2,
|
||||||
|
alternative_heizung: ausweis.alheizung,
|
||||||
|
alternative_kuehlung: ausweis.alkuehlung,
|
||||||
|
alternative_lueftung: ausweis.allueftung,
|
||||||
|
alternative_warmwasser: ausweis.alwarmwasser,
|
||||||
|
ausweisart: Enums.Ausweisart.VerbrauchsausweisWohnen,
|
||||||
|
energieeffizienzklasse: "",
|
||||||
|
aussenwand_gedaemmt: ausweis.aussenwand_gedaemmt,
|
||||||
|
aussenwand_min_12cm_gedaemmt: ausweis.aussenwand_min_12cm_gedaemmt,
|
||||||
|
bestellt: ausweis.bestellt,
|
||||||
|
boxpruefung: ausweis.boxpruefung,
|
||||||
|
brennwert_kessel: ausweis.brennwert_kessel,
|
||||||
|
dachgeschoss_gedaemmt: ausweis.dachgeschoss_gedaemmt,
|
||||||
|
dachgeschoss_min_12cm_gedaemmt: ausweis.dachgeschoss_min_12cm_gedaemmt,
|
||||||
|
doppel_verglasung: ausweis.doppel_verglasung,
|
||||||
|
dreifach_verglasung: ausweis.dreifach_verglasung,
|
||||||
|
durchlauf_erhitzer: ausweis.durchlauf_erhitzer,
|
||||||
|
einfach_verglasung: ausweis.einfach_verglasung,
|
||||||
|
einzelofen: ausweis.einzelofen,
|
||||||
|
erledigt: ausweis.erledigt,
|
||||||
|
erstellungsdatum: ausweis.erstellungsdatum,
|
||||||
|
fenster_dicht: ausweis.fenster_dicht,
|
||||||
|
fenster_teilweise_undicht: ausweis.fenster_teilweise_undicht,
|
||||||
|
heizungsrohre_gedaemmt: ausweis.heizungsrohre_gedaemmt,
|
||||||
|
isolier_verglasung: ausweis.isolier_verglasung,
|
||||||
|
keller_decke_gedaemmt: ausweis.keller_decke_gedaemmt,
|
||||||
|
keller_wand_gedaemmt: ausweis.keller_wand_gedaemmt,
|
||||||
|
niedertemperatur_kessel: ausweis.niedertemperatur_kessel,
|
||||||
|
oberste_geschossdecke_gedaemmt: ausweis.oberste_geschossdecke_gedaemmt,
|
||||||
|
oberste_geschossdecke_min_12cm_gedaemmt: ausweis.oberste_geschossdecke_min_12cm_gedaemmt,
|
||||||
|
raum_temperatur_regler: ausweis.raum_temperatur_regler,
|
||||||
|
rolllaeden_kaesten_gedaemmt: ausweis.rolllaeden_kaesten_gedaemmt,
|
||||||
|
solarsystem_warmwasser: ausweis.solarsystem_warmwasser,
|
||||||
|
standard_kessel: ausweis.standard_kessel,
|
||||||
|
waermepumpe: ausweis.waermepumpe,
|
||||||
|
warmwasser_rohre_gedaemmt: ausweis.warmwasser_rohre_gedaemmt,
|
||||||
|
zentralheizung: ausweis.zentralheizung,
|
||||||
|
zirkulation: ausweis.zirkulation,
|
||||||
|
photovoltaik: ausweis.photovoltaik,
|
||||||
|
leerstand: ausweis.leerstand,
|
||||||
|
prueftext: ausweis["check-texts"],
|
||||||
|
|
||||||
|
storniert: false,
|
||||||
|
tueren_dicht: ausweis.tueren_dicht,
|
||||||
|
tueren_undicht: ausweis.tueren_undicht,
|
||||||
|
zurueckgestellt: ausweis.zurueckGestellt,
|
||||||
|
uid: faker.string.uuid(),
|
||||||
|
events: []
|
||||||
|
},
|
||||||
|
verbrauch_1: parseInt(ausweis.energieverbrauch_1_heizquelle_1),
|
||||||
|
verbrauch_2: parseInt(ausweis.energieverbrauch_2_heizquelle_1),
|
||||||
|
verbrauch_3: parseInt(ausweis.energieverbrauch_3_heizquelle_1),
|
||||||
|
verbrauch_4: parseInt(ausweis.energieverbrauch_1_heizquelle_2),
|
||||||
|
verbrauch_5: parseInt(ausweis.energieverbrauch_2_heizquelle_2),
|
||||||
|
verbrauch_6: parseInt(ausweis.energieverbrauch_3_heizquelle_2),
|
||||||
|
einheit_1: ausweis.energietraeger_einheit_heizquelle_1,
|
||||||
|
einheit_2: ausweis.energietraeger_einheit_heizquelle_2,
|
||||||
|
warmwasser_enthalten: ausweis.warmwasser_enthalten,
|
||||||
|
uid: faker.string.uuid(),
|
||||||
|
alternative_heizung: ausweis.alheizung,
|
||||||
|
alternative_kuehlung: ausweis.alkuehlung,
|
||||||
|
alternative_lueftung: ausweis.allueftung,
|
||||||
|
alternative_warmwasser: ausweis.alwarmwasser,
|
||||||
|
anteil_warmwasser_1: ausweis.anteil_warmwasser_1,
|
||||||
|
anteil_warmwasser_2: ausweis.anteil_warmwasser_2,
|
||||||
|
ausstellgrund: ausweis.ausstellgrund,
|
||||||
|
ausstellungsdatum: moment(ausweis.bestelldatum).toDate(),
|
||||||
|
|
||||||
|
erledigt: ausweis.erledigt,
|
||||||
|
erstellungsdatum: moment(ausweis.erstellungsdatum).toDate(),
|
||||||
|
keller_beheizt: ausweis.keller_beheizt,
|
||||||
|
registriernummer: ausweis.regnummer,
|
||||||
|
// Der Monat im alten System ist 1-basiert, in der neuen Datenbank 0-basiert
|
||||||
|
// Also müssen wir hier 1 abziehen
|
||||||
|
startdatum: moment(`${ausweis.energieverbrauch_zeitraum_jahr}-${ausweis.energieverbrauch_zeitraum_monat}-01`).toDate(),
|
||||||
|
|
||||||
|
warmwasser_anteil_bekannt: ausweis.warmwasser_anteil_bekannt,
|
||||||
|
wird_gekuehlt: ausweis.wird_gekuehlt,
|
||||||
|
zusaetzliche_heizquelle: ausweis.zusaetzliche_heizquelle,
|
||||||
|
}
|
||||||
|
|
||||||
|
return ausweisTranslated
|
||||||
|
}
|
||||||
118
src/lib/faker/verbrauchsausweis-wohnen.ts
Normal file
118
src/lib/faker/verbrauchsausweis-wohnen.ts
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { faker } from "@faker-js/faker";
|
||||||
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
|
|
||||||
|
export function verbrauchsausweisWohnenFaker(seed: number = 42): VerbrauchsausweisWohnenClient {
|
||||||
|
faker.seed(seed);
|
||||||
|
|
||||||
|
const tuerenDicht = faker.datatype.boolean();
|
||||||
|
const verbrauch_1 = faker.number.int({ min: 5000, max: 20000 });
|
||||||
|
const verbrauch_4 = faker.number.int({ min: 5000, max: 15000 });
|
||||||
|
|
||||||
|
const ausweis: VerbrauchsausweisWohnenClient = {
|
||||||
|
rechnungen: null,
|
||||||
|
gebaeude_aufnahme_allgemein: {
|
||||||
|
baujahr_gebaeude: [faker.number.int({ min: 1960, max: 2014 })],
|
||||||
|
baujahr_heizung: [faker.number.int({ min: 1960, max: 2014 })],
|
||||||
|
baujahr_klima: [faker.number.int({ min: 1985, max: 2014 })],
|
||||||
|
adresse: faker.location.streetAddress(),
|
||||||
|
plz: faker.location.zipCode({ format: "#####" }),
|
||||||
|
ort: faker.location.city(),
|
||||||
|
nutzflaeche: faker.number.int({ min: 50, max: 300 }),
|
||||||
|
einheiten: faker.number.int({ min: 1, max: 3 }),
|
||||||
|
saniert: faker.datatype.boolean(),
|
||||||
|
keller: faker.helpers.enumValue(Enums.Heizungsstatus),
|
||||||
|
dachgeschoss: faker.helpers.enumValue(Enums.Heizungsstatus),
|
||||||
|
flaeche: faker.number.int({ min: 50, max: 300 }),
|
||||||
|
gebaeudetyp: "Einfamilienhaus",
|
||||||
|
gebaeudeteil: "Gesamtgebäude",
|
||||||
|
lueftung: "Fensterlüftung",
|
||||||
|
kuehlung: "Vorhanden",
|
||||||
|
gebaeude_stammdaten: {
|
||||||
|
adresse: faker.location.streetAddress(),
|
||||||
|
plz: faker.location.zipCode({ format: "#####" }),
|
||||||
|
ort: faker.location.city(),
|
||||||
|
uid: faker.string.uuid(),
|
||||||
|
gebaeude_bilder: [],
|
||||||
|
latitude: faker.location.latitude(),
|
||||||
|
longitude: faker.location.longitude(),
|
||||||
|
},
|
||||||
|
brennstoff_1: "Erdgas H",
|
||||||
|
alternative_heizung: faker.datatype.boolean(),
|
||||||
|
alternative_kuehlung: faker.datatype.boolean(),
|
||||||
|
alternative_lueftung: faker.datatype.boolean(),
|
||||||
|
alternative_warmwasser: faker.datatype.boolean(),
|
||||||
|
aussenwand_gedaemmt: faker.datatype.boolean(),
|
||||||
|
aussenwand_min_12cm_gedaemmt: faker.datatype.boolean(),
|
||||||
|
ausweisart: Enums.Ausweisart.VerbrauchsausweisWohnen,
|
||||||
|
bestellt: faker.datatype.boolean(),
|
||||||
|
boxpruefung: faker.datatype.boolean(),
|
||||||
|
brennstoff_2: "Erdgas H",
|
||||||
|
brennwert_kessel: faker.datatype.boolean(),
|
||||||
|
dachgeschoss_gedaemmt: faker.datatype.boolean(),
|
||||||
|
dachgeschoss_min_12cm_gedaemmt: faker.datatype.boolean(),
|
||||||
|
doppel_verglasung: faker.datatype.boolean(),
|
||||||
|
dreifach_verglasung: faker.datatype.boolean(),
|
||||||
|
durchlauf_erhitzer: faker.datatype.boolean(),
|
||||||
|
einfach_verglasung: faker.datatype.boolean(),
|
||||||
|
einzelofen: faker.datatype.boolean(),
|
||||||
|
energieeffizienzklasse: "",
|
||||||
|
erledigt: faker.datatype.boolean(),
|
||||||
|
erstellungsdatum: faker.date.past(),
|
||||||
|
fenster_dicht: faker.datatype.boolean(),
|
||||||
|
fenster_teilweise_undicht: faker.datatype.boolean(),
|
||||||
|
heizungsrohre_gedaemmt: faker.datatype.boolean(),
|
||||||
|
isolier_verglasung: faker.datatype.boolean(),
|
||||||
|
keller_decke_gedaemmt: faker.datatype.boolean(),
|
||||||
|
keller_wand_gedaemmt: faker.datatype.boolean(),
|
||||||
|
leerstand: faker.number.int({ min: 0, max: 20 }),
|
||||||
|
niedertemperatur_kessel: faker.datatype.boolean(),
|
||||||
|
oberste_geschossdecke_gedaemmt: faker.datatype.boolean(),
|
||||||
|
oberste_geschossdecke_min_12cm_gedaemmt: faker.datatype.boolean(),
|
||||||
|
photovoltaik: faker.datatype.boolean(),
|
||||||
|
prueftext: faker.lorem.sentence(),
|
||||||
|
raum_temperatur_regler: faker.datatype.boolean(),
|
||||||
|
rolllaeden_kaesten_gedaemmt: faker.datatype.boolean(),
|
||||||
|
solarsystem_warmwasser: faker.datatype.boolean(),
|
||||||
|
standard_kessel: faker.datatype.boolean(),
|
||||||
|
storniert: false,
|
||||||
|
tueren_dicht: tuerenDicht,
|
||||||
|
tueren_undicht: !tuerenDicht,
|
||||||
|
waermepumpe: faker.datatype.boolean(),
|
||||||
|
warmwasser_rohre_gedaemmt: faker.datatype.boolean(),
|
||||||
|
zentralheizung: faker.datatype.boolean(),
|
||||||
|
zirkulation: faker.datatype.boolean(),
|
||||||
|
zurueckgestellt: faker.datatype.boolean(),
|
||||||
|
uid: faker.string.uuid(),
|
||||||
|
events: []
|
||||||
|
},
|
||||||
|
verbrauch_1: verbrauch_1,
|
||||||
|
verbrauch_2: verbrauch_1 + faker.number.int({ min: -2000, max: 2000 }),
|
||||||
|
verbrauch_3: verbrauch_1 + faker.number.int({ min: -2000, max: 2000 }),
|
||||||
|
einheit_1: "kWh",
|
||||||
|
warmwasser_enthalten: faker.datatype.boolean(),
|
||||||
|
uid: faker.string.uuid(),
|
||||||
|
alternative_heizung: faker.datatype.boolean(),
|
||||||
|
alternative_kuehlung: faker.datatype.boolean(),
|
||||||
|
alternative_lueftung: faker.datatype.boolean(),
|
||||||
|
alternative_warmwasser: faker.datatype.boolean(),
|
||||||
|
anteil_warmwasser_1: faker.number.int({ min: 0, max: 60 }),
|
||||||
|
anteil_warmwasser_2: faker.number.int({ min: 0, max: 60 }),
|
||||||
|
ausstellgrund: faker.helpers.enumValue(Enums.Ausstellgrund),
|
||||||
|
ausstellungsdatum: faker.date.past(),
|
||||||
|
einheit_2: "kWh",
|
||||||
|
erledigt: faker.datatype.boolean(),
|
||||||
|
erstellungsdatum: faker.date.past(),
|
||||||
|
keller_beheizt: faker.datatype.boolean(),
|
||||||
|
registriernummer: faker.string.uuid(),
|
||||||
|
startdatum: faker.date.past({ years: 3 }),
|
||||||
|
verbrauch_4: verbrauch_4,
|
||||||
|
verbrauch_5: verbrauch_4 + faker.number.int({ min: -2000, max: 2000 }),
|
||||||
|
verbrauch_6: verbrauch_4 + faker.number.int({ min: -2000, max: 2000 }),
|
||||||
|
warmwasser_anteil_bekannt: faker.datatype.boolean(),
|
||||||
|
wird_gekuehlt: faker.datatype.boolean(),
|
||||||
|
zusaetzliche_heizquelle: faker.datatype.boolean(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return ausweis;
|
||||||
|
}
|
||||||
25
src/lib/helpers/zod.ts
Normal file
25
src/lib/helpers/zod.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
// get zod object keys recursively
|
||||||
|
export const zodGetKeys = <T extends z.ZodTypeAny>(schema: T): string[] => {
|
||||||
|
// make sure schema is not null or undefined
|
||||||
|
if (schema === null || schema === undefined) return [];
|
||||||
|
// check if schema is nullable or optional
|
||||||
|
if (schema instanceof z.ZodNullable || schema instanceof z.ZodOptional) return zodGetKeys(schema.unwrap());
|
||||||
|
// check if schema is an array
|
||||||
|
if (schema instanceof z.ZodArray) return zodGetKeys(schema.element);
|
||||||
|
// check if schema is an object
|
||||||
|
if (schema instanceof z.ZodObject) {
|
||||||
|
// get key/value pairs from schema
|
||||||
|
const entries = Object.entries(schema.shape);
|
||||||
|
// loop through key/value pairs
|
||||||
|
return entries.flatMap(([key, value]) => {
|
||||||
|
// get nested keys
|
||||||
|
const nested = value instanceof z.ZodType ? zodGetKeys(value).map(subKey => `${key}.${subKey}`) : [];
|
||||||
|
// return nested keys
|
||||||
|
return nested.length ? nested : key;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// return empty array
|
||||||
|
return [];
|
||||||
|
};
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
ZOOM,
|
|
||||||
Plugin,
|
Plugin,
|
||||||
Schema,
|
|
||||||
PropPanel,
|
PropPanel,
|
||||||
DEFAULT_FONT_NAME,
|
DEFAULT_FONT_NAME,
|
||||||
getFallbackFontName,
|
getFallbackFontName,
|
||||||
PropPanelSchema,
|
PropPanelSchema,
|
||||||
PropPanelWidgetProps,
|
PropPanelWidgetProps,
|
||||||
} from "@pdfme/common";
|
} from "@pdfme/common";
|
||||||
import { image, text } from "@pdfme/schemas";
|
import { text } from "@pdfme/schemas";
|
||||||
import type { TextSchema } from "@pdfme/schemas/dist/types/src/text/types";
|
import type { TextSchema } from "@pdfme/schemas/dist/types/src/text/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -34,8 +32,10 @@ import {
|
|||||||
import {
|
import {
|
||||||
GebaeudeStammdaten,
|
GebaeudeStammdaten,
|
||||||
Rechnungen,
|
Rechnungen,
|
||||||
VerbrauchsausweisWohnen,
|
|
||||||
} from "@ibcornelsen/database/client";
|
} from "@ibcornelsen/database/client";
|
||||||
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { zodGetKeys } from "#lib/helpers/zod";
|
||||||
|
import { verbrauchsausweisWohnenPDFValidator } from "#lib/validators/verbrauchsausweis-wohnen-pdf-validator";
|
||||||
|
|
||||||
const UseDynamicFontSize = (props: PropPanelWidgetProps) => {
|
const UseDynamicFontSize = (props: PropPanelWidgetProps) => {
|
||||||
const { rootElement, changeSchemas, activeSchema, i18n } = props;
|
const { rootElement, changeSchemas, activeSchema, i18n } = props;
|
||||||
@@ -62,51 +62,17 @@ const UseDynamicFontSize = (props: PropPanelWidgetProps) => {
|
|||||||
rootElement.appendChild(label);
|
rootElement.appendChild(label);
|
||||||
};
|
};
|
||||||
|
|
||||||
type AusweisIndex = keyof VerbrauchsausweisWohnen
|
type AusweisIndex = keyof Omit<Omit<VerbrauchsausweisWohnenClient, "gebaeude_aufnahme_allgemein">, "rechnungen">
|
||||||
| `gebaeude_stammdaten.${keyof GebaeudeStammdaten}`
|
| `gebaeude_aufnahme_allgemein.${keyof VerbrauchsausweisWohnenClient["gebaeude_aufnahme_allgemein"]}`
|
||||||
| `rechnung.${keyof Rechnungen}`;
|
| `gebaeude_aufnahme_allgemein.gebaeude_stammdaten.${keyof VerbrauchsausweisWohnenClient["gebaeude_aufnahme_allgemein"]["gebaeude_stammdaten"]}`
|
||||||
|
| `rechnungen.${keyof Rechnungen}`;
|
||||||
|
|
||||||
const sampleData: Partial<Record<AusweisIndex , string>> = {
|
const ausweisKeys = zodGetKeys(verbrauchsausweisWohnenPDFValidator);
|
||||||
"gebaeude_stammdaten.adresse": "Musterstraße 123",
|
|
||||||
"gebaeude_stammdaten.plz": "12345",
|
|
||||||
"gebaeude_stammdaten.ort": "Musterstadt",
|
|
||||||
"gebaeude_stammdaten.baujahr_gebaeude": "1990",
|
|
||||||
"gebaeude_stammdaten.baujahr_heizung": "2000",
|
|
||||||
}
|
|
||||||
|
|
||||||
const variableOptions: {
|
const variableOptions: {
|
||||||
label: string;
|
label: string;
|
||||||
value: AusweisIndex;
|
value: AusweisIndex;
|
||||||
}[] = [
|
}[] = ausweisKeys.map((key: AusweisIndex) => ({ label: key as string, value: key }));
|
||||||
{
|
|
||||||
label: "Gebäude -> Adresse",
|
|
||||||
value: "gebaeude_stammdaten.adresse",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Gebäude -> PLZ",
|
|
||||||
value: "gebaeude_stammdaten.plz",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Gebaeude -> Ort",
|
|
||||||
value: "gebaeude_stammdaten.ort",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Gebäude -> Baujahr Gebäude",
|
|
||||||
value: "gebaeude_stammdaten.baujahr_gebaeude",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Gebäude -> Baujahr Heizung",
|
|
||||||
value: "gebaeude_stammdaten.baujahr_heizung",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Gebäude -> Fläche",
|
|
||||||
value: "gebaeude_stammdaten.flaeche"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Gebäude -> Einheiten",
|
|
||||||
value: "gebaeude_stammdaten.einheiten"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
interface VariableSchema extends TextSchema {
|
interface VariableSchema extends TextSchema {
|
||||||
variable: AusweisIndex | undefined
|
variable: AusweisIndex | undefined
|
||||||
@@ -293,18 +259,21 @@ const propPanel: PropPanel<VariableSchema> = {
|
|||||||
backgroundColor: "",
|
backgroundColor: "",
|
||||||
opacity: DEFAULT_OPACITY,
|
opacity: DEFAULT_OPACITY,
|
||||||
variable: undefined
|
variable: undefined
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const variable: Plugin<VariableSchema> = {
|
export const variable: Plugin<VariableSchema> = {
|
||||||
ui: (props) => {
|
ui: function(props) {
|
||||||
if (props.schema.variable) {
|
// Wir binden die inputs auf dieses Element, damit wir die Werte später auslesen können.
|
||||||
props.value = sampleData[props.schema.variable] as string;
|
if (props.schema.variable && this) {
|
||||||
|
props.value = (this as unknown as Record<string, string>)[props.schema.variable] as string;
|
||||||
}
|
}
|
||||||
return text.ui(props);
|
return text.ui(props);
|
||||||
},
|
},
|
||||||
pdf: (props) => {
|
pdf: (props) => {
|
||||||
props.value = props.schema.variable as string;
|
if (props.schema.variable && this) {
|
||||||
|
props.value = (this as unknown as Record<string, string>)[props.schema.variable] as string;
|
||||||
|
}
|
||||||
text.pdf(props);
|
text.pdf(props);
|
||||||
},
|
},
|
||||||
propPanel,
|
propPanel,
|
||||||
|
|||||||
1
src/lib/pdf/templates/GEG24_Verbrauchsausweis.json
Normal file
1
src/lib/pdf/templates/GEG24_Verbrauchsausweis.json
Normal file
File diff suppressed because one or more lines are too long
BIN
src/lib/pdf/templates/GEG24_Wohngebaeude.pdf
Normal file
BIN
src/lib/pdf/templates/GEG24_Wohngebaeude.pdf
Normal file
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
import { VerbrauchsausweisWohnenValidator } from "@ibcornelsen/api/src/validators";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const verbrauchsausweisWohnenPDFValidator = VerbrauchsausweisWohnenValidator.merge(z.object({
|
||||||
|
pdf: z.object({
|
||||||
|
brennstoff: z.string()
|
||||||
|
})
|
||||||
|
}))
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
import ZipSearch from "#components/PlzSuche.svelte";
|
import ZipSearch from "#components/PlzSuche.svelte";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import BilderZusatzsysteme from "#components/Ausweis/BilderZusatzsysteme.svelte";
|
import BilderZusatzsysteme from "#components/Ausweis/BilderZusatzsysteme.svelte";
|
||||||
import { RawNotificationWrapper, RawNotification, notifications, addNotification, updateNotification } from "@ibcornelsen/ui";
|
import { RawNotificationWrapper, RawNotification, notifications } from "@ibcornelsen/ui";
|
||||||
import { auditHeizungGebaeudeBaujahr } from "#components/Verbrauchsausweis/audits/HeizungGebaeudeBaujahr";
|
import { auditHeizungGebaeudeBaujahr } from "#components/Verbrauchsausweis/audits/HeizungGebaeudeBaujahr";
|
||||||
import { auditHeizungJuengerDreiJahre } from "#components/Verbrauchsausweis/audits/HeizungJuengerDreiJahre";
|
import { auditHeizungJuengerDreiJahre } from "#components/Verbrauchsausweis/audits/HeizungJuengerDreiJahre";
|
||||||
import { auditZeitraumAktuell } from "#components/Verbrauchsausweis/audits/ZeitraumAktuell";
|
import { auditZeitraumAktuell } from "#components/Verbrauchsausweis/audits/ZeitraumAktuell";
|
||||||
@@ -17,157 +17,37 @@
|
|||||||
import { auditWohnFlaeche } from "#components/Verbrauchsausweis/audits/WohnFlaeche";
|
import { auditWohnFlaeche } from "#components/Verbrauchsausweis/audits/WohnFlaeche";
|
||||||
import { auditWarmWasser } from "#components/Verbrauchsausweis/audits/WarmWasser";
|
import { auditWarmWasser } from "#components/Verbrauchsausweis/audits/WarmWasser";
|
||||||
import { auditLeerStand } from "#components/Verbrauchsausweis/audits/LeerStand";
|
import { auditLeerStand } from "#components/Verbrauchsausweis/audits/LeerStand";
|
||||||
|
import { auditPlzNichtErkannt } from "#components/Verbrauchsausweis/audits/PlzNichtErkannt";
|
||||||
import { AuditType, hidden } from "#components/Verbrauchsausweis/audits/hidden";
|
import { AuditType, hidden } from "#components/Verbrauchsausweis/audits/hidden";
|
||||||
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt";
|
import { auditBedarfsausweisBenoetigt } from "#components/Verbrauchsausweis/audits/BedarfsausweisBenoetigt";
|
||||||
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung";
|
import { auditVerbrauchAbweichung } from "#components/Verbrauchsausweis/audits/VerbrauchAbweichung";
|
||||||
|
import { auditEndEnergie } from "#components/Verbrauchsausweis/audits/EndEnergie";
|
||||||
|
import { auditWohnflaecheGroesserGesamtflaeche } from "#components/Verbrauchsausweis/audits/WohnflaecheGroesserGesamtflaeche";
|
||||||
import { Enums } from "@ibcornelsen/database/client"
|
import { Enums } from "@ibcornelsen/database/client"
|
||||||
import { client } from "src/trpc";
|
|
||||||
import Overlay from "#components/Overlay.svelte";
|
import Overlay from "#components/Overlay.svelte";
|
||||||
import AusweisGespeichertModule from "./AusweisGespeichertModule.svelte";
|
import AusweisGespeichertModule from "./AusweisGespeichertModule.svelte";
|
||||||
import { validateAccessTokenClient } from "src/client/lib/validateAccessToken";
|
import { VerbrauchsausweisWohnenClient, BenutzerClient, UploadedGebaeudeBild } from "#components/Ausweis/types";
|
||||||
import { VerbrauchsausweisWohnenClient, BenutzerClient } from "#components/Ausweis/types";
|
import { verbrauchsausweisWohnenSpeichern } from "src/client/lib/verbrauchsausweisWohnenSpeichern";
|
||||||
import { dialogs } from "svelte-dialogs";
|
|
||||||
import LoginDialog from "#components/LoginDialog.svelte";
|
|
||||||
import { exclude } from "#lib/exclude";
|
|
||||||
|
|
||||||
|
// TODO: Vom Server sollte ein volles Objekt kommen, dass alle Subobjekte enthält, weil es sonst zu Problemen führen kann
|
||||||
|
// wenn gebaeude_aufnahme_allgemein oder gebaeude_stammdaten nicht existiert...
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
export let user: BenutzerClient = {} as BenutzerClient;
|
export let user: BenutzerClient = {} as BenutzerClient;
|
||||||
|
|
||||||
let gebaeude_aufnahme_allgemein = ausweis.gebaeude_aufnahme_allgemein || {};
|
let gebaeude_aufnahme_allgemein = ausweis.gebaeude_aufnahme_allgemein || {};
|
||||||
let gebaeude = ausweis.gebaeude_aufnahme_allgemein?.gebaeude_stammdaten || {};
|
let gebaeude = ausweis.gebaeude_aufnahme_allgemein?.gebaeude_stammdaten || {};
|
||||||
let images = ausweis.gebaeude_aufnahme_allgemein?.gebaeude_stammdaten?.gebaeude_bilder || [];
|
let images: (UploadedGebaeudeBild & { base64?: string })[] = ausweis.gebaeude_aufnahme_allgemein?.gebaeude_stammdaten?.gebaeude_bilder || [];
|
||||||
|
|
||||||
async function bilderHochladen() {
|
|
||||||
if (images.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const imagesToUpload = images.filter(image => !image.uid);
|
|
||||||
|
|
||||||
if (imagesToUpload.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alle Bilder hochladen
|
|
||||||
const notification = addNotification({
|
|
||||||
dismissable: false,
|
|
||||||
message: "Bilder hochladen.",
|
|
||||||
subtext: `${imagesToUpload.length} Bilder werden hochgeladen, bitte haben sie Geduld.`,
|
|
||||||
timeout: 0,
|
|
||||||
type: "info"
|
|
||||||
})
|
|
||||||
for (let i = 0; i < imagesToUpload.length; i++) {
|
|
||||||
const image = imagesToUpload[i];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await client.v1.bilder.upload.mutate({
|
|
||||||
base64: image.base64,
|
|
||||||
kategorie: image.kategorie,
|
|
||||||
gebaeude_uid: gebaeude.uid
|
|
||||||
})
|
|
||||||
|
|
||||||
image.uid = response.uid
|
|
||||||
|
|
||||||
updateNotification(notification, {
|
|
||||||
dismissable: true,
|
|
||||||
message: "Bild hochgeladen.",
|
|
||||||
subtext: `${i + 1}/${imagesToUpload.length} Bildern wurden erfolgreich hochgeladen.`,
|
|
||||||
timeout: 3000
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
updateNotification(notification, {
|
|
||||||
dismissable: true,
|
|
||||||
message: "Bild konnte nicht hochgeladen werden.",
|
|
||||||
subtext: `Eines ihrer Bilder konnte nicht hochgeladen werden. Wir haben bereits ein Ticket erstellt und melden uns so schnell wie möglich bei ihnen.`,
|
|
||||||
timeout: 15000,
|
|
||||||
type: "error"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function ausweisSpeichern() {
|
|
||||||
// Um einen Ausweis zu speichern müssen wir eingeloggt sein, andernfalls wird die API den call ablehnen.
|
|
||||||
// Wir prüfen also ob wir eingeloggt sind und leiten den Nutzer ggf. auf die Login Seite weiter.
|
|
||||||
if (!await validateAccessTokenClient()) {
|
|
||||||
// TOOD: Auf Dialog umstellen.
|
|
||||||
const loggedIn = await dialogs.modal(LoginDialog);
|
|
||||||
|
|
||||||
if (!loggedIn) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ausweis.uid) {
|
|
||||||
// Anscheinend wurde der Ausweis bereits erstellt und hat eine UID.
|
|
||||||
// Jetzt müssen wir ihn nun nur noch abspeichern.
|
|
||||||
try {
|
|
||||||
const gebaeudeBilderEntfernt = exclude(gebaeude, ["gebaeude_bilder"])
|
|
||||||
const gebaeudeAufnahmeGeneratedFieldsEntfernt = exclude(gebaeude_aufnahme_allgemein, ["erstellungsdatum"])
|
|
||||||
const ausweisGeneratedFieldsEntfernt = exclude(ausweis, ["ausweisart", "rechnungen"])
|
|
||||||
await client.v1.verbrauchsausweisWohnen[2016].speichern.mutate({
|
|
||||||
...ausweisGeneratedFieldsEntfernt,
|
|
||||||
gebaeude_aufnahme_allgemein: {
|
|
||||||
...gebaeudeAufnahmeGeneratedFieldsEntfernt,
|
|
||||||
gebaeude_stammdaten: {
|
|
||||||
...gebaeudeBilderEntfernt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await bilderHochladen();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
// TODO: Ticket mit Fehldermeldung abschicken.
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Wir speichern den Ausweis ab und leiten auf die "ausweis-gespeichert" Seite weiter.
|
|
||||||
try {
|
|
||||||
const response = await client.v1.verbrauchsausweisWohnen[2016].erstellen.mutate({
|
|
||||||
...ausweis,
|
|
||||||
gebaeude_aufnahme_allgemein: {
|
|
||||||
...gebaeude_aufnahme_allgemein,
|
|
||||||
gebaeude_stammdaten: {
|
|
||||||
...gebaeude
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
ausweis.uid = response.uid;
|
|
||||||
gebaeude.uid = response.gebaeude_uid;
|
|
||||||
gebaeude_aufnahme_allgemein.uid = response.gebaeude_aufnahme_uid
|
|
||||||
|
|
||||||
await bilderHochladen();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (e: any) {
|
|
||||||
await client.v1.tickets.erstellen.mutate({
|
|
||||||
titel: "Ausweis konnte nicht gespeichert werden",
|
|
||||||
beschreibung: e.stack,
|
|
||||||
email: user.email ?? "",
|
|
||||||
metadata: JSON.stringify({
|
|
||||||
ausweis
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// TODO: Ticket mit Fehldermeldung abschicken.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addNotification({
|
|
||||||
dismissable: false,
|
|
||||||
message: "Ausweis konnte nicht gespeichert werden, bitte versuchen sie es erneut.",
|
|
||||||
subtext: "Sollte das Problem weiterhin bestehen, kontaktieren sie bitte den Support.",
|
|
||||||
timeout: 6000,
|
|
||||||
type: "error"
|
|
||||||
})
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
async function spaeterWeitermachen() {
|
async function spaeterWeitermachen() {
|
||||||
const result = await ausweisSpeichern();
|
const result = await verbrauchsausweisWohnenSpeichern(ausweis, gebaeude, gebaeude_aufnahme_allgemein, images, user);
|
||||||
|
|
||||||
if (result === true) {
|
if (result !== null) {
|
||||||
window.history.pushState({}, "", `${location.pathname}?uid=${ausweis.uid}`);
|
// Falls der Nutzer zurück navigiert, sollte er wieder auf seinen Vorgang kommen.
|
||||||
|
// Sonst müsste er alles neu eingeben...
|
||||||
|
ausweis.uid = result.uid
|
||||||
|
gebaeude.uid = result.gebaeude_uid
|
||||||
|
gebaeude_aufnahme_allgemein.uid = result.gebaeude_aufnahme_uid
|
||||||
|
window.history.pushState({}, "", `${location.pathname}?uid=${result.uid}`);
|
||||||
speichernOverlayHidden = false;
|
speichernOverlayHidden = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,10 +67,10 @@
|
|||||||
gebaeude_aufnahme_allgemein.brennstoff_1 = "Erdgas H";
|
gebaeude_aufnahme_allgemein.brennstoff_1 = "Erdgas H";
|
||||||
ausweis.einheit_1 = "kWh";
|
ausweis.einheit_1 = "kWh";
|
||||||
ausweis.anteil_warmwasser_1 = 18;
|
ausweis.anteil_warmwasser_1 = 18;
|
||||||
ausweis.startdatum = moment("12.01.2019").toDate();
|
ausweis.startdatum = moment("01.01.2019").toDate();
|
||||||
gebaeude.plz = "21039";
|
gebaeude_aufnahme_allgemein.plz = "21039";
|
||||||
gebaeude.ort = "Hamburg";
|
gebaeude_aufnahme_allgemein.ort = "Hamburg";
|
||||||
gebaeude.adresse = "Curslacker Deich 170";
|
gebaeude_aufnahme_allgemein.adresse = "Curslacker Deich 170";
|
||||||
gebaeude_aufnahme_allgemein.gebaeudeteil = "Gesamtgebäude";
|
gebaeude_aufnahme_allgemein.gebaeudeteil = "Gesamtgebäude";
|
||||||
|
|
||||||
gebaeude = gebaeude;
|
gebaeude = gebaeude;
|
||||||
@@ -200,18 +80,31 @@
|
|||||||
|
|
||||||
async function ausweisAbschicken(e: SubmitEvent) {
|
async function ausweisAbschicken(e: SubmitEvent) {
|
||||||
if (e && e.preventDefault) e.preventDefault();
|
if (e && e.preventDefault) e.preventDefault();
|
||||||
const result = await ausweisSpeichern();
|
const result = await verbrauchsausweisWohnenSpeichern(ausweis, gebaeude, gebaeude_aufnahme_allgemein, images, user);
|
||||||
|
|
||||||
if (result === true) {
|
if (result !== null) {
|
||||||
// Falls der Nutzer zurück navigiert, sollte er wieder auf seinen Vorgang kommen.
|
// Falls der Nutzer zurück navigiert, sollte er wieder auf seinen Vorgang kommen.
|
||||||
// Sonst müsste er alles neu eingeben...
|
// Sonst müsste er alles neu eingeben...
|
||||||
window.history.pushState({}, "", `${location.pathname}?uid=${ausweis.uid}`);
|
ausweis.uid = result.uid
|
||||||
window.location.href = `/kundendaten?uid=${ausweis.uid}`;
|
gebaeude.uid = result.gebaeude_uid
|
||||||
|
gebaeude_aufnahme_allgemein.uid = result.gebaeude_aufnahme_uid
|
||||||
|
window.history.pushState({}, "", `${location.pathname}?uid=${result.uid}`);
|
||||||
|
window.location.href = `/kundendaten?uid=${result.uid}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let waitOverlayHidden = true;
|
let waitOverlayHidden = true;
|
||||||
let speichernOverlayHidden = true;
|
let speichernOverlayHidden = true;
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (gebaeude_aufnahme_allgemein.saniert
|
||||||
|
&& gebaeude_aufnahme_allgemein.oberste_geschossdecke_gedaemmt === undefined
|
||||||
|
&& gebaeude_aufnahme_allgemein.dachgeschoss_gedaemmt === undefined) {
|
||||||
|
|
||||||
|
gebaeude_aufnahme_allgemein.oberste_geschossdecke_gedaemmt = true;
|
||||||
|
gebaeude_aufnahme_allgemein.dachgeschoss_gedaemmt = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Overlay bind:hidden={speichernOverlayHidden}>
|
<Overlay bind:hidden={speichernOverlayHidden}>
|
||||||
@@ -221,7 +114,9 @@
|
|||||||
</Overlay>
|
</Overlay>
|
||||||
|
|
||||||
<Overlay bind:hidden={waitOverlayHidden}>
|
<Overlay bind:hidden={waitOverlayHidden}>
|
||||||
<p class="text-white font-semibold text-4xl">Bitte warten sie, ihr Ausweis wird nun erstellt.</p>
|
<p class="text-white font-semibold text-4xl">
|
||||||
|
Bitte warten sie, ihr Ausweis wird nun erstellt.
|
||||||
|
</p>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
|
|
||||||
<div class="flex flex-row gap-8 items-center mb-8">
|
<div class="flex flex-row gap-8 items-center mb-8">
|
||||||
@@ -230,15 +125,19 @@
|
|||||||
<Progressbar progress={0} />
|
<Progressbar progress={0} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PerformanceScore bind:ausweis />
|
<PerformanceScore
|
||||||
|
bind:ausweis
|
||||||
|
bind:gebaeude_aufnahme_allgemein
|
||||||
|
bind:gebaeude
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form on:submit={ausweisAbschicken} name="ausweis" data-test="ausweis">
|
<form on:submit={ausweisAbschicken} name="ausweis" data-test="ausweis">
|
||||||
<div
|
<div class="yellow-box">
|
||||||
class="yellow-box"
|
|
||||||
>
|
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<button class="button" type="button" on:click={spaeterWeitermachen}>Später Weitermachen</button>
|
<button class="button" type="button" on:click={spaeterWeitermachen}
|
||||||
|
>Später Weitermachen</button
|
||||||
|
>
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
<Hilfe />
|
<Hilfe />
|
||||||
<button
|
<button
|
||||||
@@ -253,7 +152,11 @@
|
|||||||
|
|
||||||
<Label>A - Prüfung der Ausweisart</Label>
|
<Label>A - Prüfung der Ausweisart</Label>
|
||||||
|
|
||||||
<Ausweisart bind:gebaeude bind:gebaeude_aufnahme_allgemein bind:ausweis />
|
<Ausweisart
|
||||||
|
bind:gebaeude
|
||||||
|
bind:gebaeude_aufnahme_allgemein
|
||||||
|
bind:ausweis
|
||||||
|
/>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
@@ -271,13 +174,14 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="adresse" data-test="adresse"
|
name="adresse"
|
||||||
|
data-test="adresse"
|
||||||
type="text"
|
type="text"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
required
|
required
|
||||||
data-msg-minlength="min. 5 Zeichen"
|
data-msg-minlength="min. 5 Zeichen"
|
||||||
data-msg-maxlength="max. 40 Zeichen"
|
data-msg-maxlength="max. 40 Zeichen"
|
||||||
bind:value={gebaeude.adresse}
|
bind:value={gebaeude_aufnahme_allgemein.adresse}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -285,9 +189,9 @@
|
|||||||
<!-- PLZ -->
|
<!-- PLZ -->
|
||||||
<div class="form-group col-md-4 PLZ">
|
<div class="form-group col-md-4 PLZ">
|
||||||
<ZipSearch
|
<ZipSearch
|
||||||
bind:zip={gebaeude.plz}
|
bind:zip={gebaeude_aufnahme_allgemein.plz}
|
||||||
bind:city={gebaeude.ort}
|
bind:city={gebaeude_aufnahme_allgemein.ort}
|
||||||
name="plz" data-test="plz"
|
name="plz"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -297,9 +201,10 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="ort" data-test="ort"
|
name="ort"
|
||||||
|
data-test="ort"
|
||||||
readonly={true}
|
readonly={true}
|
||||||
bind:value={gebaeude.ort}
|
bind:value={gebaeude_aufnahme_allgemein.ort}
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -314,7 +219,8 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="flaeche" data-test="flaeche"
|
name="flaeche"
|
||||||
|
data-test="flaeche"
|
||||||
maxlength="4"
|
maxlength="4"
|
||||||
type="number"
|
type="number"
|
||||||
required
|
required
|
||||||
@@ -331,14 +237,21 @@
|
|||||||
<Label>Keller *</Label>
|
<Label>Keller *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="keller" data-test="keller"
|
name="keller"
|
||||||
|
data-test="keller"
|
||||||
required
|
required
|
||||||
bind:value={gebaeude_aufnahme_allgemein.keller}
|
bind:value={gebaeude_aufnahme_allgemein.keller}
|
||||||
>
|
>
|
||||||
<option disabled>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
|
||||||
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
|
>nicht vorhanden</option
|
||||||
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
|
>
|
||||||
|
<option value={Enums.Heizungsstatus.UNBEHEIZT}
|
||||||
|
>unbeheizt</option
|
||||||
|
>
|
||||||
|
<option value={Enums.Heizungsstatus.BEHEIZT}
|
||||||
|
>beheizt</option
|
||||||
|
>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -347,11 +260,22 @@
|
|||||||
<div class="form-group col-md-3">
|
<div class="form-group col-md-3">
|
||||||
<Label>Dachgeschoss *</Label>
|
<Label>Dachgeschoss *</Label>
|
||||||
<div>
|
<div>
|
||||||
<select name="dachgeschoss" data-test="dachgeschoss" bind:value={gebaeude_aufnahme_allgemein.dachgeschoss} required>
|
<select
|
||||||
|
name="dachgeschoss"
|
||||||
|
data-test="dachgeschoss"
|
||||||
|
bind:value={gebaeude_aufnahme_allgemein.dachgeschoss}
|
||||||
|
required
|
||||||
|
>
|
||||||
<option disabled>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}>nicht vorhanden</option>
|
<option value={Enums.Heizungsstatus.NICHT_VORHANDEN}
|
||||||
<option value={Enums.Heizungsstatus.UNBEHEIZT}>unbeheizt</option>
|
>nicht vorhanden</option
|
||||||
<option value={Enums.Heizungsstatus.BEHEIZT}>beheizt</option>
|
>
|
||||||
|
<option value={Enums.Heizungsstatus.UNBEHEIZT}
|
||||||
|
>unbeheizt</option
|
||||||
|
>
|
||||||
|
<option value={Enums.Heizungsstatus.BEHEIZT}
|
||||||
|
>beheizt</option
|
||||||
|
>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -359,14 +283,16 @@
|
|||||||
<!-- Gesamtfläche -->
|
<!-- Gesamtfläche -->
|
||||||
<div class="form-group col-md-3">
|
<div class="form-group col-md-3">
|
||||||
<HelpLabel title="Gesamtfläche m²">
|
<HelpLabel title="Gesamtfläche m²">
|
||||||
Bitte geben Sie hier die beheizte Gesamtfläche in m² ein (wenn bekannt).
|
Bitte geben Sie hier die beheizte Gesamtfläche in m² ein
|
||||||
Dabei handelt es sich um die Wohnfläche + weiterer Flächen innerhalb des Gebäudes
|
(wenn bekannt). Dabei handelt es sich um die Wohnfläche +
|
||||||
(z.B. Fläche des beheizten Kellers).
|
weiterer Flächen innerhalb des Gebäudes (z.B. Fläche des
|
||||||
Diese Fläche wird dann im Energieausweis als energetische Nutzfläche (An) ausgewiesen.
|
beheizten Kellers). Diese Fläche wird dann im Energieausweis
|
||||||
|
als energetische Nutzfläche (An) ausgewiesen.
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="nutzflaeche" data-test="nutzflaeche"
|
name="nutzflaeche"
|
||||||
|
data-test="nutzflaeche"
|
||||||
maxlength="4"
|
maxlength="4"
|
||||||
type="number"
|
type="number"
|
||||||
required
|
required
|
||||||
@@ -384,7 +310,11 @@
|
|||||||
<Label>C - Eingabe von 3 zusammenhängenden Verbrauchsjahren</Label>
|
<Label>C - Eingabe von 3 zusammenhängenden Verbrauchsjahren</Label>
|
||||||
|
|
||||||
<div class="GRB">
|
<div class="GRB">
|
||||||
<Verbrauch bind:gebaeude bind:gebaeude_aufnahme_allgemein bind:ausweis />
|
<Verbrauch
|
||||||
|
bind:gebaeude
|
||||||
|
bind:gebaeude_aufnahme_allgemein
|
||||||
|
bind:ausweis
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -401,7 +331,8 @@
|
|||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="checkbox"
|
class="checkbox"
|
||||||
name="warmwasser_enthalten" data-test="warmwasser_enthalten"
|
name="warmwasser_enthalten"
|
||||||
|
data-test="warmwasser_enthalten"
|
||||||
bind:checked={ausweis.warmwasser_enthalten}
|
bind:checked={ausweis.warmwasser_enthalten}
|
||||||
/>
|
/>
|
||||||
<Label>Warmwasser im Verbrauch enthalten</Label>
|
<Label>Warmwasser im Verbrauch enthalten</Label>
|
||||||
@@ -410,7 +341,8 @@
|
|||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="checkbox"
|
class="checkbox"
|
||||||
name="warmwasser_anteil_bekannt" data-test="warmwasser_anteil_bekannt"
|
name="warmwasser_anteil_bekannt"
|
||||||
|
data-test="warmwasser_anteil_bekannt"
|
||||||
bind:checked={ausweis.warmwasser_anteil_bekannt}
|
bind:checked={ausweis.warmwasser_anteil_bekannt}
|
||||||
disabled={!ausweis.warmwasser_enthalten}
|
disabled={!ausweis.warmwasser_enthalten}
|
||||||
/>
|
/>
|
||||||
@@ -426,11 +358,13 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
name="anteil_warmwasser_1" data-test="anteil_warmwasser_1"
|
name="anteil_warmwasser_1"
|
||||||
|
data-test="anteil_warmwasser_1"
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={ausweis.anteil_warmwasser_1}
|
bind:value={ausweis.anteil_warmwasser_1}
|
||||||
disabled={!ausweis.warmwasser_anteil_bekannt || !ausweis.warmwasser_enthalten}
|
disabled={!ausweis.warmwasser_anteil_bekannt ||
|
||||||
|
!ausweis.warmwasser_enthalten}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -442,13 +376,15 @@
|
|||||||
ein Anteil von 18% angenommen.
|
ein Anteil von 18% angenommen.
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<input
|
<input
|
||||||
name="anteil_warmwasser_2" data-test="anteil_warmwasser_2"
|
name="anteil_warmwasser_2"
|
||||||
|
data-test="anteil_warmwasser_2"
|
||||||
maxlength="3"
|
maxlength="3"
|
||||||
type="number"
|
type="number"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
bind:value={ausweis.anteil_warmwasser_2}
|
bind:value={ausweis.anteil_warmwasser_2}
|
||||||
disabled={!ausweis.zusaetzliche_heizquelle ||
|
disabled={!ausweis.zusaetzliche_heizquelle ||
|
||||||
!ausweis.warmwasser_anteil_bekannt || !ausweis.warmwasser_enthalten}
|
!ausweis.warmwasser_anteil_bekannt ||
|
||||||
|
!ausweis.warmwasser_enthalten}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -465,7 +401,8 @@
|
|||||||
<label class="checkbox-inline"
|
<label class="checkbox-inline"
|
||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="alternative_heizung" data-test="alternative_heizung"
|
name="alternative_heizung"
|
||||||
|
data-test="alternative_heizung"
|
||||||
bind:checked={ausweis.alternative_heizung}
|
bind:checked={ausweis.alternative_heizung}
|
||||||
value="Heizung"
|
value="Heizung"
|
||||||
/>Heizung</label
|
/>Heizung</label
|
||||||
@@ -473,7 +410,8 @@
|
|||||||
<label class="checkbox-inline"
|
<label class="checkbox-inline"
|
||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="alternative_warmwasser" data-test="alternative_warmwasser"
|
name="alternative_warmwasser"
|
||||||
|
data-test="alternative_warmwasser"
|
||||||
bind:checked={ausweis.alternative_warmwasser}
|
bind:checked={ausweis.alternative_warmwasser}
|
||||||
value="Warmwasser"
|
value="Warmwasser"
|
||||||
/>Warmwasser</label
|
/>Warmwasser</label
|
||||||
@@ -481,7 +419,8 @@
|
|||||||
<label class="checkbox-inline"
|
<label class="checkbox-inline"
|
||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="alternative_lueftung" data-test="alternative_lueftung"
|
name="alternative_lueftung"
|
||||||
|
data-test="alternative_lueftung"
|
||||||
bind:checked={ausweis.alternative_lueftung}
|
bind:checked={ausweis.alternative_lueftung}
|
||||||
value="Lüftung"
|
value="Lüftung"
|
||||||
/>Lüftung</label
|
/>Lüftung</label
|
||||||
@@ -489,7 +428,8 @@
|
|||||||
<label class="checkbox-inline"
|
<label class="checkbox-inline"
|
||||||
><input
|
><input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="alternative_kuehlung" data-test="alternative_kuehlung"
|
name="alternative_kuehlung"
|
||||||
|
data-test="alternative_kuehlung"
|
||||||
bind:checked={ausweis.alternative_kuehlung}
|
bind:checked={ausweis.alternative_kuehlung}
|
||||||
value="Kühlung"
|
value="Kühlung"
|
||||||
/>Kühlung</label
|
/>Kühlung</label
|
||||||
@@ -512,7 +452,12 @@
|
|||||||
Bitte wählen Sie hier den Gebäudetyp aus.
|
Bitte wählen Sie hier den Gebäudetyp aus.
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select name="gebaeudetyp" data-test="gebaeudetyp" required>
|
<select
|
||||||
|
name="gebaeudetyp"
|
||||||
|
data-test="gebaeudetyp"
|
||||||
|
bind:value={gebaeude_aufnahme_allgemein.gebaeudetyp}
|
||||||
|
required
|
||||||
|
>
|
||||||
<option disabled>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
<option value="Einfamilienhaus">Einfamilienhaus</option>
|
<option value="Einfamilienhaus">Einfamilienhaus</option>
|
||||||
<option value="Freistehendes Einfamilienhaus"
|
<option value="Freistehendes Einfamilienhaus"
|
||||||
@@ -551,7 +496,12 @@
|
|||||||
'Gewerbe'.
|
'Gewerbe'.
|
||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select name="gebaeudeteil" data-test="gebaeudeteil" required>
|
<select
|
||||||
|
name="gebaeudeteil"
|
||||||
|
data-test="gebaeudeteil"
|
||||||
|
bind:value={gebaeude_aufnahme_allgemein.gebaeudeteil}
|
||||||
|
required
|
||||||
|
>
|
||||||
<option disabled>Bitte auswählen</option>
|
<option disabled>Bitte auswählen</option>
|
||||||
<option value="Gesamtgebäude">Gesamtgebäude</option>
|
<option value="Gesamtgebäude">Gesamtgebäude</option>
|
||||||
<option value="Wohnen">Wohnen</option>
|
<option value="Wohnen">Wohnen</option>
|
||||||
@@ -567,7 +517,8 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="lueftung" data-test="lueftung"
|
name="lueftung"
|
||||||
|
data-test="lueftung"
|
||||||
required
|
required
|
||||||
bind:value={gebaeude_aufnahme_allgemein.lueftung}
|
bind:value={gebaeude_aufnahme_allgemein.lueftung}
|
||||||
>
|
>
|
||||||
@@ -592,7 +543,8 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
name="kuehlung" data-test="kuehlung"
|
name="kuehlung"
|
||||||
|
data-test="kuehlung"
|
||||||
required
|
required
|
||||||
bind:value={gebaeude_aufnahme_allgemein.kuehlung}
|
bind:value={gebaeude_aufnahme_allgemein.kuehlung}
|
||||||
>
|
>
|
||||||
@@ -612,7 +564,8 @@
|
|||||||
</HelpLabel>
|
</HelpLabel>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
name="leerstand" data-test="leerstand"
|
name="leerstand"
|
||||||
|
data-test="leerstand"
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
type="number"
|
type="number"
|
||||||
bind:value={gebaeude_aufnahme_allgemein.leerstand}
|
bind:value={gebaeude_aufnahme_allgemein.leerstand}
|
||||||
@@ -627,7 +580,7 @@
|
|||||||
>F - Bitte prüfen Sie hier die Angaben zum Sanierungszustand des
|
>F - Bitte prüfen Sie hier die Angaben zum Sanierungszustand des
|
||||||
Gebäudes</Label
|
Gebäudes</Label
|
||||||
>
|
>
|
||||||
<BilderZusatzsysteme {images} {gebaeude} {gebaeude_aufnahme_allgemein} {ausweis} />
|
<BilderZusatzsysteme bind:images bind:gebaeude bind:gebaeude_aufnahme_allgemein bind:ausweis />
|
||||||
<hr />
|
<hr />
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<Hilfe />
|
<Hilfe />
|
||||||
@@ -636,7 +589,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<RawNotificationWrapper>
|
<RawNotificationWrapper>
|
||||||
{#each Object.entries($notifications) as [uid, notification] (uid)}
|
{#each Object.entries($notifications) as [uid, notification] (uid)}
|
||||||
<RawNotification notification={{ ...notification, uid }}>
|
<RawNotification notification={{ ...notification, uid }}>
|
||||||
@@ -660,6 +612,28 @@
|
|||||||
</RawNotification>
|
</RawNotification>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#await auditPlzNichtErkannt(gebaeude_aufnahme_allgemein) then result}
|
||||||
|
{#if result}
|
||||||
|
<RawNotification
|
||||||
|
notification={{
|
||||||
|
message: "Plausibilitätsprüfung",
|
||||||
|
timeout: 0,
|
||||||
|
uid: "PLZ_NICHT_ERKANNT",
|
||||||
|
dismissable: true,
|
||||||
|
onUserDismiss: () => {
|
||||||
|
hidden.add(AuditType.PLZ_NICHT_ERKANNT);
|
||||||
|
gebaeude = gebaeude;
|
||||||
|
},
|
||||||
|
type: "warning",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Die Postleitzahl konnte nicht zugeordnet werden. Bitte prüfen
|
||||||
|
Sie die Eingabe. Sollte die Postleitzahl korrekt eingegeben
|
||||||
|
sein, werden wir den Ort händisch zuordnen.
|
||||||
|
</RawNotification>
|
||||||
|
{/if}
|
||||||
|
{/await}
|
||||||
|
|
||||||
{#if auditHeizungGebaeudeBaujahr(gebaeude_aufnahme_allgemein)}
|
{#if auditHeizungGebaeudeBaujahr(gebaeude_aufnahme_allgemein)}
|
||||||
<RawNotification
|
<RawNotification
|
||||||
notification={{
|
notification={{
|
||||||
@@ -693,9 +667,10 @@
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Ihre Heizungsanlage ist jünger als 3 Jahre. Für den Verbrauchsausweis müssen
|
Ihre Heizungsanlage ist jünger als 3 Jahre. Für den
|
||||||
Sie mindestens 3 Verbrauchsjahre eingeben die den aktuellen Stand des Gebäudes
|
Verbrauchsausweis müssen Sie mindestens 3 Verbrauchsjahre eingeben
|
||||||
abbilden. Ein Verbrauchsausweis ist daher nicht möglich. Bitte klicken Sie
|
die den aktuellen Stand des Gebäudes abbilden. Ein Verbrauchsausweis
|
||||||
|
ist daher nicht möglich. Bitte klicken Sie
|
||||||
<a href="/bedarfsausweis">hier</a> um zum Eingabeformular für den Bedarfsausweis
|
<a href="/bedarfsausweis">hier</a> um zum Eingabeformular für den Bedarfsausweis
|
||||||
zu gelangen.
|
zu gelangen.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
@@ -715,11 +690,11 @@
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Die Verbrauchszeiträume sind nicht aktuell genug. Das Ende des letzten
|
Die Verbrauchszeiträume sind nicht aktuell genug. Das Ende des
|
||||||
Verbrauchszeitraumes darf nicht mehr als 18 Monate zurückliegen. Ein
|
letzten Verbrauchszeitraumes darf nicht mehr als 18 Monate
|
||||||
Verbrauchsausweis ist mit diesen Zeiträumen daher nicht möglich. Bitte
|
zurückliegen. Ein Verbrauchsausweis ist mit diesen Zeiträumen daher
|
||||||
klicken Sie <a href="/bedarfsausweis">hier</a> um zum Eingabeformular
|
nicht möglich. Bitte klicken Sie <a href="/bedarfsausweis">hier</a> um
|
||||||
für den Bedarfsausweis zu gelangen.
|
zum Eingabeformular für den Bedarfsausweis zu gelangen.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -739,8 +714,9 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Die Verbrauchszeiträume sind zu aktuell und es liegen noch keine
|
Die Verbrauchszeiträume sind zu aktuell und es liegen noch keine
|
||||||
Klimafaktoren dazu vor. Bitte verschieben Sie die Verbrauchszeiträume
|
Klimafaktoren dazu vor. Bitte verschieben Sie die
|
||||||
1 Jahr nach hinten. Wenn das nicht möglich ist, klicken Sie
|
Verbrauchszeiträume 1 Jahr nach hinten. Wenn das nicht möglich
|
||||||
|
ist, klicken Sie
|
||||||
<a href="/bedarfsausweis">hier</a> um zum Eingabeformular für den
|
<a href="/bedarfsausweis">hier</a> um zum Eingabeformular für den
|
||||||
Bedarfsausweis zu gelangen.
|
Bedarfsausweis zu gelangen.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
@@ -761,8 +737,9 @@
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Die Wohnfläche ist viel zu klein. Bitte überprüfen Sie Ihre Eingabe nochmal
|
Die Wohnfläche ist viel zu klein. Bitte überprüfen Sie Ihre Eingabe
|
||||||
und stellen sicher, daß sich Ihre Angaben auf das gesamte Gebäude beziehen.
|
nochmal und stellen sicher, daß sich Ihre Angaben auf das gesamte
|
||||||
|
Gebäude beziehen.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -780,8 +757,8 @@
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Bitte überprüfen Sie nochmal die Höhe des Warmwasseranteils. Dieser scheint
|
Bitte überprüfen Sie nochmal die Höhe des Warmwasseranteils. Dieser
|
||||||
nicht ganz im Rahmen zu liegen.
|
scheint nicht ganz im Rahmen zu liegen.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -799,8 +776,8 @@
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Bei Leerstand größer als 30% darf kein Verbrauchsausweis ausgestellt werden.
|
Bei Leerstand größer als 30% darf kein Verbrauchsausweis ausgestellt
|
||||||
Bitte klicken Sie <a href="/bedarfsausweis">hier</a> um zum Eingabeformular
|
werden. Bitte klicken Sie <a href="/bedarfsausweis">hier</a> um zum Eingabeformular
|
||||||
für den Bedarfsausweis zu gelangen.
|
für den Bedarfsausweis zu gelangen.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -819,17 +796,59 @@
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Die Abweichung der Verbräuche zwischen Zeitraum {auditVerbrauchAbweichung(ausweis,
|
Die Abweichung der Verbräuche zwischen Zeitraum {auditVerbrauchAbweichung(
|
||||||
gebaeude
|
ausweis,
|
||||||
)[0]} und {auditVerbrauchAbweichung(ausweis, gebaeude)[1]} beträgt mehr als 25%
|
gebaeude,
|
||||||
und sie haben keinen Leerstand angegeben. Sind sie sich sicher, dass
|
)[0]} und {auditVerbrauchAbweichung(ausweis, gebaeude)[1]} beträgt mehr
|
||||||
das stimmt?
|
als 30% und sie haben keinen Leerstand angegeben. Sind sie sich sicher,
|
||||||
|
dass das stimmt?
|
||||||
|
</RawNotification>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#await auditEndEnergie(ausweis, gebaeude, gebaeude_aufnahme_allgemein) then result}
|
||||||
|
{#if result}
|
||||||
|
<RawNotification
|
||||||
|
notification={{
|
||||||
|
message: "Plausibilitätsprüfung",
|
||||||
|
timeout: 0,
|
||||||
|
uid: "END_ENERGIE",
|
||||||
|
dismissable: true,
|
||||||
|
onUserDismiss: () => {
|
||||||
|
hidden.add(AuditType.END_ENERGIE);
|
||||||
|
gebaeude = gebaeude;
|
||||||
|
},
|
||||||
|
type: "warning",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Die Endenergie liegt außerhalb des normalen Rahmens. Bitte
|
||||||
|
nochmal überprüfen. Bei Passivhäusern oder ganz alten
|
||||||
|
unsanierten Gebäuden ist so eine Abweichung durchaus möglich.
|
||||||
|
</RawNotification>
|
||||||
|
{/if}
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#if auditWohnflaecheGroesserGesamtflaeche(gebaeude_aufnahme_allgemein)}
|
||||||
|
<RawNotification
|
||||||
|
notification={{
|
||||||
|
message: "Plausibilitätsprüfung",
|
||||||
|
timeout: 0,
|
||||||
|
uid: "WOHNFLAECHE_GROESSER_GESAMTFLAECHE",
|
||||||
|
dismissable: true,
|
||||||
|
onUserDismiss: () => {
|
||||||
|
hidden.add(AuditType.WOHNFLAECHE_GROESSER_GESAMTFLAECHE);
|
||||||
|
gebaeude = gebaeude;
|
||||||
|
},
|
||||||
|
type: "warning",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Die Wohnfläche darf nicht größer als die Nutzfläche sein.
|
||||||
</RawNotification>
|
</RawNotification>
|
||||||
{/if}
|
{/if}
|
||||||
</RawNotificationWrapper>
|
</RawNotificationWrapper>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:global(input[type="number"]), :global(input[type="text"]) {
|
:global(input[type="number"]),
|
||||||
|
:global(input[type="text"]) {
|
||||||
@apply input input-bordered py-1.5 px-2 h-auto;
|
@apply input input-bordered py-1.5 px-2 h-auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
limit: 10
|
limit: 10
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(ausweise);
|
||||||
|
|
||||||
|
|
||||||
if (!ausweise) return;
|
if (!ausweise) return;
|
||||||
|
|
||||||
ausweisUeberpruefung = ausweise.map(ausweis => verbrauchsausweisWohnenCalculateFormProgress(ausweis));
|
ausweisUeberpruefung = ausweise.map(ausweis => verbrauchsausweisWohnenCalculateFormProgress(ausweis));
|
||||||
|
|||||||
@@ -61,9 +61,9 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1 class="text-4xl font-medium my-8">Einstellungen</h1>
|
<h1 class="text-4xl font-medium mb-8">Einstellungen</h1>
|
||||||
<Tabs class="h-full">
|
<Tabs class="h-[calc(100%-6rem)]">
|
||||||
<div class="grid grid-cols-[1fr_3fr] h-full gap-8">
|
<div class="grid grid-cols-1 md:grid-cols-[1fr_3fr] h-full gap-8">
|
||||||
<TabList>
|
<TabList>
|
||||||
<Tab>
|
<Tab>
|
||||||
<Person size={22} />
|
<Person size={22} />
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
<TabPanel>
|
<TabPanel>
|
||||||
<h2 class="text-2xl font-medium">Profil</h2>
|
<h2 class="text-2xl font-medium">Profil</h2>
|
||||||
<form class="flex flex-col gap-4 my-4 max-w-2xl" on:submit={profilSpeichern}>
|
<form class="flex flex-col gap-4 my-4 max-w-2xl" on:submit={profilSpeichern}>
|
||||||
<div class="flex flex-row gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<span class="whitespace-nowrap">Vorname</span>
|
<span class="whitespace-nowrap">Vorname</span>
|
||||||
<input type="text" class="input text-base-content font-medium" placeholder="Max" bind:value={benutzer.vorname}>
|
<input type="text" class="input text-base-content font-medium" placeholder="Max" bind:value={benutzer.vorname}>
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
<span class="whitespace-nowrap">Telefonnummer</span>
|
<span class="whitespace-nowrap">Telefonnummer</span>
|
||||||
<input type="phone" class="input text-base-content font-medium" placeholder="040 12345678" bind:value={benutzer.telefon}>
|
<input type="phone" class="input text-base-content font-medium" placeholder="040 12345678" bind:value={benutzer.telefon}>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<span class="whitespace-nowrap">Adresse</span>
|
<span class="whitespace-nowrap">Adresse</span>
|
||||||
<input type="text" class="input text-base-content font-medium" placeholder="Musterstraße 123" bind:value={benutzer.adresse}>
|
<input type="text" class="input text-base-content font-medium" placeholder="Musterstraße 123" bind:value={benutzer.adresse}>
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
<input type="text" class="input text-base-content font-medium" placeholder="Musterhausen" bind:value={benutzer.ort}>
|
<input type="text" class="input text-base-content font-medium" placeholder="Musterhausen" bind:value={benutzer.ort}>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<span class="whitespace-nowrap">Passwort</span>
|
<span class="whitespace-nowrap">Passwort</span>
|
||||||
<input type="password" class="input text-base-content font-medium" placeholder="*********" bind:value={passwort}>
|
<input type="password" class="input text-base-content font-medium" placeholder="*********" bind:value={passwort}>
|
||||||
@@ -152,7 +152,8 @@
|
|||||||
</form>
|
</form>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<h1>Panel Two</h1>
|
<h2 class="text-2xl font-medium">Ausweise</h2>
|
||||||
|
<p>In Zukunft werden sie hier spezifische Einstellungen für die Ausweisgenerierung ansehen können. Bitte haben sie Geduld.</p>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
29
src/modules/Dashboard/DashboardModule.svelte
Normal file
29
src/modules/Dashboard/DashboardModule.svelte
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { BenutzerClient, GebaeudeClient } from "#components/Ausweis/types";
|
||||||
|
|
||||||
|
export let user: BenutzerClient;
|
||||||
|
export let gebaeudeArray: GebaeudeClient[];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<h1 class="text-4xl font-medium my-8">Willkommen zurück, {user.vorname}!</h1>
|
||||||
|
<p class="text-lg">
|
||||||
|
Hier finden Sie eine Übersicht über all ihre Ausweise und Gebäude.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1 class="text-4xl font-medium my-8">Gebäude</h1>
|
||||||
|
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
|
||||||
|
{#each gebaeudeArray as gebaeude}
|
||||||
|
<div class="card lg:card-side bg-base-200 card-bordered border-base-300">
|
||||||
|
<figure class="lg:w-1/2">
|
||||||
|
<img
|
||||||
|
src={(gebaeude.gebaeude_bilder && `/bilder/${gebaeude.gebaeude_bilder[0]?.uid}.webp`) || "/images/placeholder.jpg"}
|
||||||
|
class="object-cover w-full h-full"
|
||||||
|
alt="Gebäudebild"
|
||||||
|
/>
|
||||||
|
</figure>
|
||||||
|
<div class="card-body lg:w-1/2 p-4">
|
||||||
|
<h4 class="text-lg font-semibold">{gebaeude.adresse}, {gebaeude.plz} {gebaeude.ort}</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
@@ -43,8 +43,9 @@
|
|||||||
|
|
||||||
function addNewField() {
|
function addNewField() {
|
||||||
template = designer.getTemplate();
|
template = designer.getTemplate();
|
||||||
|
const page = designer.getPageCursor();
|
||||||
|
|
||||||
template.schemas[0]["new-field"] = {
|
template.schemas[page]["new-field"] = {
|
||||||
type: "text",
|
type: "text",
|
||||||
position: { x: 0, y: 0 },
|
position: { x: 0, y: 0 },
|
||||||
width: 10,
|
width: 10,
|
||||||
@@ -87,9 +88,18 @@
|
|||||||
input.click()
|
input.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onKeydown(e: KeyboardEvent) {
|
||||||
|
if (e.ctrlKey && e.key === "s") {
|
||||||
|
e.preventDefault();
|
||||||
|
exportTemplate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let loadTemplateInput: HTMLInputElement;
|
let loadTemplateInput: HTMLInputElement;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:keydown={onKeydown}></svelte:window>
|
||||||
|
|
||||||
<header class="mb-4">
|
<header class="mb-4">
|
||||||
<button class="btn btn-secondary" on:click={() => loadTemplateInput.click()}>Change base PDF</button>
|
<button class="btn btn-secondary" on:click={() => loadTemplateInput.click()}>Change base PDF</button>
|
||||||
<button class="btn btn-secondary" on:click={addNewField}>Add new Field</button>
|
<button class="btn btn-secondary" on:click={addNewField}>Add new Field</button>
|
||||||
@@ -99,4 +109,4 @@
|
|||||||
<input type="file" hidden bind:this={loadTemplateInput} on:change={loadBasePDF}>
|
<input type="file" hidden bind:this={loadTemplateInput} on:change={loadBasePDF}>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div bind:this={container}></div>
|
<div bind:this={container} class="h-[80vh]"></div>
|
||||||
|
|||||||
@@ -5,13 +5,14 @@
|
|||||||
import { Viewer } from "@pdfme/ui";
|
import { Viewer } from "@pdfme/ui";
|
||||||
import { Check } from "radix-svelte-icons";
|
import { Check } from "radix-svelte-icons";
|
||||||
import { image, text } from "@pdfme/schemas";
|
import { image, text } from "@pdfme/schemas";
|
||||||
import { AusweisData, convertAusweisData } from "#lib/AusweisData";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { convertAusweisData } from "#lib/AusweisData";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export let ausweise: AusweisData[];
|
export let ausweise: VerbrauchsausweisWohnenClient[];
|
||||||
|
|
||||||
let pdfInputs: AusweisData;
|
let pdfInputs: VerbrauchsausweisWohnenClient;
|
||||||
let template: Template;
|
let template: Template;
|
||||||
let viewer: Viewer
|
let viewer: Viewer
|
||||||
|
|
||||||
@@ -37,11 +38,13 @@
|
|||||||
return
|
return
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const convertedInputs = convertAusweisData(pdfInputs);
|
||||||
|
|
||||||
viewer = new Viewer({
|
viewer = new Viewer({
|
||||||
domContainer: pdfViewerContainer,
|
domContainer: pdfViewerContainer,
|
||||||
template,
|
template,
|
||||||
inputs: [convertAusweisData(pdfInputs)],
|
inputs: [convertedInputs],
|
||||||
plugins: { text, image, variable}
|
plugins: { text, image, variable: { ...variable, pdf: variable.pdf.bind(convertedInputs), ui: variable.ui.bind(convertedInputs) } }
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,8 +54,9 @@
|
|||||||
input.click();
|
input.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeInputs(inputs: AusweisData) {
|
function changeInputs(inputs: VerbrauchsausweisWohnenClient) {
|
||||||
pdfInputs = inputs;
|
pdfInputs = inputs;
|
||||||
|
|
||||||
if (!template) {
|
if (!template) {
|
||||||
alert("Bitte laden Sie zuerst ein Template.")
|
alert("Bitte laden Sie zuerst ein Template.")
|
||||||
return
|
return
|
||||||
@@ -60,11 +64,13 @@
|
|||||||
|
|
||||||
if (viewer) viewer.destroy();
|
if (viewer) viewer.destroy();
|
||||||
|
|
||||||
|
const convertedInputs = convertAusweisData(pdfInputs);
|
||||||
|
|
||||||
viewer = new Viewer({
|
viewer = new Viewer({
|
||||||
domContainer: pdfViewerContainer,
|
domContainer: pdfViewerContainer,
|
||||||
template,
|
template,
|
||||||
inputs: [convertAusweisData(pdfInputs)],
|
inputs: [convertedInputs],
|
||||||
plugins: { text, image, variable}
|
plugins: { text, image, variable: { ...variable, pdf: variable.pdf.bind(convertedInputs), ui: variable.ui.bind(convertedInputs) } }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +87,7 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
{#each ausweise as ausweis}
|
{#each ausweise as ausweis}
|
||||||
<div class="rounded-lg border p-2 flex flex-row items-center justify-between">
|
<div class="rounded-lg border p-2 flex flex-row items-center justify-between">
|
||||||
<h2 class="text-black">{ausweis.gebaeude_stammdaten.adresse}</h2>
|
<h2 class="text-black">{ausweis.gebaeude_aufnahme_allgemein.gebaeude_stammdaten.adresse}</h2>
|
||||||
<button class="btn btn-square btn-ghost p-1.5" on:click={() => {
|
<button class="btn btn-square btn-ghost p-1.5" on:click={() => {
|
||||||
changeInputs(ausweis)
|
changeInputs(ausweis)
|
||||||
}}><Check size={20}/></button>
|
}}><Check size={20}/></button>
|
||||||
|
|||||||
@@ -2,11 +2,7 @@
|
|||||||
import ZipSearch from "../components/PlzSuche.svelte";
|
import ZipSearch from "../components/PlzSuche.svelte";
|
||||||
import Label from "../components/Label.svelte";
|
import Label from "../components/Label.svelte";
|
||||||
import type {
|
import type {
|
||||||
BedarfsausweisWohnen,
|
|
||||||
Benutzer,
|
|
||||||
Bezahlmethoden,
|
Bezahlmethoden,
|
||||||
VerbrauchsausweisGewerbe,
|
|
||||||
VerbrauchsausweisWohnen,
|
|
||||||
} from "@ibcornelsen/database/client";
|
} from "@ibcornelsen/database/client";
|
||||||
import { Enums } from "@ibcornelsen/database/client";
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
import PaymentOption from "#components/PaymentOption.svelte";
|
import PaymentOption from "#components/PaymentOption.svelte";
|
||||||
@@ -15,6 +11,7 @@
|
|||||||
import type { AppRouter } from "@ibcornelsen/api";
|
import type { AppRouter } from "@ibcornelsen/api";
|
||||||
import CheckoutItem from "#components/CheckoutItem.svelte";
|
import CheckoutItem from "#components/CheckoutItem.svelte";
|
||||||
import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { PRICES } from "#lib/constants";
|
||||||
|
|
||||||
export let user: BenutzerClient;
|
export let user: BenutzerClient;
|
||||||
export let ausweis:
|
export let ausweis:
|
||||||
@@ -22,7 +19,18 @@
|
|||||||
// TODO: überarbeiten und zu inferProcedureOutput machen
|
// TODO: überarbeiten und zu inferProcedureOutput machen
|
||||||
let rechnung: inferProcedureInput<
|
let rechnung: inferProcedureInput<
|
||||||
AppRouter["v1"]["rechnungen"]["erstellen"]
|
AppRouter["v1"]["rechnungen"]["erstellen"]
|
||||||
> = {};
|
> = {
|
||||||
|
email: user.email,
|
||||||
|
empfaenger: user.vorname + " " + user.name,
|
||||||
|
strasse: user.adresse,
|
||||||
|
plz: user.plz,
|
||||||
|
ort: user.ort,
|
||||||
|
versand_empfaenger: user.vorname + " " + user.name,
|
||||||
|
versand_strasse: user.adresse,
|
||||||
|
versand_plz: user.plz,
|
||||||
|
versand_ort: user.ort,
|
||||||
|
telefon: user.telefon,
|
||||||
|
};
|
||||||
|
|
||||||
let services = [
|
let services = [
|
||||||
{
|
{
|
||||||
@@ -54,15 +62,12 @@
|
|||||||
export let selectedPaymentType: Bezahlmethoden =
|
export let selectedPaymentType: Bezahlmethoden =
|
||||||
Enums.Bezahlmethoden.paypal;
|
Enums.Bezahlmethoden.paypal;
|
||||||
|
|
||||||
let agbAkzeptiert: boolean;
|
|
||||||
let datenschutzAkzeptiert: boolean;
|
|
||||||
|
|
||||||
async function createPayment(e: SubmitEvent) {
|
async function createPayment(e: SubmitEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const response = await client.v1.rechnungen.erstellen.mutate({
|
const response = await client.v1.rechnungen.erstellen.mutate({
|
||||||
...rechnung,
|
...rechnung,
|
||||||
ausweisart: ausweis.ausweisart,
|
ausweisart: Enums.Ausweisart.VerbrauchsausweisWohnen,
|
||||||
uid: ausweis.uid,
|
uid: ausweis.uid,
|
||||||
bezahlmethode: selectedPaymentType,
|
bezahlmethode: selectedPaymentType,
|
||||||
services: services
|
services: services
|
||||||
@@ -72,9 +77,16 @@
|
|||||||
|
|
||||||
window.location.href = response.checkout_url;
|
window.location.href = response.checkout_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const priceTotal = services.reduce((acc, service) => {
|
||||||
|
if (service.selected) {
|
||||||
|
return acc + service.price;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, 0) + PRICES[Enums.Ausweisart.VerbrauchsausweisWohnen][0];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="grid grid-cols-[2fr_1fr] gap-4 h-full">
|
<form class="grid grid-cols-[2fr_1fr] gap-4 h-full" on:submit={createPayment}>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="font-semibold">Ansprechpartner</h3>
|
<h3 class="font-semibold">Ansprechpartner</h3>
|
||||||
<div class="rounded-lg border p-4 border-base-300 bg-base-100">
|
<div class="rounded-lg border p-4 border-base-300 bg-base-100">
|
||||||
@@ -348,23 +360,23 @@
|
|||||||
<div class="mt-auto">
|
<div class="mt-auto">
|
||||||
<hr />
|
<hr />
|
||||||
<div class="flex flex-row items-center justify-between">
|
<div class="flex flex-row items-center justify-between">
|
||||||
<span class="opacity-75 text-sm">Brutto</span>
|
<span class="opacity-75 text-sm">Netto</span>
|
||||||
<span class="font-semibold text-sm">45€</span>
|
<span class="font-semibold text-sm">{priceTotal * 0.81}€</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center justify-between">
|
<div class="flex flex-row items-center justify-between">
|
||||||
<span class="opacity-75 text-sm">Netto</span>
|
<span class="opacity-75 text-sm">19% MwSt</span>
|
||||||
<span class="font-semibold text-sm">45€</span>
|
<span class="font-semibold text-sm">{priceTotal * 0.19}€</span>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="flex flex-row items-center justify-between">
|
<div class="flex flex-row items-center justify-between">
|
||||||
<span class="opacity-75 text-sm">Gesamt</span>
|
<span class="opacity-75 text-sm">Gesamt</span>
|
||||||
<span class="font-semibold text-sm">45€</span>
|
<span class="font-semibold text-sm">{priceTotal}€</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-8">Mit dem Klick auf "Bestellung Bestätigen" akzeptieren sie unsere <a href="/agb">AGB</a> und <a href="/impressum">Datenschutzbestimmungen</a>. Sie werden zu ihrem ausgewählten Bezahlprovider weitergeleitet, nach Bezahlung werden sie automatisch zu unserem Portal zurückgeleitet.</p>
|
<p class="mt-8">Mit dem Klick auf "Bestellung Bestätigen" akzeptieren sie unsere <a href="/agb">AGB</a> und <a href="/impressum">Datenschutzbestimmungen</a>. Sie werden zu ihrem ausgewählten Bezahlprovider weitergeleitet, nach Bezahlung werden sie automatisch zu unserem Portal zurückgeleitet.</p>
|
||||||
<button class="btn btn-secondary w-full mt-4" disabled
|
<button class="btn btn-secondary w-full mt-4"
|
||||||
>Bestellung Bestätigen</button
|
>Bestellung Bestätigen</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
Bezahlmethoden,
|
Bezahlmethoden,
|
||||||
} from "@ibcornelsen/database/client";
|
} from "@ibcornelsen/database/client";
|
||||||
import { Enums } from "@ibcornelsen/database/client";
|
import { Enums } from "@ibcornelsen/database/client";
|
||||||
|
import { dialogs } from "svelte-dialogs";
|
||||||
|
import LoginDialog from "#components/LoginDialog.svelte";
|
||||||
|
|
||||||
export let user: BenutzerClient;
|
export let user: BenutzerClient;
|
||||||
export let ausweis: VerbrauchsausweisWohnenClient;
|
export let ausweis: VerbrauchsausweisWohnenClient;
|
||||||
@@ -40,8 +42,14 @@
|
|||||||
|
|
||||||
import { PRICES } from "#lib/constants";
|
import { PRICES } from "#lib/constants";
|
||||||
import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { validateAccessTokenClient } from "src/client/lib/validateAccessToken";
|
||||||
|
import { client } from "src/trpc";
|
||||||
|
|
||||||
const prices = PRICES[ausweis.ausweisart];
|
let prices: number[] = []
|
||||||
|
|
||||||
|
if (ausweis.gebaeude_aufnahme_allgemein.ausweisart) {
|
||||||
|
prices = PRICES[ausweis.gebaeude_aufnahme_allgemein.ausweisart]
|
||||||
|
}
|
||||||
|
|
||||||
let basePrice: number = prices[0];
|
let basePrice: number = prices[0];
|
||||||
|
|
||||||
@@ -52,12 +60,29 @@
|
|||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
function speichern(e: SubmitEvent) {
|
async function speichern(e: SubmitEvent) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
console.log("Speichern");
|
|
||||||
|
// Um einen Ausweis zu speichern müssen wir eingeloggt sein, andernfalls wird die API den call ablehnen.
|
||||||
|
// Wir prüfen also ob wir eingeloggt sind und leiten den Nutzer ggf. auf die Login Seite weiter.
|
||||||
|
if (!(await validateAccessTokenClient())) {
|
||||||
|
// TOOD: Auf Dialog umstellen.
|
||||||
|
const loggedIn = await dialogs.modal(LoginDialog);
|
||||||
|
|
||||||
|
if (!loggedIn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Falls der Ausweis noch keine benutzer_id hat müssen wir ihn claimen, damit er dem jetzigen Nutzer zugewiesen wird...
|
||||||
|
await client.v1.verbrauchsausweisWohnen.claim.mutate({
|
||||||
|
uid: ausweis.uid
|
||||||
|
})
|
||||||
|
|
||||||
window.location.href = `/kaufabschluss?uid=${ausweis.uid}`;
|
window.location.href = `/kaufabschluss?uid=${ausweis.uid}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full px-8">
|
<div class="w-full px-8">
|
||||||
|
|||||||
16
src/pages/UMBE_test.astro
Normal file
16
src/pages/UMBE_test.astro
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
import Layout from "#layouts/UMBE_Layout.astro";
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Energieausweis online erstellen - Online Energieausweis">
|
||||||
|
<h1>HALLO</h1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createCaller } from "#lib/caller";
|
import { createCaller } from "#lib/caller";
|
||||||
import { APIRoute } from "astro";
|
import { APIRoute } from "astro";
|
||||||
|
import { validate } from "uuid";
|
||||||
|
|
||||||
export const get: APIRoute = async ({params, cookies}) => {
|
export const get: APIRoute = async ({params, cookies}) => {
|
||||||
const { uid } = params;
|
const { uid } = params;
|
||||||
@@ -8,6 +9,10 @@ export const get: APIRoute = async ({params, cookies}) => {
|
|||||||
return new Response("No uid provided", { status: 400 });
|
return new Response("No uid provided", { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!validate(uid)) {
|
||||||
|
return new Response("Invalid uid", { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
const caller = createCaller({ cookies })
|
const caller = createCaller({ cookies })
|
||||||
|
|
||||||
const image = await caller.v1.bilder.getBase64({ uid })
|
const image = await caller.v1.bilder.getBase64({ uid })
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ if (!accessTokenValid) {
|
|||||||
const caller = createCaller(Astro);
|
const caller = createCaller(Astro);
|
||||||
|
|
||||||
const ausweise = await caller.v1.verbrauchsausweisWohnen.getMany({
|
const ausweise = await caller.v1.verbrauchsausweisWohnen.getMany({
|
||||||
limit: 25
|
limit: 25,
|
||||||
});
|
});
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
---
|
---
|
||||||
|
import { createCaller } from "#lib/caller";
|
||||||
import UserLayout from "../../../layouts/UserLayout.astro";
|
import UserLayout from "../../../layouts/UserLayout.astro";
|
||||||
import DashboardPDFViewerModule from "../../../modules/Dashboard/DashboardPDFViewerModule.svelte";
|
import DashboardPDFViewerModule from "../../../modules/Dashboard/DashboardPDFViewerModule.svelte";
|
||||||
import { prisma } from "@ibcornelsen/database/server";
|
import { prisma } from "@ibcornelsen/database/server";
|
||||||
|
|
||||||
const ausweise = await prisma.verbrauchsausweisWohnen.findMany({
|
const caller = createCaller(Astro);
|
||||||
take: 10,
|
|
||||||
include: {
|
const ausweise = await caller.v1.verbrauchsausweisWohnen.getMany({
|
||||||
benutzer: true,
|
limit: 10
|
||||||
gebaeude_stammdaten: true,
|
});
|
||||||
rechnungen: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<UserLayout title="PDF Viewer">
|
<UserLayout title="PDF Viewer">
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
---
|
---
|
||||||
import UserLayout from "../../../layouts/UserLayout.astro";
|
import UserLayout from "../../../layouts/UserLayout.astro";
|
||||||
import { API_UID_COOKIE_NAME } from "../../../lib/constants";
|
|
||||||
import DashboardAusweiseModule from "#modules/Dashboard/DashboardAusweiseModule.svelte";
|
import DashboardAusweiseModule from "#modules/Dashboard/DashboardAusweiseModule.svelte";
|
||||||
import { prisma } from "@ibcornelsen/database/server";
|
|
||||||
|
|
||||||
const uid = Astro.cookies.get(API_UID_COOKIE_NAME).value
|
import { validateAccessTokenServer } from "src/server/lib/validateAccessToken";
|
||||||
|
import { createCaller } from "#lib/caller";
|
||||||
|
|
||||||
if (!uid) {
|
const accessTokenValid = await validateAccessTokenServer(Astro);
|
||||||
|
|
||||||
|
if (!accessTokenValid) {
|
||||||
return Astro.redirect("/auth/login")
|
return Astro.redirect("/auth/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await prisma.benutzer.findUnique({
|
const caller = createCaller(Astro);
|
||||||
where: {
|
|
||||||
uid
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!user) {
|
const user = await caller.v1.benutzer.self();
|
||||||
return Astro.redirect("/auth/login")
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<UserLayout title="Dashboard">
|
<UserLayout title="Dashboard">
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
---
|
---
|
||||||
|
import { createCaller } from "#lib/caller";
|
||||||
import UserLayout from "../../layouts/UserLayout.astro";
|
import UserLayout from "../../layouts/UserLayout.astro";
|
||||||
import { validateAccessTokenServer } from "src/server/lib/validateAccessToken";
|
import { validateAccessTokenServer } from "src/server/lib/validateAccessToken";
|
||||||
|
import DashboardModule from "#modules/Dashboard/DashboardModule.svelte";
|
||||||
|
|
||||||
const accessTokenValid = await validateAccessTokenServer(Astro);
|
const accessTokenValid = await validateAccessTokenServer(Astro);
|
||||||
|
|
||||||
if (!accessTokenValid) {
|
if (!accessTokenValid) {
|
||||||
return Astro.redirect("/auth/login")
|
return Astro.redirect("/auth/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const caller = createCaller(Astro);
|
||||||
|
|
||||||
|
const user = await caller.v1.benutzer.self();
|
||||||
|
const gebaeudeArray = await caller.v1.gebaeude.getMany({ limit: 5 });
|
||||||
---
|
---
|
||||||
|
|
||||||
<UserLayout title="Dashboard">
|
<UserLayout title="Dashboard">
|
||||||
|
<DashboardModule user={user} gebaeudeArray={gebaeudeArray} />
|
||||||
</UserLayout>
|
</UserLayout>
|
||||||
31
src/pages/email.astro
Normal file
31
src/pages/email.astro
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
import ThemeController from "../components/ThemeController.svelte";
|
||||||
|
import moment from "moment"
|
||||||
|
|
||||||
|
const lightTheme = Astro.cookies.get("theme").value === "light";
|
||||||
|
---
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>email</title>
|
||||||
|
</head>
|
||||||
|
<body class="p-8">
|
||||||
|
<main class="prose border rounded-box flex flex-col items-center border-base-300">
|
||||||
|
<div class="bg-base-200 h-auto w-full flex flex-col items-center gap-4 justify-start py-4 border-b border-base-300 rounded-t-box">
|
||||||
|
<img src="/images/header/logo-big.svg" class="h-12 my-0">
|
||||||
|
</div>
|
||||||
|
<div class="bg-base-100 h-auto w-full flex flex-col items-center gap-4 justify-start py-16 px-8">
|
||||||
|
<h2 class="my-0">Erinnerung vom IBCornelsen</h2>
|
||||||
|
<p class="text-center">Bitte denken sie daran, die restlichen Bilder für ihr Gebäude hochzuladen. Die aktuelle Gesetzgebung erfordert dies, bevor ihr Ausweis ausgestellt werden kann.</p>
|
||||||
|
<a class="btn btn-primary text-primary-content no-underline">Bilder Hochladen</a>
|
||||||
|
</div>
|
||||||
|
<div class="bg-base-200 h-auto w-full flex flex-col items-center gap-4 justify-start py-4 border-t border-base-300 rounded-b-box">
|
||||||
|
<a class="text-base-content font-medium text-sm" href="https://online-energieausweis.org">© {moment().format("YYYY")} IB Cornelsen Hamburg</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<ThemeController lightTheme={lightTheme}></ThemeController>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
import AusweisLayout from "#layouts/AusweisLayout.astro";
|
||||||
import VerbrauchsausweisWohnenModule from "#modules/Ausweise/VerbrauchsausweisWohnenModule.svelte";
|
import VerbrauchsausweisWohnenModule from "#modules/Ausweise/VerbrauchsausweisWohnenModule.svelte";
|
||||||
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
import { createCaller } from "#lib/caller";
|
import { createCaller } from "#lib/caller";
|
||||||
|
|
||||||
const uid = Astro.url.searchParams.get("uid");
|
const uid = Astro.url.searchParams.get("uid");
|
||||||
let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient;
|
let ausweis: VerbrauchsausweisWohnenClient = {
|
||||||
|
gebaeude_aufnahme_allgemein: { gebaeude_stammdaten: {} },
|
||||||
|
} as VerbrauchsausweisWohnenClient;
|
||||||
|
|
||||||
const caller = createCaller(Astro);
|
const caller = createCaller(Astro);
|
||||||
|
|
||||||
if (uid) {
|
if (uid) {
|
||||||
ausweis = await caller.v1.verbrauchsausweisWohnen.get({
|
ausweis = await caller.v1.verbrauchsausweisWohnen.get({
|
||||||
uid: uid
|
uid: uid,
|
||||||
})
|
});
|
||||||
|
|
||||||
if (!ausweis) {
|
if (!ausweis) {
|
||||||
// Der Ausweis scheint nicht zu existieren.
|
// Der Ausweis scheint nicht zu existieren.
|
||||||
// Wir leiten auf die generische Ausweisseite ohne UID weiter.
|
// Wir leiten auf die generische Ausweisseite ohne UID weiter.
|
||||||
return Astro.redirect("/energieausweis-erstellen/verbrauchsausweis-wohnen");
|
return Astro.redirect(
|
||||||
|
"/energieausweis-erstellen/verbrauchsausweis-wohnen"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const ausweis = await caller.v1.verbrauchsausweisWohnen.get({
|
|||||||
const user = await caller.v1.benutzer.self();
|
const user = await caller.v1.benutzer.self();
|
||||||
|
|
||||||
|
|
||||||
if (!ausweis || !user) {
|
if (!ausweis) {
|
||||||
return Astro.redirect("/404");
|
return Astro.redirect("/404");
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
---
|
---
|
||||||
import { generate } from "@pdfme/generator";
|
import { generate } from "@pdfme/generator";
|
||||||
import VerbrauchsausweisWohnen2016Template from "../../data/templates/verbrauchsausweis-wohnen-2016.json";
|
import VerbrauchsausweisWohnen2016Template from "../../lib/pdf/templates/GEG24_Verbrauchsausweis.json";
|
||||||
import { convertAusweisData } from "#lib/AusweisData";
|
import { convertAusweisData } from "#lib/AusweisData";
|
||||||
import { variable } from "#lib/pdf/plugins/variables";
|
import { variable } from "#lib/pdf/plugins/variables";
|
||||||
import { text, image } from "@pdfme/schemas"
|
import { text, image } from "@pdfme/schemas";
|
||||||
import { createCaller } from "#lib/caller";
|
import { createCaller } from "#lib/caller";
|
||||||
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
||||||
|
import { Schema, Template } from "@pdfme/common";
|
||||||
|
import { Moment } from "moment";
|
||||||
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||||
|
import moment from "moment";
|
||||||
|
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen";
|
||||||
|
|
||||||
const base64 = Astro.url.searchParams.get("base64");
|
const base64 = Astro.url.searchParams.get("base64");
|
||||||
let ausweis: VerbrauchsausweisWohnenClient | null = null;
|
let ausweis: VerbrauchsausweisWohnenClient | null = null;
|
||||||
@@ -23,24 +28,208 @@ if (base64) {
|
|||||||
const caller = createCaller(Astro);
|
const caller = createCaller(Astro);
|
||||||
|
|
||||||
ausweis = await caller.v1.verbrauchsausweisWohnen.get({
|
ausweis = await caller.v1.verbrauchsausweisWohnen.get({
|
||||||
uid: uidAusweis
|
uid: uidAusweis,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ausweis) {
|
const template = VerbrauchsausweisWohnen2016Template as Template;
|
||||||
return Astro.redirect("/404");
|
|
||||||
|
const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis);
|
||||||
|
|
||||||
|
let inputs: Record<string, string> = {};
|
||||||
|
|
||||||
|
// Verbrauchszeiträume
|
||||||
|
const addVerbrauchszeitraum = (() => {
|
||||||
|
let row = 0;
|
||||||
|
let columnWidth = [16, 16, 80, 12, 18, 18, 18, 12];
|
||||||
|
|
||||||
|
const getPosition = (column: number) => {
|
||||||
|
return {
|
||||||
|
position: {
|
||||||
|
x:
|
||||||
|
15 +
|
||||||
|
columnWidth.reduce(
|
||||||
|
(a, c, i) => (i >= column ? a : a + c),
|
||||||
|
0
|
||||||
|
),
|
||||||
|
y: 141 + row * 5,
|
||||||
|
},
|
||||||
|
height: 5,
|
||||||
|
width: 14,
|
||||||
|
type: "text",
|
||||||
|
fontSize: 8,
|
||||||
|
verticalAlign: "middle",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
schema: Schema,
|
||||||
|
start: Moment,
|
||||||
|
end: Moment,
|
||||||
|
energietraeger: string,
|
||||||
|
primaerenergiefaktor: number,
|
||||||
|
energieverbrauch: number,
|
||||||
|
anteilWarmwasser: number,
|
||||||
|
klimafaktor: number
|
||||||
|
) => {
|
||||||
|
inputs[`verbrauchszeitraum_${row}_start`] = start.format("MM.YYYY");
|
||||||
|
inputs[`verbrauchszeitraum_${row}_end`] = end.format("MM.YYYY");
|
||||||
|
inputs[`verbrauchszeitraum_${row}_energietraeger`] = energietraeger;
|
||||||
|
inputs[`verbrauchszeitraum_${row}_primaerenergiefaktor`] =
|
||||||
|
primaerenergiefaktor.toString();
|
||||||
|
inputs[`verbrauchszeitraum_${row}_energieverbrauch`] =
|
||||||
|
energieverbrauch.toString();
|
||||||
|
inputs[`verbrauchszeitraum_${row}_anteil_warmwasser`] = Math.round(
|
||||||
|
anteilWarmwasser * energieverbrauch
|
||||||
|
).toString();
|
||||||
|
inputs[`verbrauchszeitraum_${row}_anteil_heizung`] = Math.round(
|
||||||
|
(1 - anteilWarmwasser) *
|
||||||
|
energieverbrauch
|
||||||
|
).toString();
|
||||||
|
inputs[`verbrauchszeitraum_${row}_klimafaktor`] =
|
||||||
|
klimafaktor.toString();
|
||||||
|
|
||||||
|
schema[`verbrauchszeitraum_${row}_start`] = getPosition(0);
|
||||||
|
schema[`verbrauchszeitraum_${row}_end`] = getPosition(1);
|
||||||
|
schema[`verbrauchszeitraum_${row}_energietraeger`] = getPosition(2);
|
||||||
|
schema[`verbrauchszeitraum_${row}_primaerenergiefaktor`] =
|
||||||
|
getPosition(3);
|
||||||
|
schema[`verbrauchszeitraum_${row}_energieverbrauch`] = getPosition(4);
|
||||||
|
schema[`verbrauchszeitraum_${row}_anteil_warmwasser`] = getPosition(5);
|
||||||
|
schema[`verbrauchszeitraum_${row}_anteil_heizung`] = getPosition(6);
|
||||||
|
schema[`verbrauchszeitraum_${row}_klimafaktor`] = getPosition(7);
|
||||||
|
|
||||||
|
row++;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
addVerbrauchszeitraum(
|
||||||
|
template.schemas[2],
|
||||||
|
moment(ausweis.startdatum),
|
||||||
|
moment(ausweis.startdatum).add("1", "year"),
|
||||||
|
ausweis.gebaeude_aufnahme_allgemein?.brennstoff_1,
|
||||||
|
berechnungen?.primaerfaktorww,
|
||||||
|
berechnungen?.verbrauch_1_kwh,
|
||||||
|
ausweis.anteil_warmwasser_1 / 100,
|
||||||
|
berechnungen?.klimafaktoren[0].klimafaktor
|
||||||
|
);
|
||||||
|
|
||||||
|
addVerbrauchszeitraum(
|
||||||
|
template.schemas[2],
|
||||||
|
moment(ausweis.startdatum).add("1", "year"),
|
||||||
|
moment(ausweis.startdatum).add("2", "years"),
|
||||||
|
ausweis.gebaeude_aufnahme_allgemein?.brennstoff_1,
|
||||||
|
berechnungen?.primaerfaktorww,
|
||||||
|
berechnungen?.verbrauch_2_kwh,
|
||||||
|
ausweis.anteil_warmwasser_1 / 100,
|
||||||
|
berechnungen?.klimafaktoren[1].klimafaktor
|
||||||
|
);
|
||||||
|
|
||||||
|
addVerbrauchszeitraum(
|
||||||
|
template.schemas[2],
|
||||||
|
moment(ausweis.startdatum).add("2", "years"),
|
||||||
|
moment(ausweis.startdatum).add("3", "years"),
|
||||||
|
ausweis.gebaeude_aufnahme_allgemein?.brennstoff_1,
|
||||||
|
berechnungen?.primaerfaktorww,
|
||||||
|
berechnungen?.verbrauch_3_kwh,
|
||||||
|
ausweis.anteil_warmwasser_1 / 100,
|
||||||
|
berechnungen?.klimafaktoren[2].klimafaktor
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ausweis.zusaetzliche_heizquelle) {
|
||||||
|
addVerbrauchszeitraum(
|
||||||
|
template.schemas[2],
|
||||||
|
moment(ausweis.startdatum),
|
||||||
|
moment(ausweis.startdatum).add("1", "year"),
|
||||||
|
ausweis.gebaeude_aufnahme_allgemein?.brennstoff_2,
|
||||||
|
berechnungen?.primaerfaktorww_1,
|
||||||
|
berechnungen?.verbrauch_4_kwh,
|
||||||
|
ausweis.anteil_warmwasser_2 / 100,
|
||||||
|
berechnungen?.klimafaktoren[0].klimafaktor
|
||||||
|
);
|
||||||
|
|
||||||
|
addVerbrauchszeitraum(
|
||||||
|
template.schemas[2],
|
||||||
|
moment(ausweis.startdatum).add("1", "year"),
|
||||||
|
moment(ausweis.startdatum).add("2", "years"),
|
||||||
|
ausweis.gebaeude_aufnahme_allgemein?.brennstoff_2,
|
||||||
|
berechnungen?.primaerfaktorww_1,
|
||||||
|
berechnungen?.verbrauch_5_kwh,
|
||||||
|
ausweis.anteil_warmwasser_2 / 100,
|
||||||
|
berechnungen?.klimafaktoren[1].klimafaktor
|
||||||
|
);
|
||||||
|
|
||||||
|
addVerbrauchszeitraum(
|
||||||
|
template.schemas[2],
|
||||||
|
moment(ausweis.startdatum).add("2", "years"),
|
||||||
|
moment(ausweis.startdatum).add("3", "years"),
|
||||||
|
ausweis.gebaeude_aufnahme_allgemein?.brennstoff_2,
|
||||||
|
berechnungen?.primaerfaktorww_1,
|
||||||
|
berechnungen?.verbrauch_6_kwh,
|
||||||
|
ausweis.anteil_warmwasser_2 / 100,
|
||||||
|
berechnungen?.klimafaktoren[1].klimafaktor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertedInputs = { ...convertAusweisData(ausweis), ...inputs };
|
||||||
|
const empfehlungen = getEmpfehlungen(ausweis);
|
||||||
|
|
||||||
|
const addEmpfehlung = (() => {
|
||||||
|
let i = 0;
|
||||||
|
let columnWidth = [9, 25, 81, 13, 10, 17, 31];
|
||||||
|
|
||||||
|
const getPosition = (column: number) => {
|
||||||
|
return {
|
||||||
|
position: {
|
||||||
|
x:
|
||||||
|
13 +
|
||||||
|
columnWidth.reduce(
|
||||||
|
(a, c, i) => (i >= column ? a : a + c),
|
||||||
|
0
|
||||||
|
),
|
||||||
|
y: 94 + i * 15,
|
||||||
|
},
|
||||||
|
height: 15,
|
||||||
|
width: columnWidth[column],
|
||||||
|
type: "text",
|
||||||
|
fontSize: 8,
|
||||||
|
verticalAlign: "middle",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (empfehlung: ReturnType<typeof getEmpfehlungen>[0]) => {
|
||||||
|
template.schemas[3][`empfehlung_${i}_nr`] = getPosition(0)
|
||||||
|
template.schemas[3][`empfehlung_${i}_bauteil`] = getPosition(1)
|
||||||
|
template.schemas[3][`empfehlung_${i}_beschreibung`] = getPosition(2)
|
||||||
|
template.schemas[3][`empfehlung_${i}_amortisationszeit`] = getPosition(5)
|
||||||
|
template.schemas[3][`empfehlung_${i}_kosten`] = getPosition(6)
|
||||||
|
|
||||||
|
convertedInputs[`empfehlung_${i}_nr`] = (i + 1).toString();
|
||||||
|
convertedInputs[`empfehlung_${i}_bauteil`] = empfehlung.anlagenteil;
|
||||||
|
convertedInputs[`empfehlung_${i}_beschreibung`] = empfehlung.description;
|
||||||
|
convertedInputs[`empfehlung_${i}_amortisationszeit`] = "";
|
||||||
|
convertedInputs[`empfehlung_${i}_kosten`] = "";
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
|
||||||
|
for (const empfehlung of empfehlungen) {
|
||||||
|
addEmpfehlung(empfehlung);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pdf = await generate({
|
const pdf = await generate({
|
||||||
template: VerbrauchsausweisWohnen2016Template,
|
template,
|
||||||
plugins: { text, image, variable },
|
plugins: { text, image, variable: { ...variable, pdf: variable.pdf.bind(convertedInputs), ui: variable.ui.bind(convertedInputs) } },
|
||||||
inputs: [convertAusweisData(ausweis)],
|
inputs: [convertedInputs],
|
||||||
options: {
|
options: {
|
||||||
author: "IB Cornelsen",
|
author: "IB Cornelsen",
|
||||||
creationDate: new Date(),
|
creationDate: new Date(),
|
||||||
creator: "IB Cornelsen",
|
creator: "IB Cornelsen",
|
||||||
language: "de",
|
language: "de",
|
||||||
title: "Verbrauchsausweis Wohnen 2016",
|
title: "Verbrauchsausweis Wohnen GEG 2024",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
48
src/style/UMBE_global.css
Normal file
48
src/style/UMBE_global.css
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Abel&display=swap');
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,400&display=swap");
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-weight: 400;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: "Abel", "Poppins", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
article hr {
|
||||||
|
@apply mb-4 mt-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
@apply px-6 md:px-8 py-6 w-full relative bg-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
article h1 {
|
||||||
|
@apply text-4xl font-normal my-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
article h2 {
|
||||||
|
@apply text-2xl font-normal my-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
article h3 {
|
||||||
|
@apply text-xl font-normal my-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
article a {
|
||||||
|
@apply text-blue-700 font-medium text-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
article select {
|
||||||
|
@apply rounded-lg px-2 py-1.5 outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
@apply h-5 w-4 checkbox-secondary;
|
||||||
|
}
|
||||||
28
tests/verbrauchsausweis-wohnen/energieverbrauch.test.ts
Normal file
28
tests/verbrauchsausweis-wohnen/energieverbrauch.test.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { test, describe, expect } from "bun:test";
|
||||||
|
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016";
|
||||||
|
import { importVerbrauchsausweisWohnenAltesSystem, verbrauchsausweisWohnenImportTranslate } from "#lib/altes-system/import";
|
||||||
|
|
||||||
|
describe('Energieverbrauch', async () => {
|
||||||
|
const alteAusweise = await importVerbrauchsausweisWohnenAltesSystem();
|
||||||
|
const ausweis = verbrauchsausweisWohnenImportTranslate(alteAusweise.data[0]);
|
||||||
|
const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis);
|
||||||
|
const berechnungenAlt = alteAusweise.data[0].calculations;
|
||||||
|
|
||||||
|
|
||||||
|
test("Klimafaktoren", async () => {
|
||||||
|
console.log("PLZ: " + ausweis.gebaeude_aufnahme_allgemein.plz)
|
||||||
|
|
||||||
|
expect(berechnungen?.klimafaktoren).toHaveLength(3)
|
||||||
|
expect(berechnungen?.klimafaktoren.map(x => x.klimafaktor)).toEqual(berechnungenAlt.klimafaktoren)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
test("Endenergieverbrauch", async () => {
|
||||||
|
expect(berechnungen?.endEnergieVerbrauchGesamt).toBeCloseTo(berechnungenAlt.endEnergieVerbrauchGesamt, 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Primärenergieverbrauch", async () => {
|
||||||
|
|
||||||
|
expect(berechnungen?.primaerEnergieVerbrauchGesamt).toBeCloseTo(berechnungenAlt.primaerEnergieVerbrauchGesamt, 0)
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user