23 Commits

Author SHA1 Message Date
Moritz Utcke
3cb71b8e2c Revert "Revert "Bugfixes"" 2025-04-09 20:13:52 -04:00
Moritz Utcke
eb8bae6d69 Merge pull request #507 from IBCornelsen/revert-506-dev
Revert "Bugfixes"
2025-04-09 19:25:36 -04:00
Moritz Utcke
4f382c150d Revert "Bugfixes" 2025-04-09 19:25:21 -04:00
Moritz Utcke
53ea51885a Merge pull request #506 from IBCornelsen/dev
Bugfixes
2025-04-09 19:11:44 -04:00
Moritz Utcke
f5ae2cd0d4 Mollie 2025-04-09 13:54:39 -04:00
Moritz Utcke
8860750487 Mollie 2025-04-09 13:25:06 -04:00
Moritz Utcke
a58c8d466e Verbrauchsausweis Gewerbe 2025-04-09 13:10:11 -04:00
Moritz Utcke
8daee69576 Bugfixes 2025-04-09 11:46:27 -04:00
Moritz Utcke
7665141a5a Formular Button 2025-04-09 09:18:11 -04:00
Moritz Utcke
7327d39c57 Ausweis ID im Ausweis 2025-04-09 09:06:43 -04:00
Moritz Utcke
9177ca18f0 Merge pull request #505 from IBCornelsen/dev
Updates und Verbesserungen
2025-04-08 19:59:34 -04:00
Moritz Utcke
0956744878 Ausstellen 2025-04-08 19:34:51 -04:00
Moritz Utcke
b0235056a7 Adresse 2025-04-08 18:50:27 -04:00
Moritz Utcke
d354189d3c Ausweis, Ausstellung, Adresse 2025-04-08 18:49:29 -04:00
Moritz Utcke
07760aa26a Bugfix Process not defined 2025-04-08 15:13:17 -04:00
Moritz Utcke
13322836aa Recover DB 2025-04-08 13:53:32 -04:00
Moritz Utcke
d8acd0476a Actions 2025-04-08 13:06:42 -04:00
Moritz Utcke
a2e0d50b1f Update .gitignore 2025-04-08 10:23:14 -04:00
Moritz Utcke
176f1c08ad Klimafaktoren 2025-04-07 23:55:42 -04:00
Moritz Utcke
1970a105a9 Webhook 2025-04-07 21:41:27 -04:00
Moritz Utcke
71438a39eb Ausstellen 2025-04-07 21:31:47 -04:00
Moritz Utcke
ba7792a4b9 Ausstellen 2025-04-07 21:27:38 -04:00
Moritz Utcke
145bf46ee1 Partner Code 2025-04-07 20:36:47 -04:00
83 changed files with 1476 additions and 877 deletions

View File

@@ -1,10 +1,10 @@
name: Dev Pipeline name: Development Pipeline
on: on:
pull_request: pull_request:
branches: [main] branches: [dev]
push: push:
branches: [main] branches: [dev]
jobs: jobs:
deploy: deploy:
@@ -26,8 +26,8 @@ jobs:
export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH
echo $PATH echo $PATH
cd ~/online-energieausweis cd ~/online-energieausweis
git reset --hard origin/main git reset --hard origin/dev
git clean -f -d git clean -f -d
git pull origin main git pull origin dev
git status git status
make prod make prod

33
.github/workflows/prod-pipeline.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Production Pipeline
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Bun
run: |
curl -fsSL https://bun.sh/install | bash
- uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.PROD_USERNAME }}
password: ${{ secrets.PROD_PASSWORD }}
port: 22
script: |
export PATH=$HOME/.bun/bin:$PATH
export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH
echo $PATH
cd ~/online-energieausweis
git reset --hard origin/main
git clean -f -d
git pull origin main
git status
make prod

2
.gitignore vendored
View File

@@ -34,7 +34,7 @@ dbml/schema.dbml
prisma/migrations/20250315143314_/migration.sql prisma/migrations/20250315143314_/migration.sql
src/astro-typesafe-api-caller.ts # src/astro-typesafe-api-caller.ts
src/testing/ausweise.csv src/testing/ausweise.csv
src/testing/users.csv src/testing/users.csv

View File

@@ -2,20 +2,27 @@
FILE_NAME=data-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br FILE_NAME=data-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br
FILE_NAME_COMPLETE=full-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br FILE_NAME_COMPLETE=full-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br
# Wir exportieren die Datenbank und komprimieren sie.
docker exec -t online-energieausweis-database-1 pg_dump --data-only -U main main | brotli --best > $FILE_NAME
docker exec -t online-energieausweis-database-1 pg_dumpall -c -U main | brotli --best > $FILE_NAME_COMPLETE
# Das wird benötigt für AWS Ionos Kompatibilität. # Das wird benötigt für AWS Ionos Kompatibilität.
export AWS_REQUEST_CHECKSUM_CALCULATION=when_required export AWS_REQUEST_CHECKSUM_CALCULATION=when_required
export AWS_RESPONSE_CHECKSUM_VALIDATION=when_required export AWS_RESPONSE_CHECKSUM_VALIDATION=when_required
# Wir exportieren die Datenbank und komprimieren sie.
# IMPORTANT: Dieser Befehl benötigt das `ionos` Profil, sonst wird er nicht funktionieren. # IMPORTANT: Dieser Befehl benötigt das `ionos` Profil, sonst wird er nicht funktionieren.
# Das Profil kann mit `aws configure --profile ionos` erstellt werden. # Das Profil kann mit `aws configure --profile ionos` erstellt werden.
# Den Key dafür findet man auf https://dcd.ionos.com/latest/?lang=en#/key-management # Den Key dafür findet man auf https://dcd.ionos.com/latest/?lang=en#/key-management
docker exec -t online-energieausweis-database-1 pg_dump --data-only -U main main | brotli --best > $FILE_NAME
aws s3 cp $FILE_NAME s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD aws s3 cp $FILE_NAME s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD
echo "Uploaded $FILE_NAME"
docker exec -t online-energieausweis-database-1 pg_dumpall -c -U main | brotli --best > $FILE_NAME_COMPLETE
aws s3 cp $FILE_NAME_COMPLETE s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD aws s3 cp $FILE_NAME_COMPLETE s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD
echo "Uploaded $FILE_NAME_COMPLETE"
# Wir entfernen das Backup # Wir entfernen das Backup
rm $FILE_NAME rm $FILE_NAME
rm $FILE_NAME_COMPLETE rm $FILE_NAME_COMPLETE

View File

@@ -96,7 +96,7 @@
"postcss-import": "^16.1.0", "postcss-import": "^16.1.0",
"postcss-nesting": "^13.0.1", "postcss-nesting": "^13.0.1",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"prisma": "^6.4.1", "prisma": "6.4.1",
"prisma-dbml-generator": "^0.12.0", "prisma-dbml-generator": "^0.12.0",
"prisma-generator-fake-data": "^0.14.3", "prisma-generator-fake-data": "^0.14.3",
"tsx": "^4.19.3", "tsx": "^4.19.3",

View File

@@ -0,0 +1,17 @@
-- AlterTable
ALTER TABLE "BedarfsausweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'BedarfsausweisGewerbe';
-- AlterTable
ALTER TABLE "BedarfsausweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'BedarfsausweisWohnen';
-- AlterTable
ALTER TABLE "GEGNachweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'GEGNachweisGewerbe';
-- AlterTable
ALTER TABLE "GEGNachweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'GEGNachweisWohnen';
-- AlterTable
ALTER TABLE "VerbrauchsausweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'VerbrauchsausweisGewerbe';
-- AlterTable
ALTER TABLE "VerbrauchsausweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'VerbrauchsausweisWohnen';

View File

@@ -26,6 +26,7 @@ model BedarfsausweisGewerbe {
klimatisierung Boolean? @default(false) klimatisierung Boolean? @default(false)
nachweistyp AusweisTyp @default(Standard) nachweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(BedarfsausweisGewerbe)
created_at DateTime @default(now()) created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now()) updated_at DateTime @updatedAt @default(now())

View File

@@ -100,6 +100,7 @@ model BedarfsausweisWohnen {
pruefpunkt_fenster Boolean? @default(false) pruefpunkt_fenster Boolean? @default(false)
ausweistyp AusweisTyp @default(Standard) ausweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(BedarfsausweisWohnen)
benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction) benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction)

View File

@@ -17,6 +17,7 @@ model GEGNachweisGewerbe {
beschreibung String? @db.Text beschreibung String? @db.Text
nachweistyp AusweisTyp @default(Standard) nachweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(GEGNachweisGewerbe)
created_at DateTime @default(now()) created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now()) updated_at DateTime @updatedAt @default(now())

View File

@@ -17,6 +17,7 @@ model GEGNachweisWohnen {
beschreibung String? @db.Text beschreibung String? @db.Text
nachweistyp AusweisTyp @default(Standard) nachweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(GEGNachweisWohnen)
created_at DateTime @default(now()) created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now()) updated_at DateTime @updatedAt @default(now())

View File

@@ -74,6 +74,7 @@ model VerbrauchsausweisGewerbe {
updated_at DateTime @updatedAt @default(now()) updated_at DateTime @updatedAt @default(now())
ausweistyp AusweisTyp @default(Standard) ausweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(VerbrauchsausweisGewerbe)
pruefpunkt_heizungsalter Boolean? @default(false) pruefpunkt_heizungsalter Boolean? @default(false)
pruefpunkt_verbrauch_niedrig Boolean? @default(false) pruefpunkt_verbrauch_niedrig Boolean? @default(false)

View File

@@ -75,6 +75,7 @@ model VerbrauchsausweisWohnen {
kontrolldatei_angefragt Boolean? @default(false) kontrolldatei_angefragt Boolean? @default(false)
ausweistyp AusweisTyp @default(Standard) ausweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(VerbrauchsausweisWohnen)
created_at DateTime @default(now()) created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now()) updated_at DateTime @updatedAt @default(now())

41
recover-db-dev.bash Normal file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
# === Configuration ===
BUCKET_NAME="ibc-db-backup"
ENDPOINT_URL="https://s3-eu-central-1.ionoscloud.com"
LOCAL_DOWNLOAD_DIR="./" # Where to save the file
# === Get latest file from IONOS S3 bucket ===
LATEST_FILE=$(aws s3api list-objects-v2 \
--bucket "$BUCKET_NAME" \
--prefix "data-dump" \
--endpoint-url "$ENDPOINT_URL" \
--query 'Contents | sort_by(@, &LastModified) | [-1].Key' \
--output text)
# === Check if file was found ===
if [ "$LATEST_FILE" == "None" ] || [ -z "$LATEST_FILE" ]; then
echo "❌ No matching .sql.br file found."
exit 1
fi
FILENAME=$(basename "$LATEST_FILE")
SQL_FILE="${FILENAME%.br}" # Remove .br suffix
echo "📥 Downloading $LATEST_FILE"
aws s3 cp "s3://$BUCKET_NAME/$LATEST_FILE" "$LOCAL_DOWNLOAD_DIR" \
--endpoint-url "$ENDPOINT_URL"
# === Decompress with Brotli ===
echo "🗜️ Decompressing $FILENAME -> $SQL_FILE"
brotli -d "$FILENAME"
# === Import into Postgres inside Docker ===
echo "🐘 Importing into PostgreSQL (online-energieausweis-database-1:main)"
docker exec -i "online-energieausweis-database-1" env PGPASSWORD="hHMP8cd^N3SnzGRR" \
psql -U "main" -d "main" < "$SQL_FILE"
echo "✅ Import complete."
# === Optional: Clean up
rm "$FILENAME" "$SQL_FILE"

View File

@@ -1,5 +1,4 @@
import { api } from "astro-typesafe-api/client"; import { api } from "astro-typesafe-api/client";
import { exclude } from "#lib/exclude.js";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js"; import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { import {
@@ -566,7 +565,7 @@ export async function ausweisSpeichern(
return; return;
} }
aufnahme.id = aufnahme_id; aufnahme.id = aufnahme_id as string;
if (ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen) { if (ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen) {
const id = await verbrauchsausweisWohnenSpeichern( const id = await verbrauchsausweisWohnenSpeichern(

View File

@@ -1,5 +1,4 @@
<script lang="ts"> <script lang="ts">
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte"; import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte";
import { import {
BedarfsausweisWohnenClient, BedarfsausweisWohnenClient,
@@ -9,8 +8,9 @@
VerbrauchsausweisWohnenClient, VerbrauchsausweisWohnenClient,
} from "./types.js"; } from "./types.js";
import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte"; import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte";
import { Enums } from "#lib/client/prisma"; import { Enums } from "#lib/client/prisma.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js"; import { endEnergieVerbrauchVerbrauchsausweis_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Client.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Client.js";
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
export let aufnahme: AufnahmeClient; export let aufnahme: AufnahmeClient;
@@ -21,7 +21,9 @@
[Enums.Ausweisart.VerbrauchsausweisGewerbe]: 1000, [Enums.Ausweisart.VerbrauchsausweisGewerbe]: 1000,
[Enums.Ausweisart.VerbrauchsausweisWohnen]: 250, [Enums.Ausweisart.VerbrauchsausweisWohnen]: 250,
[Enums.Ausweisart.BedarfsausweisWohnen]: 250, [Enums.Ausweisart.BedarfsausweisWohnen]: 250,
[Enums.Ausweisart.BedarfsausweisGewerbe]: 250 [Enums.Ausweisart.BedarfsausweisGewerbe]: 0,
[Enums.Ausweisart.GEGNachweisGewerbe]: 0,
[Enums.Ausweisart.GEGNachweisWohnen]: 0,
}[ausweisart]; }[ausweisart];
/** /**
@@ -64,9 +66,9 @@
(async () => { (async () => {
let result; let result;
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) { if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) {
result = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt); result = await endEnergieVerbrauchVerbrauchsausweis_2016_Client(ausweis, aufnahme, objekt);
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) { } else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
result = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt); result = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client(ausweis, aufnahme, objekt);
} }
if (!result) { if (!result) {

View File

@@ -15,7 +15,9 @@
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js"; import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { Enums, Objekt } from "#lib/client/prisma.js"; import { Enums, Objekt } from "#lib/client/prisma.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js"; import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
import { addNotification } from "#components/Notifications/shared.js"; import { addNotification, updateNotification } from "#components/Notifications/shared.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Client.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Client.js";
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
export let aufnahme: AufnahmeKomplettClient; export let aufnahme: AufnahmeKomplettClient;
@@ -86,15 +88,15 @@
let calculations = null; let calculations = null;
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) { if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
calculations = endEnergieVerbrauchVerbrauchsausweis_2016(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt); calculations = endEnergieVerbrauchVerbrauchsausweis_2016_Client(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt);
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) { } else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
calculations = endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt); calculations = endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt);
} }
async function registriernummerAnfordern() { async function registriernummer() {
try { try {
const result = await api.admin.registriernummer.GET.fetch({ const result = await api.admin.registriernummer.GET.fetch({
uid: ausweis.id id: ausweis.id
}, { }, {
headers: { headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}` "Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
@@ -141,7 +143,13 @@
} }
} }
async function ausweisAusstellen() { async function ausstellen() {
const notification = addNotification({
message: "Ausweis wird ausgestellt.",
subtext: "Der Ausweis wird nun ausgestellt, bitte habe einen Augenblick geduld..",
type: "info",
timeout: 0,
})
try { try {
await api.admin.ausstellen.GET.fetch({ await api.admin.ausstellen.GET.fetch({
id_ausweis: ausweis.id id_ausweis: ausweis.id
@@ -150,8 +158,17 @@
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}` "Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
} }
}) })
ausweis.ausgestellt = true;
updateNotification(notification, {
message: "Ausweis ausgestellt.",
subtext: "Der Ausweis wurde erfolgreich ausgestellt.",
timeout: 3000,
type: "success",
})
} catch(e) { } catch(e) {
addNotification({ updateNotification(notification, {
message: "Das hat nicht geklappt.", message: "Das hat nicht geklappt.",
subtext: e as string, subtext: e as string,
timeout: 3000, timeout: 3000,
@@ -227,7 +244,11 @@
{:else if ausweis.bestellt} {:else if ausweis.bestellt}
<span class="bg-primary px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Bestellt</span> <span class="bg-primary px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Bestellt</span>
{:else} {:else}
<span class="bg-red-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Gespeichert</span> {#if ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe || ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisGewerbe}
<span class="bg-red-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Gespeichert</span>
{:else}
<span class="bg-red-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Angefordert</span>
{/if}
{/if} {/if}
</div> </div>
<div class="badge badge-accent font-semibold text-black text-m">{objekt.adresse}</div> <div class="badge badge-accent font-semibold text-black text-m">{objekt.adresse}</div>
@@ -244,7 +265,7 @@
<p class="text-sm font-semibold">Sie haben Hilfe zu diesem Ausweis angefordert. Sie werden innerhalb der nächsten 48 Stunden über die hinterlegte Telefonnummer vom IB Cornelsen kontaktiert.</p> <p class="text-sm font-semibold">Sie haben Hilfe zu diesem Ausweis angefordert. Sie werden innerhalb der nächsten 48 Stunden über die hinterlegte Telefonnummer vom IB Cornelsen kontaktiert.</p>
{:else if ausweis.ausweistyp === Enums.AusweisTyp.Offline || ausweis.ausweistyp === Enums.AusweisTyp.OfflineXL} {:else if ausweis.ausweistyp === Enums.AusweisTyp.Offline || ausweis.ausweistyp === Enums.AusweisTyp.OfflineXL}
<p class="text-sm font-semibold">Sie haben die offline Variant zu diesem Ausweis angefordert. Bitte übermitteln Sie uns die letzten drei Jahre der Energieabrechnungen Ihres Energieversorgers.</p> <p class="text-sm font-semibold">Sie haben die offline Variant zu diesem Ausweis angefordert. Bitte übermitteln Sie uns die letzten drei Jahre der Energieabrechnungen Ihres Energieversorgers.</p>
{:else} {:else if !ausweis.ausgestellt}
<p class="text-sm font-semibold">Der Ausweis wurde von Ihnen freigegeben und befindet sich in Prüfung vom IB Cornelsen</p> <p class="text-sm font-semibold">Der Ausweis wurde von Ihnen freigegeben und befindet sich in Prüfung vom IB Cornelsen</p>
{/if} {/if}
{/if} {/if}
@@ -377,7 +398,6 @@
{/if} {/if}
{#if benutzer.rolle === Enums.BenutzerRolle.ADMIN} {#if benutzer.rolle === Enums.BenutzerRolle.ADMIN}
<!-- TODO -->
{#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen} {#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen}
<a <a
class="button text-sm" class="button text-sm"
@@ -388,13 +408,18 @@
class="button text-sm" class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?id={ausweis.id}" href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?id={ausweis.id}"
>Formular</a> >Formular</a>
{:else if ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude?id={ausweis.id}"
>Formular</a>
{/if} {/if}
{/if} {/if}
{#if benutzer.rolle === Enums.BenutzerRolle.ADMIN} {#if benutzer.rolle === Enums.BenutzerRolle.ADMIN}
<button class="button text-sm" on:click={ausweisAusstellen}>A</button> <button class="button text-sm" on:click={ausstellen}>A</button>
<button class="button text-sm" on:click={stornieren}>S</button> <button class="button text-sm" on:click={stornieren}>S</button>
<button class="button text-sm" on:click={registriernummerAnfordern}>R</button> <button class="button text-sm" on:click={registriernummer}>R</button>
{/if} {/if}
<a <a

View File

@@ -47,19 +47,6 @@
<div class="text-sm text-center">Energieausweis</div> <div class="text-sm text-center">Energieausweis</div>
</a> </a>
{/if} {/if}
{#if objekt.aufnahmen.at(-1)?.bedarfsausweise_wohnen.length}
{@const ausweis = objekt.aufnahmen.at(-1)?.bedarfsausweise_wohnen.at(-1)}
<a href="/pdf/ansichtsausweis?id={ausweis.id}" target="_blank">
<div class="inline-block border rounded-lg bg-white">
{#if ausweis?.ausgestellt}
<img src="/images/dashboard/AusweisHaken.svg" class="h-auto w-auto max-h-[150px] max-w-full object-contain p-1" alt="Energieausweis ausgestellt">
{:else}
<img src="/images/dashboard/AusweisKreuz.svg" class="h-auto w-auto max-h-[150px] max-w-full object-contain p-1" alt="Energieausweis ausgestellt">
{/if}
</div>
<div class="text-sm text-center">Energieausweis</div>
</a>
{/if}
</div> </div>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
{#each objekt.aufnahmen as aufnahme} {#each objekt.aufnahmen as aufnahme}

View File

@@ -1,113 +1,89 @@
<script lang="ts"> <script lang="ts">
import { ripple } from "svelte-ripple-action"; import {
import type { RippleOptions } from "svelte-ripple-action/dist/constants.js"; Reader,
import { Reader, Bell, Gear, LockClosed, CaretDown } from "radix-svelte-icons" Bell,
Gear,
LockClosed,
CaretDown,
} 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.js"; import { notifications } from "#components/NotificationProvider/shared.js";
import ThemeController from "#components/ThemeController.svelte"; import ThemeController from "#components/ThemeController.svelte";
import { BenutzerClient, ObjektKomplettClient } from "#components/Ausweis/types.js"; import {
BenutzerClient,
ObjektKomplettClient,
} from "#components/Ausweis/types.js";
export let lightTheme: boolean; export let lightTheme: boolean;
export let benutzer: BenutzerClient; export let benutzer: BenutzerClient;
const rippleOptions: RippleOptions = {
center: false,
color: lightTheme ? "rgba(233,233,233,0.1)" : "rgba(113, 128, 150, 0.1)",
};
let headerOpen = false;
</script> </script>
<aside class:hidden={!headerOpen} class="fixed left-0 top-16 w-full h-[calc(100%-4rem)] flex md:relative md:h-auto md:w-auto md:top-0 md:flex bg-base-200 border-r border-r-base-300 flex-col py-4"> <aside class="rounded-lg bg-white box px-6 py-5">
<div class="flex flex-row items-center">
<div class="flex flex-row items-center px-4">
<div class="flex flex-row mr-6"> <div class="flex flex-row mr-6">
<a href="/"><img src="/images/header/logo-IBC-big.svg" class="h-16" alt="IBCornelsen - Logo"/></a> <a href="/"
><img
src="/images/header/logo-IBC-big.svg"
class="h-16"
alt="IBCornelsen - Logo"
/></a
>
</div> </div>
<div class="flex-col items-end"> <div class="flex-col items-end">
<div class="text-base-content font-semibold text-left flex" <div class="text-base-content font-semibold text-left flex">
>{benutzer.vorname} {benutzer.name}</div> {benutzer.vorname}
{benutzer.name}
</div>
<div class="text-base-content text-sm flex">{benutzer.email}</div> <div class="text-base-content text-sm flex">{benutzer.email}</div>
<a href="/auth/logout" class="text-xs">Logout</a> <a href="/auth/logout" class="text-xs">Logout</a>
</div> </div>
</div> </div>
<div class="flex flex-col gap-2 mt-0 md:mt-8 px-0"> <div class="flex flex-col gap-2 mt-0 md:mt-8 px-0">
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard"> <a class="button-tab" href="/dashboard">
<Reader width={22} height={22} /> <Reader width={22} height={22} />
Vorgänge Vorgänge
</a> </a>
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard"> <a class="button-tab" href="/dashboard">
<Reader width={22} height={22} /> <Reader width={22} height={22} />
Inbox Inbox
</a> </a>
<hr class="border-gray-600"> <hr class="border-gray-600" />
<!--
<div class="text-base-content text-xl px-4 mt-4">Mitwirkende</div>
<div class="flex flex-col gap-4 px-4">
{#each [
{ name: "Max Mustermann", image: "/images/profile-placeholder.svg", profession: "Architekt" },
{ name: "Erika Musterfrau", image: "/images/profile-placeholder.svg", profession: "Ingenieurin" },
{ name: "Hans Beispiel", image: "/images/profile-placeholder.svg", profession: "Energieberater" },
{ name: "Anna Beispiel", image: "/images/profile-placeholder.svg", profession: "Bauleiterin" }
] as person}
<div class="flex items-center gap-4">
<img src={person.image} alt={person.name} class="w-12 h-12 rounded-full object-cover" />
<div class="flex flex-col">
<span class="text-base-content font-medium">{person.name}</span>
<span class="text-sm text-gray-500">{person.profession}</span>
</div>
<button class="ml-auto btn btn-primary btn-sm">Chat</button>
</div>
{/each}
</div>
-->
<!-- <button use:ripple={rippleOptions} class="button-tab">
<EnvelopeClosed width={22} height={22} />
Kontakt
</button>
<li><details class="[&_.caret]:open:rotate-180">
<summary class="button-tab w-full outline-0 hover:outline-0">
<Cube width={22} height={22} />
Services <CaretDown size={24} class="caret ml-auto transition-transform"></CaretDown></summary>
<ul>
<li>
<button use:ripple={rippleOptions} class="button-tab">
Kontakt
</button>
</li>
<li>
<button use:ripple={rippleOptions} class="button-tab">
Kontakt
</button>
</li>
</ul>
</details></li> -->
{#if benutzer.rolle === "ADMIN"} {#if benutzer.rolle === "ADMIN"}
<li><details class="[&_.caret]:open:rotate-180" open> <li>
<summary class="button-tab w-full outline-0 hover:outline-0 cursor-pointer"> <details class="[&_.caret]:open:rotate-180" open>
<LockClosed width={22} height={22} /> <summary
Admin <CaretDown size={24} class="caret ml-auto transition-transform"></CaretDown></summary> class="button-tab w-full outline-0 hover:outline-0 cursor-pointer"
<ul> >
<li> <LockClosed width={22} height={22} />
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard/admin/ausweise-pruefen"> Admin <CaretDown
Ausweise Prüfen size={24}
</a> class="caret ml-auto transition-transform"
</li> ></CaretDown></summary
<li> >
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard/admin/impersonate-user"> <ul>
Impersonate User <li>
</a> <a
</li> class="button-tab"
</ul> href="/dashboard/admin/ausweise-pruefen"
</details></li> >
Ausweise Prüfen
</a>
</li>
<li>
<a
class="button-tab"
href="/dashboard/admin/impersonate-user"
>
Impersonate User
</a>
</li>
</ul>
</details>
</li>
{/if} {/if}
</div> </div>
<div class="mt-10 flex flex-col gap-4 px-8"> <div class="mt-10 flex flex-col gap-4 px-8">
@@ -116,18 +92,26 @@
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<div class="indicator"> <div class="indicator">
{#if Object.keys($notifications).length > 0} {#if Object.keys($notifications).length > 0}
<span class="indicator-item badge badge-accent text-xs">{Object.keys($notifications).length}</span> <span class="indicator-item badge badge-accent text-xs"
>{Object.keys($notifications).length}</span
>
{/if} {/if}
<button tabindex="0" class="hover:bg-gray-200 p-3 rounded-lg"> <button
tabindex="0"
class="hover:bg-gray-200 p-3 rounded-lg"
>
<Bell size={24} /> <Bell size={24} />
</button> </button>
</div> </div>
<ul class="dropdown-content mb-2 border border-base-300 z-10 menu py-4 px-0 bg-base-200 rounded-box w-80"> <ul
class="dropdown-content mb-2 border border-base-300 z-10 menu py-4 px-0 bg-base-200 rounded-box w-80"
>
<NotificationProvider component={DashboardNotification} /> <NotificationProvider component={DashboardNotification} />
</ul> </ul>
</div> </div>
<a href="/dashboard/einstellungen" <a
href="/dashboard/einstellungen"
class="hover:bg-gray-200 p-3 rounded-lg" class="hover:bg-gray-200 p-3 rounded-lg"
> >
<Gear size={24} /> <Gear size={24} />
@@ -137,10 +121,8 @@
<div class="divider px-8"></div> <div class="divider px-8"></div>
<a <a
href="/dashboard/einstellungen" href="/dashboard/einstellungen"
use:ripple={rippleOptions}
class="hover:bg-gray-200 no-animation focus:shadow-none justify-start py-4 h-auto px-8 rounded-none w-full flex flex-row gap-4" class="hover:bg-gray-200 no-animation focus:shadow-none justify-start py-4 h-auto px-8 rounded-none w-full flex flex-row gap-4"
> >
</a> </a>
</aside> </aside>

View File

@@ -28,6 +28,12 @@ export function updateNotification(uid: string, updater: Partial<Notification>)
value[uid] = { ...defaults, ...value[uid], ...updater } as Notification; value[uid] = { ...defaults, ...value[uid], ...updater } as Notification;
return value; return value;
}) })
if (updater.timeout) {
setTimeout(() => {
deleteNotification(uid);
}, updater.timeout);
}
} }
export function addNotification(notification: Partial<Notification>): string { export function addNotification(notification: Partial<Notification>): string {

View File

@@ -1,5 +1,5 @@
import * as z from "zod" import * as z from "zod"
import { Ausstellgrund, AusweisTyp } from "@prisma/client" import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
export const BedarfsausweisGewerbeSchema = z.object({ export const BedarfsausweisGewerbeSchema = z.object({
id: z.string(), id: z.string(),
@@ -20,6 +20,7 @@ export const BedarfsausweisGewerbeSchema = z.object({
bauteilaktivierung: z.boolean().nullish(), bauteilaktivierung: z.boolean().nullish(),
klimatisierung: z.boolean().nullish(), klimatisierung: z.boolean().nullish(),
nachweistyp: z.nativeEnum(AusweisTyp), nachweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
created_at: z.date(), created_at: z.date(),
updated_at: z.date(), updated_at: z.date(),
benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(), benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(),

View File

@@ -1,5 +1,5 @@
import * as z from "zod" import * as z from "zod"
import { Ausstellgrund, AusweisTyp } from "@prisma/client" import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
export const BedarfsausweisWohnenSchema = z.object({ export const BedarfsausweisWohnenSchema = z.object({
id: z.string(), id: z.string(),
@@ -86,6 +86,7 @@ export const BedarfsausweisWohnenSchema = z.object({
pruefpunkt_geometrie: z.boolean().nullish(), pruefpunkt_geometrie: z.boolean().nullish(),
pruefpunkt_fenster: z.boolean().nullish(), pruefpunkt_fenster: z.boolean().nullish(),
ausweistyp: z.nativeEnum(AusweisTyp), ausweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
rechnung_id: z.string().nullish(), rechnung_id: z.string().nullish(),
aufnahme_id: z.string().describe("ID der korrespondierenden Gebäudeaufnahme"), aufnahme_id: z.string().describe("ID der korrespondierenden Gebäudeaufnahme"),
}) })

View File

@@ -1,5 +1,5 @@
import * as z from "zod" import * as z from "zod"
import { Ausstellgrund, AusweisTyp } from "@prisma/client" import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
export const GEGNachweisGewerbeSchema = z.object({ export const GEGNachweisGewerbeSchema = z.object({
id: z.string(), id: z.string(),
@@ -10,6 +10,7 @@ export const GEGNachweisGewerbeSchema = z.object({
zurueckgestellt: z.boolean().describe("Falls der Nachweis vom Aussteller zurückgestellt wurde, sollte dieser Wert auf true stehen").nullish(), zurueckgestellt: z.boolean().describe("Falls der Nachweis vom Aussteller zurückgestellt wurde, sollte dieser Wert auf true stehen").nullish(),
beschreibung: z.string().describe("Beschreibung des Bauvorhabens").nullish(), beschreibung: z.string().describe("Beschreibung des Bauvorhabens").nullish(),
nachweistyp: z.nativeEnum(AusweisTyp), nachweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
created_at: z.date(), created_at: z.date(),
updated_at: z.date(), updated_at: z.date(),
benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(), benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(),

View File

@@ -1,5 +1,5 @@
import * as z from "zod" import * as z from "zod"
import { Ausstellgrund, AusweisTyp } from "@prisma/client" import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
export const GEGNachweisWohnenSchema = z.object({ export const GEGNachweisWohnenSchema = z.object({
id: z.string(), id: z.string(),
@@ -10,6 +10,7 @@ export const GEGNachweisWohnenSchema = z.object({
zurueckgestellt: z.boolean().describe("Falls der Nachweis vom Aussteller zurückgestellt wurde, sollte dieser Wert auf true stehen").nullish(), zurueckgestellt: z.boolean().describe("Falls der Nachweis vom Aussteller zurückgestellt wurde, sollte dieser Wert auf true stehen").nullish(),
beschreibung: z.string().describe("Beschreibung des Bauvorhabens").nullish(), beschreibung: z.string().describe("Beschreibung des Bauvorhabens").nullish(),
nachweistyp: z.nativeEnum(AusweisTyp), nachweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
created_at: z.date(), created_at: z.date(),
updated_at: z.date(), updated_at: z.date(),
benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(), benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(),

View File

@@ -1,5 +1,5 @@
import * as z from "zod" import * as z from "zod"
import { Ausstellgrund, AusweisTyp } from "@prisma/client" import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
export const VerbrauchsausweisGewerbeSchema = z.object({ export const VerbrauchsausweisGewerbeSchema = z.object({
id: z.string(), id: z.string(),
@@ -52,6 +52,7 @@ export const VerbrauchsausweisGewerbeSchema = z.object({
created_at: z.date(), created_at: z.date(),
updated_at: z.date(), updated_at: z.date(),
ausweistyp: z.nativeEnum(AusweisTyp), ausweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
pruefpunkt_heizungsalter: z.boolean().nullish(), pruefpunkt_heizungsalter: z.boolean().nullish(),
pruefpunkt_verbrauch_niedrig: z.boolean().nullish(), pruefpunkt_verbrauch_niedrig: z.boolean().nullish(),
pruefpunkt_verbrauch_hoch: z.boolean().nullish(), pruefpunkt_verbrauch_hoch: z.boolean().nullish(),

View File

@@ -1,5 +1,5 @@
import * as z from "zod" import * as z from "zod"
import { Ausstellgrund, AusweisTyp } from "@prisma/client" import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
export const VerbrauchsausweisWohnenSchema = z.object({ export const VerbrauchsausweisWohnenSchema = z.object({
id: z.string().describe("ID des Ausweises"), id: z.string().describe("ID des Ausweises"),
@@ -38,6 +38,7 @@ export const VerbrauchsausweisWohnenSchema = z.object({
beschreibung: z.string().nullish(), beschreibung: z.string().nullish(),
kontrolldatei_angefragt: z.boolean().describe("Ob bei der Anfrage der Registriernummer eine Kontrolldatei angefragt wurde").nullish(), kontrolldatei_angefragt: z.boolean().describe("Ob bei der Anfrage der Registriernummer eine Kontrolldatei angefragt wurde").nullish(),
ausweistyp: z.nativeEnum(AusweisTyp), ausweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
created_at: z.date(), created_at: z.date(),
updated_at: z.date(), updated_at: z.date(),
pruefpunkt_heizungsalter: z.boolean().nullish(), pruefpunkt_heizungsalter: z.boolean().nullish(),

View File

@@ -3,22 +3,19 @@
import "../style/global.css"; import "../style/global.css";
import "../../svelte-dialogs.config.js"; import "../../svelte-dialogs.config.js";
import DashboardSidebar from "../components/Dashboard/DashboardSidebar.svelte"; import DashboardSidebar from "../components/Dashboard/DashboardSidebar.svelte";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken"; import { BenutzerClient } from "#components/Ausweis/types";
import { BenutzerClient, ObjektClient } from "#components/Ausweis/types";
const valid = validateAccessTokenServer(Astro)
if (!valid) {
Astro.redirect("/auth/login", 302)
}
export interface Props { export interface Props {
title: string; title: string;
user: BenutzerClient user: BenutzerClient;
} }
const { title, user } = Astro.props; const { title, user } = Astro.props;
if (!user) {
Astro.redirect("/auth/login", 302);
}
const schema = JSON.stringify({ const schema = JSON.stringify({
"@context": "http://schema.org", "@context": "http://schema.org",
"@type": "Corporation", "@type": "Corporation",
@@ -53,22 +50,22 @@ let lightTheme = Astro.cookies.get("theme")?.value === "light";
if (import.meta.env.PROD) { if (import.meta.env.PROD) {
H.init("1jdkoe52", { H.init("1jdkoe52", {
serviceName: "online-energieausweis", serviceName: "online-energieausweis",
backendUrl: "https://highlight-backend.online-energieausweis.org/public", backendUrl:
"https://highlight-backend.online-energieausweis.org/public",
tracingOrigins: true, tracingOrigins: true,
networkRecording: { networkRecording: {
enabled: true, enabled: true,
recordHeadersAndBody: true recordHeadersAndBody: true,
} },
}) });
} }
</script> </script>
<!DOCTYPE html>
<html lang="de"> <html lang="de">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<script type="application/ld+json" set:html={schema}></script> <script type="application/ld+json" set:html={schema} />
<link rel="icon" type="image/svg+xml" href="/favicon.jpg" /> <link rel="icon" type="image/svg+xml" href="/favicon.jpg" />
<meta <meta
@@ -112,7 +109,6 @@ let lightTheme = Astro.cookies.get("theme")?.value === "light";
</head> </head>
<body> <body>
<main <main
class="p-0 grid max-w-[1920px] class="p-0 grid max-w-[1920px]
xs:grid-cols-[minmax(1fr,1fr)] xs:gap-1 xs:p-0 xs:grid-cols-[minmax(1fr,1fr)] xs:gap-1 xs:p-0
@@ -122,16 +118,15 @@ let lightTheme = Astro.cookies.get("theme")?.value === "light";
xl:grid-cols-[minmax(150px,350px)1fr] xl:gap-4 xl:p-6 xl:grid-cols-[minmax(150px,350px)1fr] xl:gap-4 xl:p-6
2xl:grid-cols-[minmax(150px,300px)1fr] 2xl:gap-5 2xl:p-6" 2xl:grid-cols-[minmax(150px,300px)1fr] 2xl:gap-5 2xl:p-6"
> >
<DashboardSidebar
lightTheme={lightTheme}
benutzer={user}
client:load
/>
<DashboardSidebar lightTheme={lightTheme} benutzer={user} client:load> <article class="box px-6 py-5 h-screen">
</DashboardSidebar> <slot />
</article>
<article class="box rounded-tl-none
xl:px-10 py-8">
<slot />
</article>
</main> </main>
</body> </body>
</html> </html>

View File

@@ -2,7 +2,8 @@ import { AufnahmeClient, ObjektClient, VerbrauchsausweisGewerbeClient } from "#c
import { getKlimafaktoren } from "#lib/Klimafaktoren.js"; import { getKlimafaktoren } from "#lib/Klimafaktoren.js";
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor.js"; import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor.js";
import moment from "moment"; import moment from "moment";
import bauwerkskatalog from "./bauwerkskatalog.json" assert { type: "json" } import bauwerkskatalog from "./bauwerkskatalog.json" with { type: "json" }
import { getKlimafaktorenServer } from "#lib/server/klimafaktoren.js";
function vergleichsWertNichtWohngebaeude(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient) { function vergleichsWertNichtWohngebaeude(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient) {
let tekWerte = new Array(8).fill(0); let tekWerte = new Array(8).fill(0);
@@ -59,43 +60,13 @@ function vergleichsWertNichtWohngebaeude(ausweis: VerbrauchsausweisGewerbeClient
* @param Ausweis ausweis Ein Ausweis dessen Energiebedarf berechnet werden soll * @param Ausweis ausweis Ein Ausweis dessen Energiebedarf berechnet werden soll
* @return VerbrauchsausweisGewerbeCalculationResult * @return VerbrauchsausweisGewerbeCalculationResult
*/ */
export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient) { export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, klimafaktoren: { month: number, year: number, klimafaktor: number }[]) {
if (!aufnahme || !objekt || !ausweis) { if (!aufnahme || !objekt || !ausweis || !klimafaktoren) {
return null; return null;
} }
const nutzflaeche = aufnahme.nutzflaeche || 0; const nutzflaeche = aufnahme.nutzflaeche || 0;
let startdatum = moment(ausweis.startdatum);
let klimafaktoren: Awaited<ReturnType<typeof getKlimafaktoren>> = [{
month: startdatum.month(),
year: startdatum.year(),
klimafaktor: 1
},
{
month: startdatum.month(),
year: startdatum.year() + 1,
klimafaktor: 1
},
{
month: startdatum.month(),
year: startdatum.year() + 2,
klimafaktor: 1
}];
try {
const response = await getKlimafaktoren(ausweis.startdatum, objekt.plz)
if (response) {
klimafaktoren = response
}
} catch (e) {
// TODO: Entweder setzen wir hier mit falschen Klimafaktoren fort, oder wir geben null zurück.
// Im Moment setzen wir einfach fort, aber das ist nicht unbedingt die beste Lösung.
// return null
}
// Endenergieverbrauch // Endenergieverbrauch
// Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden. // Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden.
let brennstoff_1 = { coe: 0, energietraeger: "", einheit: "", umrechnungsfaktor: 0, primaerenergiefaktor: 0 }, brennstoff_2 = { coe: 0, energietraeger: "", einheit: "", umrechnungsfaktor: 0, primaerenergiefaktor: 0 }; let brennstoff_1 = { coe: 0, energietraeger: "", einheit: "", umrechnungsfaktor: 0, primaerenergiefaktor: 0 }, brennstoff_2 = { coe: 0, energietraeger: "", einheit: "", umrechnungsfaktor: 0, primaerenergiefaktor: 0 };

View File

@@ -0,0 +1,39 @@
import moment from "moment";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "./VerbrauchsausweisGewerbe_2016.js";
import { Aufnahme, Objekt, VerbrauchsausweisGewerbe } from "#lib/server/prisma.js";
import { getKlimafaktoren } from "#lib/Klimafaktoren.js";
export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client(
ausweis: VerbrauchsausweisGewerbe,
aufnahme: Aufnahme,
objekt: Objekt,
) {
const startdatum = moment(ausweis.startdatum);
let klimafaktoren = await getKlimafaktoren(
objekt.plz as string,
startdatum.toDate(),
startdatum.add(2, "years").toDate()
);
if (!klimafaktoren || klimafaktoren.length === 0) {
klimafaktoren = [
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year"),
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 1,
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 2,
},
];
}
return await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt, klimafaktoren)
}

View File

@@ -0,0 +1,39 @@
import moment from "moment";
import { getKlimafaktorenServer } from "#lib/server/klimafaktoren.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "./VerbrauchsausweisGewerbe_2016.js";
import { Aufnahme, Objekt, VerbrauchsausweisGewerbe } from "#lib/server/prisma.js";
export async function endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server(
ausweis: VerbrauchsausweisGewerbe,
aufnahme: Aufnahme,
objekt: Objekt,
) {
const startdatum = moment(ausweis.startdatum);
let klimafaktoren = await getKlimafaktorenServer(
objekt.plz as string,
startdatum.toDate(),
startdatum.add(2, "years").toDate()
);
if (klimafaktoren.length === 0) {
klimafaktoren = [
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year"),
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 1,
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 2,
},
];
}
return await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt, klimafaktoren)
}

View File

@@ -1,8 +1,6 @@
import { AufnahmeClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { AufnahmeClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { getKlimafaktoren } from "#lib/Klimafaktoren.js";
import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor.js"; import { getHeizwertfaktor } from "#lib/server/Heizwertfaktor.js";
import { Enums } from "#lib/client/prisma.js"; import { Enums } from "#lib/client/prisma.js";
import moment from "moment";
export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016( export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
ausweis: VerbrauchsausweisWohnenClient, ausweis: VerbrauchsausweisWohnenClient,
@@ -24,43 +22,13 @@ export function energetischeNutzflaecheVerbrauchsausweisWohnen_2016(
export async function endEnergieVerbrauchVerbrauchsausweis_2016( export async function endEnergieVerbrauchVerbrauchsausweis_2016(
ausweis: VerbrauchsausweisWohnenClient, ausweis: VerbrauchsausweisWohnenClient,
aufnahme: AufnahmeClient, aufnahme: AufnahmeClient,
objekt: ObjektClient objekt: ObjektClient,
klimafaktoren: {month: number, year: number, klimafaktor: number}[]
) { ) {
if (!aufnahme || !objekt || !ausweis) { if (!aufnahme || !objekt || !ausweis || !klimafaktoren) {
return null; return null;
} }
let startdatum = moment(ausweis.startdatum);
let klimafaktoren: Awaited<ReturnType<typeof getKlimafaktoren>> = [{
month: startdatum.month(),
year: startdatum.year(),
klimafaktor: 1
},
{
month: startdatum.month(),
year: startdatum.year() + 1,
klimafaktor: 1
},
{
month: startdatum.month(),
year: startdatum.year() + 2,
klimafaktor: 1
}];
try {
const response = await getKlimafaktoren(ausweis.startdatum, objekt.plz)
if (response) {
klimafaktoren = response
}
} catch (e) {
// TODO: Entweder setzen wir hier mit falschen Klimafaktoren fort, oder wir geben null zurück.
// Im Moment setzen wir einfach fort, aber das ist nicht unbedingt die beste Lösung.
// return null
}
// Endenergieverbrauch // Endenergieverbrauch
// Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden. // Um den EEV auszurechnen, müssen die Verbräuche zu kWh konvertiert werden.
let brennstoff_1 = getHeizwertfaktor( let brennstoff_1 = getHeizwertfaktor(

View File

@@ -0,0 +1,43 @@
import {
VerbrauchsausweisWohnenClient,
AufnahmeClient,
ObjektClient,
} from "#components/Ausweis/types.js";
import { getKlimafaktoren } from "#lib/Klimafaktoren.js";
import moment from "moment";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "./VerbrauchsausweisWohnen_2016.js";
export async function endEnergieVerbrauchVerbrauchsausweis_2016_Client(
ausweis: VerbrauchsausweisWohnenClient,
aufnahme: AufnahmeClient,
objekt: ObjektClient,
) {
const startdatum = moment(ausweis.startdatum);
let klimafaktoren = await getKlimafaktoren(
objekt.plz as string,
startdatum.toDate(),
startdatum.add(2, "years").toDate()
);
if (!klimafaktoren || klimafaktoren.length === 0) {
klimafaktoren = [
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year"),
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 1,
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 2,
},
];
}
return await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt, klimafaktoren)
}

View File

@@ -0,0 +1,48 @@
import {
VerbrauchsausweisWohnenClient,
AufnahmeClient,
ObjektClient,
} from "#components/Ausweis/types.js";
import moment from "moment";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "./VerbrauchsausweisWohnen_2016.js";
import { getKlimafaktorenServer } from "#lib/server/klimafaktoren.js";
export async function endEnergieVerbrauchVerbrauchsausweis_2016_Server(
ausweis: VerbrauchsausweisWohnenClient,
aufnahme: AufnahmeClient,
objekt: ObjektClient
) {
const startdatum = moment(ausweis.startdatum);
let klimafaktoren = await getKlimafaktorenServer(
objekt.plz as string,
startdatum.toDate(),
startdatum.add(2, "years").toDate()
);
if (klimafaktoren.length === 0) {
klimafaktoren = [
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year"),
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 1,
},
{
klimafaktor: 1,
month: startdatum.get("m"),
year: startdatum.get("year") + 2,
},
];
}
return await endEnergieVerbrauchVerbrauchsausweis_2016(
ausweis,
aufnahme,
objekt,
klimafaktoren
);
}

View File

@@ -1,13 +0,0 @@
import type { VerbrauchsausweisWohnen } from "#lib/client/prisma";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "./VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import { AufnahmeClient, ObjektClient } from "#components/Ausweis/types.js";
export async function endEnergieVerbrauch(ausweis: VerbrauchsausweisWohnen, aufnahme: AufnahmeClient, objekt: ObjektClient): Promise<number> {
const result = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt);
if (!result) {
return 0;
}
return result.endEnergieVerbrauchGesamt;
}

View File

@@ -18,8 +18,6 @@ export const getKlimafaktoren = memoize(async (date: Date, plz: string) => {
}); });
return response; return response;
} catch (e) { } catch (e) {
console.log(e);
return null; return null;
} }
}); });

View File

@@ -112,4 +112,4 @@ export const SERVICES: Record<
}; };
export const BASE_URI = process.env.NODE_ENV == "production" ? "https://online-energieausweis.org" : "http://localhost:3000"; export const BASE_URI = process.env.NODE_ENV == "production" ? "https://online-energieausweis.org" : "http://localhost:3000";
export const LEX_OFFICE_API_KEY = process.env.NODE_ENV == "production" ? "iwQLCU_ZAq6bVV7hmR8RO8MiC8Q" : "znjmkmbA3Hbx9dC7wdKp7TnOf1pcRl_tCUwEBZys7bj-QRPG" export const LEX_OFFICE_API_KEY = process.env.NODE_ENV == "production" ? "iwQLCU_ZAq6bVV7hmR8RO8MiC8Q" : "iwQLCU_ZAq6bVV7hmR8RO8MiC8Q"

View File

@@ -4,8 +4,8 @@ import { PDFDocument, StandardFonts } from "pdf-lib";
import { xml2pdf } from "./elements/xml2pdf.js"; import { xml2pdf } from "./elements/xml2pdf.js";
import moment from "moment"; import moment from "moment";
import { Enums, Heizungsstatus } from "#lib/server/prisma.js"; import { Enums, Heizungsstatus } from "#lib/server/prisma.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
import { copyPage } from "./utils/copyPage.js"; import { copyPage } from "./utils/copyPage.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Server.js";
/* -------------------------------- Pdf Tools ------------------------------- */ /* -------------------------------- Pdf Tools ------------------------------- */
@@ -18,7 +18,7 @@ export async function pdfDatenblattVerbrauchsausweisGewerbe(ausweis: Verbrauchsa
// const template = VerbrauchsausweisWohnen2016Template as Template; // const template = VerbrauchsausweisWohnen2016Template as Template;
const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt); const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server(ausweis, aufnahme, objekt);
const height = pages[0].getHeight() const height = pages[0].getHeight()
const width = pages[0].getWidth() const width = pages[0].getWidth()

View File

@@ -6,6 +6,7 @@ import { xml2pdf } from "./elements/xml2pdf.js";
import moment from "moment"; import moment from "moment";
import { Enums, Heizungsstatus } from "#lib/server/prisma.js"; import { Enums, Heizungsstatus } from "#lib/server/prisma.js";
import { copyPage } from "./utils/copyPage.js"; import { copyPage } from "./utils/copyPage.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016_Server } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Server.js";
/* -------------------------------- Pdf Tools ------------------------------- */ /* -------------------------------- Pdf Tools ------------------------------- */
@@ -19,7 +20,7 @@ export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: Verbrauchsau
// const template = VerbrauchsausweisWohnen2016Template as Template; // const template = VerbrauchsausweisWohnen2016Template as Template;
const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt); const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016_Server(ausweis, aufnahme, objekt);
const height = pages[0].getHeight() const height = pages[0].getHeight()
const width = pages[0].getWidth() const width = pages[0].getWidth()
@@ -332,8 +333,5 @@ export async function pdfDatenblattVerbrauchsausweisWohnen(ausweis: Verbrauchsau
await layoutPage2.draw(pages[1], 0, pages[1].getHeight()) await layoutPage2.draw(pages[1], 0, pages[1].getHeight())
await layoutPage3.draw(pages[2], 0, pages[2].getHeight()) await layoutPage3.draw(pages[2], 0, pages[2].getHeight())
console.log("DONE");
return pdf.save(); return pdf.save();
} }

View File

@@ -1,5 +1,4 @@
import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types.js"; import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js"; import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";
import { Enums } from "#lib/server/prisma.js"; import { Enums } from "#lib/server/prisma.js";
import * as fs from "fs" import * as fs from "fs"
@@ -7,18 +6,19 @@ import moment from "moment";
import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from "pdf-lib"; import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from "pdf-lib";
import { addCheckMark } from "./utils/checkbox.js"; import { addCheckMark } from "./utils/checkbox.js";
import { addText } from "./utils/text.js"; import { addText } from "./utils/text.js";
import { addAnsichtsausweisLabel, addDatumGEG } from "./utils/helpers.js"; import { addAnsichtsausweisLabel, addDatumGEG, addRegistriernummer } from "./utils/helpers.js";
import { getS3File } from "#lib/s3.js"; import { getS3File } from "#lib/s3.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Server.js";
export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient) { export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewerbeClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, vorschau = true) {
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("../../../public/pdf/templates/GEG24_Nichtwohngebaeude.pdf", import.meta.url), "base64"); const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("../../../public/pdf/templates/GEG24_Nichtwohngebaeude.pdf", import.meta.url), "base64");
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF) const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
const pages = pdf.getPages() const pages = pdf.getPages()
// const template = VerbrauchsausweisWohnen2016Template as Template; // const template = VerbrauchsausweisWohnen2016Template as Template;
const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt); const berechnungen = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Server(ausweis, aufnahme, objekt);
const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt) const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt)
@@ -30,7 +30,7 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
const form = pdf.getForm() const form = pdf.getForm()
form.updateFieldAppearances(font) form.updateFieldAppearances(font)
pages[0].drawText(`ID: ${aufnahme.id || ""}`, { pages[0].drawText(`ID: ${ausweis.id || ""}`, {
x: 211, x: 211,
y: height - 112.5, y: height - 112.5,
size: 10 size: 10
@@ -213,15 +213,20 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
const addEnergieverbrauchSkalaPfeile = async (page: PDFPage) => { const addEnergieverbrauchSkalaPfeile = async (page: PDFPage) => {
const pfeilNachUnten = await pdf.embedPng(fs.readFileSync(new URL("../../../public/images/pfeil-nach-unten.png", import.meta.url), "base64")) const pfeilNachUnten = await pdf.embedPng(fs.readFileSync(new URL("../../../public/images/pfeil-nach-unten.png", import.meta.url), "base64"))
const pfeilNachOben = await pdf.embedPng(fs.readFileSync(new URL("../../../public/images/pfeil-nach-oben.png", import.meta.url), "base64"))
// Wir müssen den berechneten Wert zwischen 0 und 1000 als Wert zwischen 0 und 1 festlegen // Wir müssen den berechneten Wert zwischen 0 und 1000 als Wert zwischen 0 und 1 festlegen
const endenergieverbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.endEnergieVerbrauchGesamt || 0)) / 1000 const endenergieverbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.endEnergieVerbrauchGesamt || 0)) / 1000
const stromVerbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.endEnergieVerbrauchStrom || 0)) / 1000 const stromVerbrauchTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.endEnergieVerbrauchStrom || 0)) / 1000
const vergleichsWertWaermeTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.vergleichsWertWaerme || 0)) / 1000
const vergleichsWertStromTranslationPercentage = Math.min(1000, Math.max(0, berechnungen?.vergleichsWertStrom || 0)) / 1000
const minTranslation = 78 const minTranslation = 78
const maxTranslation = 512 const maxTranslation = 512
const endenergieverbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * endenergieverbrauchTranslationPercentage; const endenergieverbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * endenergieverbrauchTranslationPercentage;
const stromVerbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * stromVerbrauchTranslationPercentage; const stromVerbrauchTranslationX = minTranslation + (maxTranslation - minTranslation) * stromVerbrauchTranslationPercentage;
const vergleichsWertWaermeTranslationX = minTranslation + (maxTranslation - minTranslation) * vergleichsWertWaermeTranslationPercentage;
const vergleichsWertStromTranslationX = minTranslation + (maxTranslation - minTranslation) * vergleichsWertStromTranslationPercentage;
const pfeilWidth = 20 const pfeilWidth = 20
const margin = 5; const margin = 5;
@@ -233,8 +238,17 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
height: 30 height: 30
}) })
page.drawImage(pfeilNachOben, {
x: vergleichsWertWaermeTranslationX,
y: height - 293,
width: pfeilWidth,
height: 30
})
const endEnergieVerbrauchGesamtText = `${berechnungen?.endEnergieVerbrauchGesamt.toString()}kWh/(m²a)`; const endEnergieVerbrauchGesamtText = `${berechnungen?.endEnergieVerbrauchGesamt.toString()}kWh/(m²a)`;
const stromVerbrauchGesamtText = `${berechnungen?.endEnergieVerbrauchStrom.toString()}kWh/(m²a)`; const stromVerbrauchGesamtText = `${berechnungen?.endEnergieVerbrauchStrom.toString()}kWh/(m²a)`;
const vergleichswertWaermeText = `${berechnungen?.vergleichsWertWaerme.toString()}kWh/(m²a)`
const vergleichswertStromText = `${berechnungen?.vergleichsWertStrom.toString()}kWh/(m²a)`
if (endenergieverbrauchTranslationPercentage > 0.5) { if (endenergieverbrauchTranslationPercentage > 0.5) {
page.drawText("Endenergieverbrauch Wärme", { page.drawText("Endenergieverbrauch Wärme", {
@@ -263,6 +277,33 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
}) })
} }
if (vergleichsWertWaermeTranslationPercentage > 0.5) {
page.drawText("Vergleichswert Wärme", {
x: vergleichsWertWaermeTranslationX - margin - font.widthOfTextAtSize("Vergleichswert", 10),
y: height - 275,
size: 10
})
page.drawText(vergleichswertWaermeText, {
x: vergleichsWertWaermeTranslationX - margin - bold.widthOfTextAtSize(vergleichswertWaermeText, 10),
y: height - 289,
size: 10,
font: bold
})
} else {
page.drawText("Vergleichswert Wärme", {
x: vergleichsWertWaermeTranslationX + pfeilWidth + margin,
y: height - 275,
size: 10
})
page.drawText(vergleichswertWaermeText, {
x: vergleichsWertWaermeTranslationX + pfeilWidth + margin,
y: height - 289,
size: 10,
font: bold
})
}
page.drawImage(pfeilNachUnten, { page.drawImage(pfeilNachUnten, {
x: stromVerbrauchTranslationX, x: stromVerbrauchTranslationX,
y: height - 354, y: height - 354,
@@ -270,6 +311,13 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
height: 30 height: 30
}) })
page.drawImage(pfeilNachOben, {
x: vergleichsWertStromTranslationX,
y: height - 437,
width: pfeilWidth,
height: 30
})
if (endenergieverbrauchTranslationPercentage > 0.5) { if (endenergieverbrauchTranslationPercentage > 0.5) {
page.drawText("Endenergieverbrauch Strom", { page.drawText("Endenergieverbrauch Strom", {
x: stromVerbrauchTranslationX - margin - font.widthOfTextAtSize("Primärenergieverbrauch", 10), x: stromVerbrauchTranslationX - margin - font.widthOfTextAtSize("Primärenergieverbrauch", 10),
@@ -296,16 +344,43 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
font: bold font: bold
}) })
} }
if (vergleichsWertWaermeTranslationPercentage > 0.5) {
page.drawText("Vergleichswert Strom", {
x: vergleichsWertStromTranslationX - margin - font.widthOfTextAtSize("Vergleichswert", 10),
y: height - 420,
size: 10
})
page.drawText(vergleichswertStromText, {
x: vergleichsWertStromTranslationX - margin - bold.widthOfTextAtSize(vergleichswertStromText, 10),
y: height - 434,
size: 10,
font: bold
})
} else {
page.drawText("Vergleichswert Strom", {
x: vergleichsWertStromTranslationX + pfeilWidth + margin,
y: height - 420,
size: 10
})
page.drawText(vergleichswertStromText, {
x: vergleichsWertStromTranslationX + pfeilWidth + margin,
y: height - 434,
size: 10,
font: bold
})
}
} }
addEnergieverbrauchSkalaPfeile(pages[2]) addEnergieverbrauchSkalaPfeile(pages[2])
if (ausweis.warmwasser_enthalten) { if (ausweis.warmwasser_enthalten) {
addCheckMark(pages[2], 41, height - 269) addCheckMark(pages[2], 41, height - 293)
} }
if (ausweis.kuehlung_enthalten) { if (ausweis.kuehlung_enthalten) {
addCheckMark(pages[2], 41, height - 281) addCheckMark(pages[2], 41, height - 305)
} }
if (ausweis.stromverbrauch_enthaelt_heizung) { if (ausweis.stromverbrauch_enthaelt_heizung) {
@@ -612,10 +687,16 @@ export async function pdfVerbrauchsausweisGewerbe(ausweis: VerbrauchsausweisGewe
} }
for (const page of pages) { for (let i = 0; i < pages.length; i++) {
addAnsichtsausweisLabel(page, font) const page = pages[i];
addDatumGEG(page, font) if (vorschau) {
} addAnsichtsausweisLabel(page, font)
}
addDatumGEG(page, font)
if (i !== pages.length - 1) {
addRegistriernummer(page, font, ausweis.registriernummer || "")
}
}

View File

@@ -1,5 +1,4 @@
import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { AufnahmeClient, BenutzerClient, BildClient, ObjektClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js"; import { getEmpfehlungen } from "#lib/XML/getEmpfehlungen.js";
import { Enums } from "#lib/server/prisma.js"; import { Enums } from "#lib/server/prisma.js";
import * as fs from "fs" import * as fs from "fs"
@@ -7,19 +6,21 @@ import moment from "moment";
import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from "pdf-lib"; import { PDFDocument, PDFFont, PDFImage, PDFPage, StandardFonts } from "pdf-lib";
import { addCheckMark } from "./utils/checkbox.js"; import { addCheckMark } from "./utils/checkbox.js";
import { addText } from "./utils/text.js"; import { addText } from "./utils/text.js";
import { addAnsichtsausweisLabel, addDatumGEG } from "./utils/helpers.js"; import { addAnsichtsausweisLabel, addDatumGEG, addRegistriernummer } from "./utils/helpers.js";
import { getS3File } from "#lib/s3.js"; import { getS3File } from "#lib/s3.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016_Server } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Server.js";
/* -------------------------------- Pdf Tools ------------------------------- */ /* -------------------------------- Pdf Tools ------------------------------- */
export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient) { export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, vorschau = true) {
const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("../../../public/pdf/templates/GEG24_Wohngebaeude_ohne_pfeile.pdf", import.meta.url), "base64"); const VerbrauchsausweisWohnenGEG2024PDF = fs.readFileSync(new URL("../../../public/pdf/templates/GEG24_Wohngebaeude_ohne_pfeile.pdf", import.meta.url), "base64");
const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF) const pdf = await PDFDocument.load(VerbrauchsausweisWohnenGEG2024PDF)
const pages = pdf.getPages() const pages = pdf.getPages()
// const template = VerbrauchsausweisWohnen2016Template as Template; // const template = VerbrauchsausweisWohnen2016Template as Template;
const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt); const berechnungen = await endEnergieVerbrauchVerbrauchsausweis_2016_Server(ausweis, aufnahme, objekt);
const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt) const empfehlungen = getEmpfehlungen(ausweis, aufnahme, objekt)
const height = pages[0].getHeight() const height = pages[0].getHeight()
@@ -27,7 +28,7 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne
const font = await pdf.embedFont(StandardFonts.Helvetica) const font = await pdf.embedFont(StandardFonts.Helvetica)
const bold = await pdf.embedFont(StandardFonts.HelveticaBold) const bold = await pdf.embedFont(StandardFonts.HelveticaBold)
pages[0].drawText(`ID: ${aufnahme.id || ""}`, { pages[0].drawText(`ID: ${ausweis.id || ""}`, {
x: 211, x: 211,
y: height - 112.5, y: height - 112.5,
size: 10 size: 10
@@ -591,9 +592,15 @@ export async function pdfVerbrauchsausweisWohnen(ausweis: VerbrauchsausweisWohne
addEmpfehlung(empfehlung.anlagenteil, empfehlung.description, true, empfehlung.amortisationszeit, empfehlung.kosten) addEmpfehlung(empfehlung.anlagenteil, empfehlung.description, true, empfehlung.amortisationszeit, empfehlung.kosten)
} }
for (const page of pages) { for (let i = 0; i < pages.length; i++) {
addAnsichtsausweisLabel(page, font) const page = pages[i];
if (vorschau) {
addAnsichtsausweisLabel(page, font)
}
addDatumGEG(page, font) addDatumGEG(page, font)
if (i !== pages.length - 1) {
addRegistriernummer(page, font, ausweis.registriernummer || "")
}
} }
return pdf.save(); return pdf.save();

View File

@@ -22,3 +22,13 @@ export function addAnsichtsausweisLabel(page: PDFPage, font: PDFFont) {
opacity: 0.3, opacity: 0.3,
}); });
} }
export function addRegistriernummer(page: PDFPage, font: PDFFont, registriernummer: string) {
page.drawText(registriernummer, {
x: 435,
y: page.getHeight() - 113,
size: 10,
font,
});
}

View File

@@ -31,15 +31,15 @@ export function getPrismaAusweisAdapter(id: string) {
* Gibt den richtigen Ansichtsausweis basierend auf der Ausweisart zurück. * Gibt den richtigen Ansichtsausweis basierend auf der Ausweisart zurück.
* @param ausweis * @param ausweis
*/ */
export async function getAnsichtsausweis(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, ausweisart = getAusweisartFromId(ausweis.id)) { export async function getAnsichtsausweis(ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient, aufnahme: AufnahmeClient, objekt: ObjektClient, bilder: BildClient[], user: BenutzerClient, vorschau: boolean = true, ausweisart = getAusweisartFromId(ausweis.id)) {
if (!ausweisart) { if (!ausweisart) {
return null return null
} }
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) { if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
return await pdfVerbrauchsausweisWohnen(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt, bilder, user) return await pdfVerbrauchsausweisWohnen(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt, bilder, user, vorschau)
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) { } else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
return await pdfVerbrauchsausweisGewerbe(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt, bilder, user) return await pdfVerbrauchsausweisGewerbe(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt, bilder, user, vorschau)
} }
return null return null

View File

@@ -8,6 +8,28 @@ export async function getVerbrauchsausweisWohnen(id: string): Promise<Verbrauchs
}) })
} }
export async function getVerbrauchsausweisWohnenKomplett(id: string) {
return await prisma.verbrauchsausweisWohnen.findUnique({
where: {
id
},
include: {
aufnahme: {
include: {
bilder: true,
objekt: {
include: {
benutzer: true,
},
},
},
},
},
})
}
export type VerbrauchsausweisWohnenKomplett = Awaited<ReturnType<typeof getVerbrauchsausweisWohnenKomplett>>;
export async function getVerbrauchsausweisGewerbe(id: string): Promise<VerbrauchsausweisGewerbe | null> { export async function getVerbrauchsausweisGewerbe(id: string): Promise<VerbrauchsausweisGewerbe | null> {
return await prisma.verbrauchsausweisGewerbe.findUnique({ return await prisma.verbrauchsausweisGewerbe.findUnique({
where: { where: {
@@ -16,6 +38,26 @@ export async function getVerbrauchsausweisGewerbe(id: string): Promise<Verbrauch
}) })
} }
export async function getVerbrauchsausweisGewerbeKomplett(id: string) {
return await prisma.verbrauchsausweisGewerbe.findUnique({
where: {
id
},
include: {
aufnahme: {
include: {
bilder: true,
objekt: {
include: {
benutzer: true,
},
},
},
},
},
})
}
export async function getBedarfsausweisWohnen(id: string): Promise<BedarfsausweisWohnen | null> { export async function getBedarfsausweisWohnen(id: string): Promise<BedarfsausweisWohnen | null> {
return await prisma.bedarfsausweisWohnen.findUnique({ return await prisma.bedarfsausweisWohnen.findUnique({
where: { where: {
@@ -24,6 +66,26 @@ export async function getBedarfsausweisWohnen(id: string): Promise<Bedarfsauswei
}) })
} }
export async function getBedarfsausweisWohnenKomplett(id: string) {
return await prisma.bedarfsausweisWohnen.findUnique({
where: {
id
},
include: {
aufnahme: {
include: {
bilder: true,
objekt: {
include: {
benutzer: true,
},
},
},
},
},
})
}
export async function getBedarfsausweisGewerbe(id: string): Promise<BedarfsausweisGewerbe | null> { export async function getBedarfsausweisGewerbe(id: string): Promise<BedarfsausweisGewerbe | null> {
return await prisma.bedarfsausweisGewerbe.findUnique({ return await prisma.bedarfsausweisGewerbe.findUnique({
where: { where: {

282
src/lib/server/invoice.ts Normal file
View File

@@ -0,0 +1,282 @@
import { getAusweisartFromId } from "#components/Ausweis/types.js";
import moment from "moment";
import { createLexOfficeCustomer } from "./lexoffice.js";
import { Enums, prisma, Rechnung } from "./prisma.js";
import { LEX_OFFICE_API_KEY, PRICES } from "#lib/constants.js";
import { VerbrauchsausweisWohnenKomplett } from "./db.js";
export function createLineItem(name: string, preis: number, steuer: number) {
return {
type: "custom",
name: name,
description: "",
quantity: 1,
lineItemAmount: preis,
unitName: name,
unitPrice: {
currency: "EUR",
grossAmount: preis,
taxRatePercentage: steuer,
},
};
}
type LineItem = ReturnType<typeof createLineItem>;
export function addedServicesNeu(
data: any,
rechnung: Rechnung,
steuer: number
) {
if (rechnung.services.includes(Enums.Service.Qualitaetsdruck)) {
data["lineItems"].push(
createLineItem("Zusatzservice Postversand", 9, steuer)
);
}
if (rechnung.services.includes(Enums.Service.Aushang)) {
data["lineItems"].push(
createLineItem("Zusatzservice Aushang", 10, steuer)
);
}
if (rechnung.services.includes(Enums.Service.SameDay)) {
data["lineItems"].push(
createLineItem("Zusatzservice Same Day Service", 29, steuer)
);
}
if (rechnung.services.includes(Enums.Service.Telefonberatung)) {
data["lineItems"].push(
createLineItem("Zusatzservice Telefonische Beratung", 75, steuer)
);
}
return data;
}
/**
* Erstellt eine Rechnung in LexOffice und gibt die ID zurück.
* Die Preise basieren auf den in der Konstante `__PRICES__` definierten Preisen.
* @param Ausweis ausweis
* @param Rechnung $rechnung
* @return array
* @throws Error
*/
export async function createInvoice(
ausweis: VerbrauchsausweisWohnenKomplett,
rechnung: Rechnung
) {
if (!ausweis) {
throw new Error("Ausweis ist null");
}
if (!ausweis.benutzer_id) {
throw new Error("Benutzer ist nicht vorhanden");
}
const user = await prisma.benutzer.findUnique({
where: {
id: ausweis.benutzer_id,
},
});
if (!user) {
throw new Error("Nutzer existiert nicht!");
} else if (user.lex_office_id == null) {
// User has no valid lex_id
const lex_office_id = await createLexOfficeCustomer(user);
user.lex_office_id = lex_office_id;
await prisma.benutzer.update({
where: {
id: user.id,
},
data: {
lex_office_id: user.lex_office_id,
},
});
}
const ausweisart = getAusweisartFromId(ausweis.id);
let data = {
voucherDate: moment().format("YYYY-MM-DDTHH:mm:ss.SSSZ"),
taxConditions: {
taxType: "gross",
},
shippingConditions: {
shippingType: "none",
},
address: {
contactId: user.lex_office_id,
name: rechnung.empfaenger || "----",
street: rechnung.strasse,
city: rechnung.ort,
zip: rechnung.plz,
countryCode: "DE",
supplement: rechnung.zusatzzeile,
},
lineItems: [] as LineItem[],
totalPrice: {
currency: "EUR",
totalGrossAmount: rechnung.betrag,
},
title: "Rechnung",
introduction:
"Ihren Energieausweis (Ausweis ID {ausweis.id}) stellen wir Ihnen hiermit in Rechnung",
remark: "Vielen Dank für Ihren Einkauf.",
};
if (rechnung.status == Enums.Rechnungsstatus.paid) {
const types: Record<Enums.Bezahlmethoden, string> = {
[Enums.Bezahlmethoden.paypal]: "PayPal",
[Enums.Bezahlmethoden.creditcard]: "Kreditkarte",
[Enums.Bezahlmethoden.sofort]: "Sofortüberweisung",
[Enums.Bezahlmethoden.giropay]: "Giropay",
[Enums.Bezahlmethoden.rechnung]: "Rechnung",
};
const type = types[rechnung.bezahlmethode];
data[
"introduction"
] = `Vielen Dank für Ihren Einkauf (Ausweis ID ${ausweis.id}). Ihre Rechnung haben sie bereits mit ${type} bezahlt.`;
}
const tax_rate = 19;
if (rechnung.betrag == 15) {
// Korrektur alleinstehend
data["lineItems"].push(
createLineItem("Service Korrektur anfordern", rechnung.betrag, 19)
);
} else if (rechnung.betrag == 476) {
data["lineItems"].push(
createLineItem("GEG Berechnung Wohngebäude", rechnung.betrag, 19)
);
} else if (rechnung.betrag > 400 && rechnung.betrag != 476) {
data["lineItems"].push(
createLineItem("Bedarfsausweis Gewerbe", rechnung.betrag, 19)
);
} else if (ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen) {
if (ausweis.ausweistyp == Enums.AusweisTyp.Standard) {
data["lineItems"].push(
createLineItem(
`Verbrauchsausweis Online (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisWohnen.Standard,
19
)
);
} else if (ausweis.ausweistyp == Enums.AusweisTyp.Beratung) {
data["lineItems"].push(
createLineItem(
`Verbrauchsausweis Online (Vorprüfung negativ) (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisWohnen.Beratung,
19
)
);
} else if (ausweis.ausweistyp == Enums.AusweisTyp.Offline) {
data["lineItems"].push(
createLineItem(
`Verbrauchsausweis Offline (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisWohnen.Offline,
19
)
);
}
} else if (ausweisart == Enums.Ausweisart.BedarfsausweisWohnen) {
if (ausweis.ausweistyp == Enums.AusweisTyp.Standard) {
data["lineItems"].push(
createLineItem(
`Bedarfsausweis Online (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisWohnen.Standard,
19
)
);
} else if (ausweis.ausweistyp == Enums.AusweisTyp.Beratung) {
data["lineItems"].push(
createLineItem(
`Bedarfsausweis Online (Vorprüfung negativ) (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisWohnen.Beratung,
19
)
);
} else if (ausweis.ausweistyp == Enums.AusweisTyp.Offline) {
data["lineItems"].push(
createLineItem(
`Bedarfsausweis Offline (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisWohnen.Offline,
19
)
);
}
} else if (ausweisart == Enums.Ausweisart.VerbrauchsausweisGewerbe) {
if (ausweis.ausweistyp == Enums.AusweisTyp.Standard) {
data["lineItems"].push(
createLineItem(
`Verbrauchsausweis Nichtwohngebäude Online (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisGewerbe.Standard,
19
)
);
} else if (ausweis.ausweistyp == Enums.AusweisTyp.Beratung) {
data["lineItems"].push(
createLineItem(
`Verbrauchsausweis Nichtwohngebäude Online (Vorprüfung negativ) (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisGewerbe.Beratung,
19
)
);
} else if (ausweis.ausweistyp == Enums.AusweisTyp.Offline) {
data["lineItems"].push(
createLineItem(
`Verbrauchsausweis Nichtwohngebäude Offline (ID ${ausweis.id})`,
PRICES.VerbrauchsausweisGewerbe.Offline,
19
)
);
}
}
data = addedServicesNeu(data, rechnung, 19);
const response = await fetch(
"https://api.lexoffice.io/v1/invoices?finalize=true",
{
method: "POST",
headers: {
Accept: `application/json`,
Authorization: `Bearer ${LEX_OFFICE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}
);
if (response.status == 400) {
throw new Error("Fehler beim Absenden der Request.");
}
const invoice = await response.json();
// Wir müssen den Ausweis nun wieder abfragen, um die erstellte Rechnungsnummer zu bekommen.
const response_id = invoice["id"];
const request = await fetch(
`https://api.lexoffice.io/v1/invoices/${response_id}`,
{
method: "GET",
headers: {
Accept: `application/json`,
Authorization: `Bearer ${LEX_OFFICE_API_KEY}`,
"Content-Type": "application/json",
},
}
);
const abfrage_response = await request.json();
return {
id: invoice["id"],
voucherNumber: abfrage_response["voucherNumber"],
};
}

View File

@@ -0,0 +1,47 @@
import moment from "moment";
import { prisma } from "./prisma.js";
export async function getKlimafaktorenServer(plz: string, startdatum: Date, enddatum: Date) {
const start = moment(startdatum);
const end = moment(enddatum);
if (start.isSameOrAfter(end)) {
return []
}
const intervals = [];
let currentDate = start.clone();
while (currentDate.isSameOrBefore(end)) {
let copy = currentDate.clone();
intervals.push(copy);
currentDate.add(1, "year");
}
let klimafaktoren = await prisma.klimafaktoren.findMany({
where: {
plz,
month: intervals[0].month(),
OR: intervals.map((date) => {
return {
year: date.year(),
};
}),
},
});
if (!klimafaktoren) {
return []
}
// NOTE: Sollten wir hier lieber den Output padden und trotzdem die gefundenen zurückgeben?
if (klimafaktoren.length !== intervals.length) {
return []
}
return klimafaktoren.map((klimafaktor) => ({
month: klimafaktor.month,
year: klimafaktor.year,
klimafaktor: klimafaktor.klimafaktor,
}));
}

View File

@@ -1,10 +1,10 @@
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js"; import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { LEX_OFFICE_API_KEY } from "#lib/constants.js"; import { LEX_OFFICE_API_KEY } from "#lib/constants.js";
import { Aufnahme, BedarfsausweisWohnen, Benutzer, Rechnung, VerbrauchsausweisGewerbe, VerbrauchsausweisWohnen } from "#lib/client/prisma"; import { Aufnahme, BedarfsausweisWohnen, Benutzer, Rechnung, VerbrauchsausweisGewerbe, VerbrauchsausweisWohnen } from "#lib/client/prisma.js";
import { prisma } from "#lib/server/prisma"; import { prisma } from "#lib/server/prisma.js";
import moment from "moment"; import moment from "moment";
export function lexOfficeAnfrageSenden(ausweis: VerbrauchsausweisWohnen | BedarfsausweisWohnen | VerbrauchsausweisGewerbe, options: { export async function lexOfficeAnfrageSenden(ausweis: VerbrauchsausweisWohnen | BedarfsausweisWohnen | VerbrauchsausweisGewerbe, options: {
bezeichnung: string, bezeichnung: string,
positionstext: string, positionstext: string,
preis: number, preis: number,
@@ -103,149 +103,149 @@ export function lexOfficeAnfrageSenden(ausweis: VerbrauchsausweisWohnen | Bedarf
throw new Error(`Ein Fehler ist aufgetreten: ${pdfResult.message}`); throw new Error(`Ein Fehler ist aufgetreten: ${pdfResult.message}`);
} }
$pdf_id = $render_response["documentFileId"]; // $pdf_id = $render_response["documentFileId"];
db()->execute("UPDATE Angebotsanfragen SET // db()->execute("UPDATE Angebotsanfragen SET
Adresse_Objekt = :Adresse_Objekt, // Adresse_Objekt = :Adresse_Objekt,
PLZ_Objekt = :PLZ_Objekt, // PLZ_Objekt = :PLZ_Objekt,
Ort_Objekt = :Ort_Objekt, // Ort_Objekt = :Ort_Objekt,
Dienstleistung = :Dienstleistung, // Dienstleistung = :Dienstleistung,
Empfaengerrechnung = :Empfaengerrechnung, // Empfaengerrechnung = :Empfaengerrechnung,
Zusatzzeilerechnung = :Zusatzzeilerechnung, // Zusatzzeilerechnung = :Zusatzzeilerechnung,
Adresse = :Adresse, // Adresse = :Adresse,
PLZ = :PLZ, // PLZ = :PLZ,
Ort = :Ort, // Ort = :Ort,
Anlass = :Anlass, // Anlass = :Anlass,
Baujahrheizung = :Baujahrheizung, // Baujahrheizung = :Baujahrheizung,
Baujahrgebaeude = :Baujahrgebaeude, // Baujahrgebaeude = :Baujahrgebaeude,
Baujahrklima = :Baujahrklima, // Baujahrklima = :Baujahrklima,
Gebaeudetyp = :Gebaeudetyp, // Gebaeudetyp = :Gebaeudetyp,
Nutzflaeche = :Nutzflaeche, // Nutzflaeche = :Nutzflaeche,
Sanierungsstatus = :Sanierungsstatus, // Sanierungsstatus = :Sanierungsstatus,
Nachricht = :Nachricht, // Nachricht = :Nachricht,
Datei = :Datei, // Datei = :Datei,
Rolle = :Rolle, // Rolle = :Rolle,
Email = :Email, // Email = :Email,
Angebotspreis = :Angebotspreis, // Angebotspreis = :Angebotspreis,
Rabatt = :Rabatt, // Rabatt = :Rabatt,
`Status` = 'Verschickt', // `Status` = 'Verschickt',
lex_office_id = :lex_office_id, // lex_office_id = :lex_office_id,
Textanschreiben = :Textanschreiben, // Textanschreiben = :Textanschreiben,
Positionstext = :Positionstext // Positionstext = :Positionstext
WHERE Auftragsnummer = :Auftragsnummer", [ // WHERE Auftragsnummer = :Auftragsnummer", [
"Adresse_Objekt": $_POST["gebaeude_strasse"], // "Adresse_Objekt": $_POST["gebaeude_strasse"],
"PLZ_Objekt": $_POST["gebaeude_plz"], // "PLZ_Objekt": $_POST["gebaeude_plz"],
"Ort_Objekt": $_POST["gebaeude_ort"], // "Ort_Objekt": $_POST["gebaeude_ort"],
"Dienstleistung": $_POST["dienstleistung"], // "Dienstleistung": $_POST["dienstleistung"],
"Empfaengerrechnung": $_POST["rechnung_empfaenger"], // "Empfaengerrechnung": $_POST["rechnung_empfaenger"],
"Zusatzzeilerechnung": $_POST["rechnung_zusatzzeile"], // "Zusatzzeilerechnung": $_POST["rechnung_zusatzzeile"],
"Adresse": $_POST["rechnung_strasse"], // "Adresse": $_POST["rechnung_strasse"],
"PLZ": $_POST["rechnung_plz"], // "PLZ": $_POST["rechnung_plz"],
"Ort": $_POST["rechnung_ort"], // "Ort": $_POST["rechnung_ort"],
"Anlass": $_POST["anlass"], // "Anlass": $_POST["anlass"],
"Baujahrheizung": $_POST["baujahr_heizung"], // "Baujahrheizung": $_POST["baujahr_heizung"],
"Baujahrgebaeude": $_POST["baujahr_gebaeude"], // "Baujahrgebaeude": $_POST["baujahr_gebaeude"],
"Baujahrklima": $_POST["baujahr_klimaanlage"], // "Baujahrklima": $_POST["baujahr_klimaanlage"],
"Gebaeudetyp": $_POST["gebaeudetyp"], // "Gebaeudetyp": $_POST["gebaeudetyp"],
"Nutzflaeche": $_POST["nutzflaeche"], // "Nutzflaeche": $_POST["nutzflaeche"],
"Sanierungsstatus": $_POST["sanierungsstatus"], // "Sanierungsstatus": $_POST["sanierungsstatus"],
"Nachricht": $_POST["nachricht"], // "Nachricht": $_POST["nachricht"],
"Datei": $dateien, // "Datei": $dateien,
"Rolle": $_POST["rolle"], // "Rolle": $_POST["rolle"],
"Email": $_POST["email"], // "Email": $_POST["email"],
"Angebotspreis": $_POST["Angebotspreis"], // "Angebotspreis": $_POST["Angebotspreis"],
"Rabatt": $_POST["Rabatt"], // "Rabatt": $_POST["Rabatt"],
"lex_office_id": $lex_office_id, // "lex_office_id": $lex_office_id,
"Textanschreiben": $_POST["Textanschreiben"], // "Textanschreiben": $_POST["Textanschreiben"],
"Positionstext": $_POST["Positionstext"], // "Positionstext": $_POST["Positionstext"],
"Auftragsnummer": $_POST["Auftragsnummer"] // "Auftragsnummer": $_POST["Auftragsnummer"]
]); // ]);
// Die Auftragsnummer abfragen // // Die Auftragsnummer abfragen
$curl_nummer = curl_init(); // $curl_nummer = curl_init();
curl_setopt_array($curl_nummer, [ // curl_setopt_array($curl_nummer, [
CURLOPT_URL: "https://api.lexoffice.io/v1/quotations/$lex_office_id", // CURLOPT_URL: "https://api.lexoffice.io/v1/quotations/$lex_office_id",
CURLOPT_RETURNTRANSFER: true, // CURLOPT_RETURNTRANSFER: true,
CURLOPT_ENCODING: "", // CURLOPT_ENCODING: "",
CURLOPT_MAXREDIRS: 10, // CURLOPT_MAXREDIRS: 10,
CURLOPT_TIMEOUT: 30, // CURLOPT_TIMEOUT: 30,
CURLOPT_HTTP_VERSION: CURL_HTTP_VERSION_1_1, // CURLOPT_HTTP_VERSION: CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST: "GET", // CURLOPT_CUSTOMREQUEST: "GET",
CURLOPT_HTTPHEADER: [ // CURLOPT_HTTPHEADER: [
"Accept: application/json", // "Accept: application/json",
"Authorization: Bearer " . LEX_OFFICE_API_KEY // "Authorization: Bearer " . LEX_OFFICE_API_KEY
] // ]
]); // ]);
$nummer_response = curl_exec($curl_nummer); // $nummer_response = curl_exec($curl_nummer);
$nummer_response = json_decode($nummer_response, true); // $nummer_response = json_decode($nummer_response, true);
$err = curl_error($curl_nummer); // $err = curl_error($curl_nummer);
curl_close($curl_nummer); // curl_close($curl_nummer);
// Und die Mail verschicken // // Und die Mail verschicken
$mail = new PHPMailer\PHPMailer\PHPMailer(true); // $mail = new PHPMailer\PHPMailer\PHPMailer(true);
$mail->IsSMTP(); // $mail->IsSMTP();
$mail->Host = "smtp.ionos.de"; // $mail->Host = "smtp.ionos.de";
$mail->SMTPAuth = true; // $mail->SMTPAuth = true;
$mail->Username = 'info@online-energieausweis.org'; // $mail->Username = 'info@online-energieausweis.org';
$mail->Password = 'Katendeich5a2024!'; // $mail->Password = 'Katendeich5a2024!';
$mail->CharSet = 'UTF-8'; // $mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64'; // $mail->Encoding = 'base64';
$mail->setFrom("info@online-energieausweis.org", "IB Cornelsen",0); // $mail->setFrom("info@online-energieausweis.org", "IB Cornelsen",0);
$mail->addAddress($_POST["email"], $_POST["vorname"] . " " . $_POST["name"]); // $mail->addAddress($_POST["email"], $_POST["vorname"] . " " . $_POST["name"]);
$mail->addCC("jens.cornelsen@ib-cornelsen.de", "Jens Cornelsen"); // $mail->addCC("jens.cornelsen@ib-cornelsen.de", "Jens Cornelsen");
$mail->isHTML(true); // $mail->isHTML(true);
$mail->Subject = "{$nummer_response["voucherNumber"]} - {$_POST["Angebotsbezeichnung"]}"; // $mail->Subject = "{$nummer_response["voucherNumber"]} - {$_POST["Angebotsbezeichnung"]}";
// carriage return type (RFC) // // carriage return type (RFC)
$eol = "<br>"; // $eol = "<br>";
$anrede = "Sehr geehrte" . ($_POST["anrede"] == "Herr" ? "r " : " ") . $_POST["anrede"]; // $anrede = "Sehr geehrte" . ($_POST["anrede"] == "Herr" ? "r " : " ") . $_POST["anrede"];
$message = "$anrede {$_POST["name"]},{$eol}{$eol}"; // $message = "$anrede {$_POST["name"]},{$eol}{$eol}";
$message .= "vielen Dank für Ihre Anfrage. Im Anhang finden Sie das ausgearbeitete Angebot als PDF-Dokument.{$eol}{$eol}"; // $message .= "vielen Dank für Ihre Anfrage. Im Anhang finden Sie das ausgearbeitete Angebot als PDF-Dokument.{$eol}{$eol}";
$message .= "Mit freundlichen Grüßen,$eol"; // $message .= "Mit freundlichen Grüßen,$eol";
$message .= "Jens Cornelsen$eol"; // $message .= "Jens Cornelsen$eol";
$message .= "--{$eol}IB Cornelsen{$eol}Katendeich 5A{$eol}21035 Hamburg{$eol}{$eol}www.ib-cornelsen.de{$eol}{$eol}Fon 040 209339858{$eol}Fax 040 209339859"; // $message .= "--{$eol}IB Cornelsen{$eol}Katendeich 5A{$eol}21035 Hamburg{$eol}{$eol}www.ib-cornelsen.de{$eol}{$eol}Fon 040 209339858{$eol}Fax 040 209339859";
$mail->Body = $message; // $mail->Body = $message;
$curl_pdf = curl_init(); // $curl_pdf = curl_init();
curl_setopt_array($curl_pdf, [ // curl_setopt_array($curl_pdf, [
CURLOPT_URL: "https://api.lexoffice.io/v1/files/$pdf_id", // CURLOPT_URL: "https://api.lexoffice.io/v1/files/$pdf_id",
CURLOPT_RETURNTRANSFER: true, // CURLOPT_RETURNTRANSFER: true,
CURLOPT_ENCODING: "", // CURLOPT_ENCODING: "",
CURLOPT_MAXREDIRS: 10, // CURLOPT_MAXREDIRS: 10,
CURLOPT_TIMEOUT: 30, // CURLOPT_TIMEOUT: 30,
CURLOPT_HTTP_VERSION: CURL_HTTP_VERSION_1_1, // CURLOPT_HTTP_VERSION: CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST: "GET", // CURLOPT_CUSTOMREQUEST: "GET",
CURLOPT_HTTPHEADER: [ // CURLOPT_HTTPHEADER: [
"Accept: application/pdf", // "Accept: application/pdf",
"Authorization: Bearer " . LEX_OFFICE_API_KEY // "Authorization: Bearer " . LEX_OFFICE_API_KEY
] // ]
]); // ]);
$response = curl_exec($curl_pdf); // $response = curl_exec($curl_pdf);
$err = curl_error($curl_pdf); // $err = curl_error($curl_pdf);
$HOME = dirname($ROOT); // $HOME = dirname($ROOT);
curl_close($curl_pdf); // curl_close($curl_pdf);
$fp = fopen("$HOME/{$PERSISTENT_FOLDER}/angebote/$pdf_id.pdf", "w+"); // $fp = fopen("$HOME/{$PERSISTENT_FOLDER}/angebote/$pdf_id.pdf", "w+");
fwrite($fp, $response); // fwrite($fp, $response);
fclose($fp); // fclose($fp);
$mail->addAttachment("$HOME/{$PERSISTENT_FOLDER}/angebote/$pdf_id.pdf", "Angebot.pdf"); // $mail->addAttachment("$HOME/{$PERSISTENT_FOLDER}/angebote/$pdf_id.pdf", "Angebot.pdf");
$mail->send(); // $mail->send();
echo "Alles wurde abgesendet! Du kannst die Webseite nun verlassen."; // echo "Alles wurde abgesendet! Du kannst die Webseite nun verlassen.";
} }
export async function createLexOfficeCustomer(user: Benutzer) { export async function createLexOfficeCustomer(user: Benutzer) {

View File

@@ -36,6 +36,8 @@
export let unterlagen: Unterlage[] = []; export let unterlagen: Unterlage[] = [];
export let id: string | null; export let id: string | null;
export let partner_code: string;
export let loadFromDatabase: boolean = false; export let loadFromDatabase: boolean = false;
// Wir holen die daten aus dem LocalStorage falls // Wir holen die daten aus dem LocalStorage falls
@@ -143,6 +145,7 @@
bind:unterlagen bind:unterlagen
bind:blockLocalStorageSync bind:blockLocalStorageSync
{ausweisart} {ausweisart}
{partner_code}
showWeiter={false} showWeiter={false}
{form} {form}
{skala} {skala}
@@ -277,6 +280,7 @@
bind:unterlagen bind:unterlagen
bind:blockLocalStorageSync bind:blockLocalStorageSync
{ausweisart} {ausweisart}
{partner_code}
showWeiter={true} showWeiter={true}
{form} {form}
{skala} {skala}

View File

@@ -4,7 +4,7 @@
import Carousel from "#components/Carousel.svelte"; import Carousel from "#components/Carousel.svelte";
import DashboardAusweis from "#components/Dashboard/DashboardAusweis.svelte"; import DashboardAusweis from "#components/Dashboard/DashboardAusweis.svelte";
import DashboardNachweis from "#components/Dashboard/DashboardNachweis.svelte"; import DashboardNachweis from "#components/Dashboard/DashboardNachweis.svelte";
import NotificationProvider from "#components/NotificationProvider/NotificationProvider.svelte"; import NotificationWrapper from "#components/Notifications/NotificationWrapper.svelte";
import { Objekt } from "#lib/client/prisma.js"; import { Objekt } from "#lib/client/prisma.js";
import mime from "mime" import mime from "mime"
import { ChevronLeft, ChevronRight, FileText } from "radix-svelte-icons"; import { ChevronLeft, ChevronRight, FileText } from "radix-svelte-icons";
@@ -96,5 +96,5 @@
</div> </div>
<div class="fixed bottom-8 right-8 flex flex-col gap-4"> <div class="fixed bottom-8 right-8 flex flex-col gap-4">
<NotificationProvider component={AusweisPruefenNotification}></NotificationProvider> <NotificationWrapper></NotificationWrapper>
</div> </div>

View File

@@ -1,83 +0,0 @@
<script lang="ts">
import { BenutzerClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import DashboardAusweis from "#components/Dashboard/DashboardAusweis.svelte";
import DashboardAusweisSkeleton from "#components/Dashboard/DashboardAusweisSkeleton.svelte";
import { verbrauchsausweisWohnenCalculateFormProgress } from "#lib/VerbrauchsausweisWohnen/calculateFormProgress";
import { onMount } from "svelte";
export let user: BenutzerClient;
let ausweise: VerbrauchsausweisWohnenClient[] | null = null;
let ausweisUeberpruefung: ReturnType<typeof verbrauchsausweisWohnenCalculateFormProgress>[] = [];
let errorCount = 0;
onMount(async () => {
ausweise = await client.v1.verbrauchsausweisWohnen.getMany.query({
limit: 10
});
console.log(ausweise);
if (!ausweise) return;
ausweisUeberpruefung = ausweise.map(ausweis => verbrauchsausweisWohnenCalculateFormProgress(ausweis));
errorCount = ausweisUeberpruefung.reduce((acc, { errors }) => acc + errors.length, 0);
})
</script>
{#if errorCount > 0}
<h1 class="text-4xl font-medium my-8">Wichtiges</h1>
<div class="flex flex-row gap-4 overflow-x-auto">
{#each ausweisUeberpruefung as { errors }}
{#if errors.length > 0}
<div class="card w-96 card-bordered bg-base-200 border-base-300">
<div class="card-body">
<div class="badge font-semibold" class:badge-warning={errors[0].severity == "warning"} class:badge-error={errors[0].severity == "error"}>{errors[0].severity == "error" ? "Achtung!" : "Wichtig!"}</div>
<h2 class="card-title">{errors[0].title}</h2>
<p>{errors[0].description}</p>
{#if errors[0].resolvehref}
<div class="card-actions justify-end">
<a class="btn btn-primary" href={errors[0].resolvehref}>Beheben</a>
</div>
{/if}
</div>
</div>
{/if}
{/each}
</div>
{/if}
<h1 class="text-4xl font-medium my-8">Ihre Ausweise</h1>
<div class="grid xl:grid-cols-2 grid-cols-1 gap-4">
{#if ausweise === null}
<DashboardAusweisSkeleton></DashboardAusweisSkeleton>
{:else}
{#if ausweise.length == 0}
<div class="">
<h1 class="text-2xl">Es konnten keine Ausweise gefunden werden.</h1>
<p>Erstellen sie einen Verbrauchsausweis für ihr Wohngebäude <a href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude">hier</a></p>
</div>
{:else}
{#each ausweise as ausweis, i}
<DashboardAusweis progress={ausweisUeberpruefung[i]?.progress || 0} {ausweis}></DashboardAusweis>
{/each}
{/if}
{/if}
</div>
<div class="flex items-center justify-center mt-12">
<div class="join">
<button class="join-item btn btn-ghost shadow-none">1</button>
<button class="join-item btn btn-ghost shadow-none">2</button>
<button class="join-item btn btn-ghost shadow-none">3</button>
<button class="join-item btn btn-ghost shadow-none">4</button>
</div>
</div>

View File

@@ -2,7 +2,6 @@
import "../../style/formular.css"; import "../../style/formular.css";
import { import {
BenutzerClient, BenutzerClient,
ObjektClient,
ObjektKomplettClient, ObjektKomplettClient,
} from "#components/Ausweis/types.js"; } from "#components/Ausweis/types.js";
import DashboardObjekt from "#components/Dashboard/DashboardObjekt.svelte"; import DashboardObjekt from "#components/Dashboard/DashboardObjekt.svelte";
@@ -14,10 +13,7 @@
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js"; import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import Pagination from "#components/Pagination.svelte"; import Pagination from "#components/Pagination.svelte";
import AusweisePruefenFilter from "#components/Dashboard/AusweisePruefenFilter.svelte"; import { Enums, Objekt } from "#lib/client/prisma.js";
import { filterAusweise } from "#lib/filters.js";
import { z, ZodTypeAny } from "zod";
import { Enums } from "#lib/client/prisma.js";
export let user: BenutzerClient; export let user: BenutzerClient;
export let objekte: ObjektKomplettClient[]; export let objekte: ObjektKomplettClient[];
@@ -26,7 +22,7 @@
let objektOverlayHidden = true; let objektOverlayHidden = true;
let objekt: Omit<ObjektClient, "uid"> = { let objekt: Objekt = {
adresse: "", adresse: "",
erstellungsdatum: new Date(), erstellungsdatum: new Date(),
latitude: 0, latitude: 0,
@@ -91,8 +87,6 @@
objekte = objekte objekte = objekte
} }
let filters: { name: keyof z.infer<typeof filterAusweise>, type: ZodTypeAny, value: any }[] = []
export let id: string = ""; export let id: string = "";
</script> </script>

View File

@@ -27,7 +27,7 @@
<span>{user.vorname} {user.name}</span> <span>{user.vorname} {user.name}</span>
<span class="text-xs">{user.email}</span> <span class="text-xs">{user.email}</span>
</div> </div>
<a href="/dashboard/admin/impersonate?uid={user.uid}" class="button text-sm">Einloggen</a> <a href="/dashboard/admin/impersonate?id={user.id}" class="button text-sm">Einloggen</a>
</div> </div>
{/each} {/each}
</div> </div>

View File

@@ -32,6 +32,8 @@
import { getMaximumDevitationInPercent } from "#client/lib/helpers.js"; import { getMaximumDevitationInPercent } from "#client/lib/helpers.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js"; import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js"; import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Client.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Client.js";
export let user: Partial<BenutzerClient>; export let user: Partial<BenutzerClient>;
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen; export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbe | BedarfsausweisWohnen;
@@ -211,7 +213,7 @@
versand_plz: versand_plz, versand_plz: versand_plz,
versand_ort: versand_ort, versand_ort: versand_ort,
telefon: telefon, telefon: telefon,
nachweis_id: result.nachweis_id, nachweis_id: result.nachweis_id
}, },
{ {
headers: { headers: {
@@ -291,7 +293,7 @@
let result: Awaited<ReturnType<typeof ausweisSpeichern>> | Awaited<ReturnType<typeof nachweisSpeichern>> | null = null; let result: Awaited<ReturnType<typeof ausweisSpeichern>> | Awaited<ReturnType<typeof nachweisSpeichern>> | null = null;
if (ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisGewerbe || ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe) { if (ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisGewerbe || ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe) {
result = await nachweisSpeichern(ausweis, objekt, aufnahme, bilder, unterlagen, ausweisart) result = await nachweisSpeichern(ausweis as unknown as GEGNachweisWohnen, objekt, aufnahme, bilder, unterlagen, ausweisart)
} else { } else {
result = await ausweisSpeichern(ausweis, objekt, aufnahme, bilder, unterlagen, ausweisart) result = await ausweisSpeichern(ausweis, objekt, aufnahme, bilder, unterlagen, ausweisart)
} }
@@ -394,33 +396,6 @@
} }
} }
/**
* TODO
* Ausschlusskriterien: Neubau, Modernisierung
Baujahr vor 1978, unsaniert und bis 4 Wohneinheiten /
Heizung jünger als 3 Jahre / Verbrauchsjahre unvollständig / Verbrauchsjahre nicht aktuell genug /
Klimafaktoren unvollständig /
Leerstand größer 30% /
Fehlende oder unvollständige Bilder (pro Abschnitt mindestens ein Bild) /
Fehlende Angaben zum Sanierungsstand (Bei F mindestens 2 Haken), (Bei G mindestens 1 Haken)
*/
let bestellenNichtMoeglich = false;
if (
((ausweis.ausstellgrund === "Neubau" ||
ausweis.ausstellgrund === "Modernisierung") &&
aufnahme.baujahr_gebaeude[0] < 1978 &&
aufnahme.saniert === false &&
aufnahme.einheiten &&
aufnahme.einheiten > 4) ||
new Date().getFullYear() - aufnahme.baujahr_heizung[0] < 3 ||
!ausweis.verbrauch_1 ||
!ausweis.verbrauch_2 ||
!ausweis.verbrauch_3 ||
(aufnahme.leerstand && aufnahme.leerstand > 30)
) {
bestellenNichtMoeglich = true;
}
const gegAnfrage = const gegAnfrage =
ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisWohnen ||
ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe || ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe ||
@@ -924,7 +899,7 @@ grid-cols-3 sm:grid-cols-5 justify-around justify-items-center items-center"
<h3>Bitte untenstehende Punkte bestätigen. Bitte gehen Sie gegebenenfalls zurück zum Formular und überprüfen bzw. korrigieren Ihre Eingaben.</h3> <h3>Bitte untenstehende Punkte bestätigen. Bitte gehen Sie gegebenenfalls zurück zum Formular und überprüfen bzw. korrigieren Ihre Eingaben.</h3>
{#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe} {#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe}
{@const request = ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen ? endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt) : endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt)} {@const request = ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen ? endEnergieVerbrauchVerbrauchsausweis_2016_Client(ausweis, aufnahme, objekt) : endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client(ausweis, aufnahme, objekt)}
{#await request} {#await request}

View File

@@ -49,6 +49,7 @@
export let bilder: BildClient[]; export let bilder: BildClient[];
export let id: string | null; export let id: string | null;
export let partner_code: string;
export let loadFromDatabase: boolean = false; export let loadFromDatabase: boolean = false;
const ausweisart = Enums.Ausweisart.VerbrauchsausweisGewerbe const ausweisart = Enums.Ausweisart.VerbrauchsausweisGewerbe
@@ -128,6 +129,7 @@
ausweisart={Enums.Ausweisart.VerbrauchsausweisGewerbe} ausweisart={Enums.Ausweisart.VerbrauchsausweisGewerbe}
showWeiter={false} showWeiter={false}
{form} {form}
{partner_code}
{skala} {skala}
> >
</ButtonWeiterHilfe> </ButtonWeiterHilfe>
@@ -244,6 +246,7 @@
ausweisart={Enums.Ausweisart.VerbrauchsausweisGewerbe} ausweisart={Enums.Ausweisart.VerbrauchsausweisGewerbe}
showWeiter={true} showWeiter={true}
{form} {form}
{partner_code}
{skala} {skala}
> >
</ButtonWeiterHilfe> </ButtonWeiterHilfe>

View File

@@ -160,6 +160,7 @@ let skala: HTMLDivElement;
bind:aufnahme bind:aufnahme
ausweisart={Enums.Ausweisart.VerbrauchsausweisWohnen} ausweisart={Enums.Ausweisart.VerbrauchsausweisWohnen}
showWeiter={false} showWeiter={false}
{partner_code}
{form} {form}
{skala} {skala}
> >

View File

@@ -1,84 +1,91 @@
--- ---
import AusweisLayout from "#layouts/AusweisLayoutDaten_partner.astro";
import AusweisLayout from "#layouts/AusweisLayoutDaten.astro";
import BedarfsausweisWohnenModule from "#modules/BedarfsausweisWohnen/BedarfsausweisWohnenModule.svelte"; import BedarfsausweisWohnenModule from "#modules/BedarfsausweisWohnen/BedarfsausweisWohnenModule.svelte";
import { AufnahmeClient, ObjektClient, BildClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types"; import { Aufnahme, BedarfsausweisWohnen, Bild, Enums, Objekt } from "#lib/server/prisma";
import { createCaller } from "src/astro-typesafe-api-caller"; import { getAufnahme, getObjekt, getBilder, getBedarfsausweisWohnen } from "#lib/server/db";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants"; import { getCurrentUser } from "#lib/server/user";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import { Enums } from "#lib/server/prisma";
const id = Astro.url.searchParams.get("uid") || ""; const id = Astro.url.searchParams.get("id");
const aufnahme_id = Astro.url.searchParams.get("aufnahme") const aufnahme_id = Astro.url.searchParams.get("aufnahme")
const ausweistyp = Astro.url.searchParams.get("ausweistyp") || Enums.AusweisTyp.Standard; let ausweistyp = Astro.url.searchParams.get("ausweistyp") as Enums.AusweisTyp || Enums.AusweisTyp.Standard;
let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient; const partner_code = Astro.params.partner as string;
let aufnahme: AufnahmeClient = {} as AufnahmeClient;
let objekt: ObjektClient = {} as ObjektClient;
let bilder: BildClient[] = []
const valid = validateAccessTokenServer(Astro); let ausweis: BedarfsausweisWohnen = {} as BedarfsausweisWohnen;
let aufnahme: Aufnahme = {} as Aufnahme;
let objekt: Objekt = {} as Objekt;
let bilder: Bild[] = []
const caller = createCaller(Astro); const user = await getCurrentUser(Astro)
if (id) { if (id) {
if (!valid) { if (!user) {
return Astro.redirect( return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}` `/auth/login?redirect=${Astro.url.toString()}`
); );
} }
try { ausweis = await getBedarfsausweisWohnen(id) as BedarfsausweisWohnen
ausweis = await caller["bedarfsausweis-wohnen"]._id.GET.fetch(null, { ausweistyp = ausweis.ausweistyp;
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
id
}
});
aufnahme = await caller.aufnahme._id.GET.fetch(null, { if (!ausweis || (ausweis.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) {
headers: { // Der Ausweis scheint nicht zu existieren.
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` // Wir leiten auf die generische Ausweisseite ohne ID weiter.
}, return Astro.redirect(
params: { "/energieausweis-erstellen/bedarfsausweis-wohngebaeude"
id: ausweis.aufnahme_id );
} }
})
objekt = await caller.objekt._id.GET.fetch(null, { aufnahme = await getAufnahme(ausweis.aufnahme_id) as Aufnahme
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
id: ausweis.objekt_id
}
})
bilder = await caller.aufnahme._id.bilder.GET.fetch(null, { if (!aufnahme) {
headers: { // Die Aufnahme existiert nicht, das sollte eigentlich nicht passieren aber so können wir nicht fortfahren.
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` return Astro.redirect(
}, "/energieausweis-erstellen/bedarfsausweis-wohngebaeude"
params: { );
id: ausweis.aufnahme_id }
}
})
if (!ausweis) { objekt = await getObjekt(aufnahme.objekt_id) as Objekt
// Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne UID weiter. if (!objekt) {
return Astro.redirect( // Das Objekt existiert nicht, das sollte eigentlich nicht passieren aber so können wir nicht fortfahren.
"/energieausweis-erstellen/bedarfsausweis-wohngebaeude" return Astro.redirect(
); "/energieausweis-erstellen/bedarfsausweis-wohngebaeude"
} );
} catch(e) { }
bilder = await getBilder(aufnahme.id);
} else if (aufnahme_id) {
if (!user) {
return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}`
);
}
aufnahme = await getAufnahme(ausweis.aufnahme_id) as Aufnahme
if (!aufnahme) {
// Die Aufnahme existiert wohl nicht.
return Astro.redirect(
"/energieausweis-erstellen/bedarfsausweis-wohngebaeude"
);
}
objekt = await getObjekt(aufnahme.objekt_id) as Objekt
if (!objekt) {
// Das Objekt existiert nicht.
return Astro.redirect( return Astro.redirect(
"/energieausweis-erstellen/bedarfsausweis-wohngebaeude" "/energieausweis-erstellen/bedarfsausweis-wohngebaeude"
); );
} }
} }
console.log(ausweistyp);
--- ---
<AusweisLayout title="Bedarfsausweis erstellen | IBCornelsen" tabHover3="glow"> <AusweisLayout title="Bedarfsausweis erstellen | IBCornelsen">
<BedarfsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} {ausweistyp} {id}></BedarfsausweisWohnenModule> <BedarfsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} {ausweistyp} {id} {user} loadFromDatabase={id !== null} {partner_code}></BedarfsausweisWohnenModule>
</AusweisLayout> </AusweisLayout>

View File

@@ -1,79 +1,80 @@
--- ---
import AusweisLayout from "#layouts/AusweisLayoutDaten_partner.astro"; import AusweisLayout from "#layouts/AusweisLayoutDaten.astro";
import { AufnahmeClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types"; import { AufnahmeClient, ObjektClient, BildClient, VerbrauchsausweisGewerbeClient } from "#components/Ausweis/types";
import { createCaller } from "src/astro-typesafe-api-caller";
import { inferOutput } from "astro-typesafe-api/client";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import VerbrauchsausweisGewerbeModule from "#modules/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbeModule.svelte"; import VerbrauchsausweisGewerbeModule from "#modules/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbeModule.svelte";
import { Enums } from "#lib/server/prisma"; import { Aufnahme, Enums, Objekt, VerbrauchsausweisGewerbe } from "#lib/server/prisma";
import { getAufnahme, getObjekt, getBilder, getVerbrauchsausweisGewerbe } from "#lib/server/db";
import { getCurrentUser } from "#lib/server/user";
const uid = Astro.url.searchParams.get("uid"); const id = Astro.url.searchParams.get("id");
const ausweistyp = Astro.url.searchParams.get("ausweistyp") || Enums.AusweisTyp.Standard; const aufnahme_id = Astro.url.searchParams.get("aufnahme")
let ausweistyp = Astro.url.searchParams.get("ausweistyp") as Enums.AusweisTyp || Enums.AusweisTyp.Standard;
const partner_code = Astro.params.partner as string;
let ausweis: VerbrauchsausweisGewerbeClient = {} as VerbrauchsausweisGewerbeClient; let ausweis: VerbrauchsausweisGewerbeClient = {} as VerbrauchsausweisGewerbeClient;
let aufnahme: AufnahmeClient = {} as AufnahmeClient; let aufnahme: AufnahmeClient = {} as AufnahmeClient;
let objekt: ObjektClient = {} as ObjektClient; let objekt: ObjektClient = {} as ObjektClient;
let bilder: UploadedGebaeudeBild[] = [] let bilder: BildClient[] = []
const valid = validateAccessTokenServer(Astro); const user = await getCurrentUser(Astro)
const caller = createCaller(Astro); if (id) {
if (!user) {
if (uid) {
if (!valid) {
return Astro.redirect( return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}` `/auth/login?redirect=${Astro.url.toString()}`
); );
} }
try { ausweis = await getVerbrauchsausweisGewerbe(id) as VerbrauchsausweisGewerbe
let { uid_aufnahme, uid_objekt, uid_benutzer, ...result } = await caller["verbrauchsausweis-gewerbe"]._uid.GET.fetch(null, { ausweistyp = ausweis.ausweistyp;
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid
}
});
ausweis = result if (!ausweis || (ausweis.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) {
// Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne ID weiter.
return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-gewerbe"
);
}
aufnahme = await caller.aufnahme._uid.GET.fetch(null, { aufnahme = await getAufnahme(ausweis.aufnahme_id) as Aufnahme
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid: uid_aufnahme
}
})
objekt = await caller.objekt._uid.GET.fetch(null, { if (!aufnahme) {
headers: { // Die Aufnahme existiert nicht, das sollte eigentlich nicht passieren aber so können wir nicht fortfahren.
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` return Astro.redirect(
}, "/energieausweis-erstellen/verbrauchsausweis-gewerbe"
params: { );
uid: uid_objekt }
}
})
bilder = await caller.aufnahme._uid.bilder.GET.fetch(null, { objekt = await getObjekt(aufnahme.objekt_id) as Objekt
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid: uid_aufnahme
}
})
if (!ausweis) { if (!objekt) {
// Der Ausweis scheint nicht zu existieren. // Das Objekt existiert nicht, das sollte eigentlich nicht passieren aber so können wir nicht fortfahren.
// Wir leiten auf die generische Ausweisseite ohne UID weiter. return Astro.redirect(
return Astro.redirect( "/energieausweis-erstellen/verbrauchsausweis-gewerbe"
"/energieausweis-erstellen/verbrauchsausweis-gewerbe" );
); }
}
} catch(e) { bilder = await getBilder(aufnahme.id);
} else if (aufnahme_id) {
if (!user) {
return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}`
);
}
aufnahme = await getAufnahme(ausweis.aufnahme_id) as Aufnahme
if (!aufnahme) {
// Die Aufnahme existiert wohl nicht.
return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-gewerbe"
);
}
objekt = await getObjekt(aufnahme.objekt_id) as Objekt
if (!objekt) {
// Das Objekt existiert nicht.
return Astro.redirect( return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-gewerbe" "/energieausweis-erstellen/verbrauchsausweis-gewerbe"
); );
@@ -81,6 +82,6 @@ if (uid) {
} }
--- ---
<AusweisLayout title="Verbrauchsausweis Gewerbe erstellen | IBCornelsen" tabHover2="glow"> <AusweisLayout title="Verbrauchsausweis Gewerbe erstellen | IBCornelsen">
<VerbrauchsausweisGewerbeModule client:only {ausweis} {objekt} {aufnahme} {bilder} {ausweistyp}/> <VerbrauchsausweisGewerbeModule client:only {ausweis} {objekt} {aufnahme} {bilder} {ausweistyp} {user} {id} {partner_code} loadFromDatabase={id !== null}/>
</AusweisLayout> </AusweisLayout>

View File

@@ -1,77 +1,79 @@
--- ---
import AusweisLayout from "#layouts/AusweisLayoutDaten_partner.astro"; import AusweisLayout from "#layouts/AusweisLayoutDaten_partner.astro";
import VerbrauchsausweisWohnenModule from "#modules/VerbrauchsausweisWohnen/VerbrauchsausweisWohnenModule.svelte"; import VerbrauchsausweisWohnenModule from "#modules/VerbrauchsausweisWohnen/VerbrauchsausweisWohnenModule.svelte";
import { AufnahmeClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types"; import { Aufnahme, Bild, Enums, Objekt, VerbrauchsausweisWohnen } from "#lib/server/prisma";
import { createCaller } from "src/astro-typesafe-api-caller"; import { getVerbrauchsausweisWohnen, getAufnahme, getObjekt, getBilder } from "#lib/server/db";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants"; import { getCurrentUser } from "#lib/server/user";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import { Enums } from "#lib/server/prisma";
const uid = Astro.url.searchParams.get("uid"); const id = Astro.url.searchParams.get("id");
const ausweistyp = Astro.url.searchParams.get("ausweistyp") || Enums.AusweisTyp.Standard; const aufnahme_id = Astro.url.searchParams.get("aufnahme")
let ausweistyp = Astro.url.searchParams.get("ausweistyp") as Enums.AusweisTyp || Enums.AusweisTyp.Standard;
const partner_code = Astro.params.partner as string;
let ausweis: VerbrauchsausweisWohnen = {} as VerbrauchsausweisWohnen;
let aufnahme: Aufnahme = {} as Aufnahme;
let objekt: Objekt = {} as Objekt;
let bilder: Bild[] = []
let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient; const user = await getCurrentUser(Astro)
let aufnahme: AufnahmeClient = {} as AufnahmeClient;
let objekt: ObjektClient = {} as ObjektClient;
let bilder: UploadedGebaeudeBild[] = []
const valid = validateAccessTokenServer(Astro); if (id) {
if (!user) {
const caller = createCaller(Astro);
if (uid) {
if (!valid) {
return Astro.redirect( return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}` `/auth/login?redirect=${Astro.url.toString()}`
); );
} }
try { ausweis = await getVerbrauchsausweisWohnen(id) as VerbrauchsausweisWohnen
ausweis = await caller["verbrauchsausweis-wohnen"]._uid.GET.fetch(null, { ausweistyp = ausweis.ausweistyp;
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid
}
});
aufnahme = await caller.aufnahme._uid.GET.fetch(null, { if (!ausweis || (ausweis.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) {
headers: { // Der Ausweis scheint nicht zu existieren.
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` // Wir leiten auf die generische Ausweisseite ohne ID weiter.
}, return Astro.redirect(
params: { "/energieausweis-erstellen/verbrauchsausweis-wohngebaeude"
uid: ausweis.uid_aufnahme );
} }
})
objekt = await caller.objekt._uid.GET.fetch(null, { aufnahme = await getAufnahme(ausweis.aufnahme_id) as Aufnahme
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid: ausweis.uid_objekt
}
})
bilder = await caller.aufnahme._uid.bilder.GET.fetch(null, { if (!aufnahme) {
headers: { // Die Aufnahme existiert nicht, das sollte eigentlich nicht passieren aber so können wir nicht fortfahren.
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}` return Astro.redirect(
}, "/energieausweis-erstellen/verbrauchsausweis-wohngebaeude"
params: { );
uid: ausweis.uid_aufnahme }
}
})
if (!ausweis) { objekt = await getObjekt(aufnahme.objekt_id) as Objekt
// Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne UID weiter. if (!objekt) {
return Astro.redirect( // Das Objekt existiert nicht, das sollte eigentlich nicht passieren aber so können wir nicht fortfahren.
"/energieausweis-erstellen/verbrauchsausweis-wohngebaeude" return Astro.redirect(
); "/energieausweis-erstellen/verbrauchsausweis-wohngebaeude"
} );
} catch(e) { }
bilder = await getBilder(aufnahme.id);
} else if (aufnahme_id) {
if (!user) {
return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}`
);
}
aufnahme = await getAufnahme(ausweis.aufnahme_id) as Aufnahme
if (!aufnahme) {
// Die Aufnahme existiert wohl nicht.
return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-wohngebaeude"
);
}
objekt = await getObjekt(aufnahme.objekt_id) as Objekt
if (!objekt) {
// Das Objekt existiert nicht.
return Astro.redirect( return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-wohngebaeude" "/energieausweis-erstellen/verbrauchsausweis-wohngebaeude"
); );
@@ -81,5 +83,5 @@ if (uid) {
--- ---
<AusweisLayout title="Verbrauchsausweis erstellen" tabHover1="glow"> <AusweisLayout title="Verbrauchsausweis erstellen" tabHover1="glow">
<VerbrauchsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} {ausweistyp} /> <VerbrauchsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} {id} {ausweistyp} {user} {partner_code} loadFromDatabase={id !== null} />
</AusweisLayout> </AusweisLayout>

View File

@@ -18,6 +18,13 @@ import { BASE_URI } from "#lib/constants.js";
import { getAnsichtsausweis, getDatenblatt } from "#lib/server/ausweis.js"; import { getAnsichtsausweis, getDatenblatt } from "#lib/server/ausweis.js";
import { PutObjectCommand } from "@aws-sdk/client-s3"; import { PutObjectCommand } from "@aws-sdk/client-s3";
import { s3Client } from "#lib/s3.js"; import { s3Client } from "#lib/s3.js";
import { createInvoice } from "#lib/server/invoice.js";
import { tryCatch } from "#lib/tryCatch.js";
import {
getBedarfsausweisWohnenKomplett,
getVerbrauchsausweisGewerbeKomplett,
getVerbrauchsausweisWohnenKomplett,
} from "#lib/server/db.js";
export const GET = defineApiRoute({ export const GET = defineApiRoute({
input: z.object({ input: z.object({
@@ -37,66 +44,18 @@ export const GET = defineApiRoute({
aufnahme: Aufnahme & { aufnahme: Aufnahme & {
bilder: Bild[]; bilder: Bild[];
objekt: Objekt & { objekt: Objekt & {
benutzer: Benutzer; benutzer: Benutzer | null;
}; };
}; };
}) })
| null = null; | null = null;
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) { if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
ausweis = await prisma.verbrauchsausweisWohnen.findUnique({ ausweis = await getVerbrauchsausweisWohnenKomplett(id_ausweis);
where: {
id: id_ausweis,
},
include: {
aufnahme: {
include: {
bilder: true,
objekt: {
include: {
benutzer: true,
},
},
},
},
},
});
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) { } else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
ausweis = await prisma.verbrauchsausweisGewerbe.findUnique({ ausweis = await getVerbrauchsausweisGewerbeKomplett(id_ausweis);
where: {
id: id_ausweis,
},
include: {
aufnahme: {
include: {
bilder: true,
objekt: {
include: {
benutzer: true,
},
},
},
},
},
});
} else if (ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) { } else if (ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) {
ausweis = await prisma.bedarfsausweisWohnen.findUnique({ ausweis = await getBedarfsausweisWohnenKomplett(id_ausweis);
where: {
id: id_ausweis,
},
include: {
aufnahme: {
include: {
bilder: true,
objekt: {
include: {
benutzer: true,
},
},
},
},
},
});
} }
if (!ausweis) { if (!ausweis) {
@@ -125,34 +84,34 @@ export const GET = defineApiRoute({
}); });
} }
// TODO if (!rechnung.lex_office_id) {
// SECTION: Rechnung erstellen (LexOffice) const [result, error] = await tryCatch(
// Wir wollen die Rechnung an lex office versenden, und uns die ID von da holen. createInvoice(ausweis, rechnung)
// Falls die Rechnung bereits existiert ist das nicht nötig. );
// if (!$rechnung->lex_office_id) {
// [$lex_office_id, $renr] = createInvoice($ausweis, $rechnung);
// sleep(1); // TODO: Nach der Umstellung von LexOffice auf etwas anderes MUSS das hier unbedingt entfernt werden!
// if (!$lex_office_id || !$renr) { if (error) {
// die("Bei der Erstellung der Rechnung ist etwas schiefgelaufen - Möglicherweise ist etwas mit LexOffice?"); return;
// } }
// $rechnung->lex_office_id = $lex_office_id; const { id, voucherNumber } = result;
// $rechnung->rechnungsnummer = $renr;
// $rechnung->save();
// }
// TODO await prisma.rechnung.update({
// if ($ausweis->erledigt != 2) {$ausweis->erstellungsdatum = date("Y-m-d H:i:s");} where: {
// $ausweis->erledigt = 2; id: rechnung.id,
// $ausweis->save(); },
data: {
lex_office_id: id,
},
});
}
const pdfAusweis = await getAnsichtsausweis( const pdfAusweis = await getAnsichtsausweis(
ausweis, ausweis,
ausweis.aufnahme, ausweis.aufnahme,
ausweis.aufnahme.objekt, ausweis.aufnahme.objekt,
ausweis.aufnahme.bilder, ausweis.aufnahme.bilder,
ausweis.aufnahme.objekt.benutzer ausweis.aufnahme.objekt.benutzer,
false
); );
const pdfDatenblatt = await getDatenblatt( const pdfDatenblatt = await getDatenblatt(
ausweis, ausweis,
@@ -170,18 +129,18 @@ export const GET = defineApiRoute({
ACL: "private", ACL: "private",
}); });
const response = await s3Client.send(command); await s3Client.send(command);
} }
if (pdfDatenblatt) { if (pdfDatenblatt) {
const command = new PutObjectCommand({ const command = new PutObjectCommand({
Bucket: "ibc-pdfs", Bucket: "ibc-pdfs",
Key: `ID_${ausweis.id}_Energieausweis.pdf`, Key: `ID_${ausweis.id}_Datenblatt.pdf`,
Body: pdfDatenblatt, Body: pdfDatenblatt,
ACL: "private", ACL: "private",
}); });
const response = await s3Client.send(command); await s3Client.send(command);
} }
let text: string; let text: string;
@@ -273,5 +232,34 @@ fax 040 · 209339859
subject: `Ihr Originalausweis vom Ingenieurbüro Cornelsen (ID: ${ausweis.id})`, subject: `Ihr Originalausweis vom Ingenieurbüro Cornelsen (ID: ${ausweis.id})`,
text, text,
}); });
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
await prisma.verbrauchsausweisWohnen.update({
where: {
id: ausweis.id,
},
data: {
ausgestellt: true,
},
});
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
await prisma.verbrauchsausweisGewerbe.update({
where: {
id: ausweis.id,
},
data: {
ausgestellt: true,
},
});
} else if (ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) {
await prisma.bedarfsausweisWohnen.update({
where: {
id: ausweis.id,
},
data: {
ausgestellt: true,
},
});
}
}, },
}); });

View File

@@ -7,10 +7,7 @@ import {
authorizationHeaders, authorizationHeaders,
} from "#lib/middleware/authorization.js"; } from "#lib/middleware/authorization.js";
import { import {
BedarfsausweisWohnen,
Enums, Enums,
VerbrauchsausweisGewerbe,
VerbrauchsausweisWohnen,
} from "#lib/server/prisma.js"; } from "#lib/server/prisma.js";
import { prisma } from "#lib/server/prisma.js"; import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { APIError, defineApiRoute } from "astro-typesafe-api/server";
@@ -21,14 +18,14 @@ import { getPrismaAusweisAdapter } from "#lib/server/ausweis.js";
export const GET = defineApiRoute({ export const GET = defineApiRoute({
input: z.object({ input: z.object({
uid: UUidWithPrefix, id: UUidWithPrefix,
}), }),
headers: authorizationHeaders, headers: authorizationHeaders,
middleware: adminMiddleware, middleware: adminMiddleware,
async fetch({ uid }, context, user) { async fetch({ id }, context, user) {
const ausweisart = getAusweisartFromId(uid); const ausweisart = getAusweisartFromId(id);
const adapter = getPrismaAusweisAdapter( const adapter = getPrismaAusweisAdapter(
uid id
) as typeof prisma.verbrauchsausweisWohnen; ) as typeof prisma.verbrauchsausweisWohnen;
if (!adapter) { if (!adapter) {
@@ -40,7 +37,7 @@ export const GET = defineApiRoute({
const ausweis = await adapter.findUnique({ const ausweis = await adapter.findUnique({
where: { where: {
uid, id,
}, },
include: { include: {
aufnahme: { aufnahme: {
@@ -125,32 +122,27 @@ export const GET = defineApiRoute({
? "Energiebedarfsausweis" ? "Energiebedarfsausweis"
: "Energieverbrauchsausweis"; : "Energieverbrauchsausweis";
const body = `<Datenregistratur xmlns="http://energieausweis.dibt.de/WebServiceEnergie/DibtEnergieAusweisService"> const requestPayload = {
<doc> doc: {
<root> root: {
<Authentifizierung> Authentifizierung: {
<Aussteller_ID_DIBT>${Aussteller_ID_DIBT}</Aussteller_ID_DIBT> Aussteller_ID_DIBT: Aussteller_ID_DIBT,
<Aussteller_PWD_DIBT>${Aussteller_PWD_DIBT}</Aussteller_PWD_DIBT> Aussteller_PWD_DIBT: Aussteller_PWD_DIBT,
</Authentifizierung> },
<EnEV-Nachweis> 'EnEV-Nachweis': {
<Ausstellungsdatum>${Ausstellungsdatum}</Ausstellungsdatum> Ausstellungsdatum: Ausstellungsdatum,
<Bundesland>${postleitzahl.bundesland}</Bundesland> Bundesland: postleitzahl.bundesland,
<Postleitzahl>${postleitzahl.plz}</Postleitzahl> Postleitzahl: postleitzahl.plz,
<Gesetzesgrundlage>${Gesetzesgrundlage}</Gesetzesgrundlage> Gesetzesgrundlage: Gesetzesgrundlage,
</EnEV-Nachweis> },
<Energieausweis-Daten> 'Energieausweis-Daten': {
<Gebaeudeart>${gebaeudeart}</Gebaeudeart> Gebaeudeart: gebaeudeart,
<Art>${art}</Art> Art: art,
<Neubau>${ Neubau: ausweis.ausstellgrund === Enums.Ausstellgrund.Neubau ? "1" : "0",
ausweis.ausstellgrund === },
Enums.Ausstellgrund.Neubau },
? "1" },
: "0" }
}</Neubau>
</Energieausweis-Daten>
</root>
</doc>
</Datenregistratur>`;
return await new Promise(async (resolve, reject) => { return await new Promise(async (resolve, reject) => {
soap.createClient( soap.createClient(
@@ -165,7 +157,7 @@ export const GET = defineApiRoute({
} }
client.Datenregistratur( client.Datenregistratur(
body, requestPayload,
async function ( async function (
err: any, err: any,
result: { result: {
@@ -193,7 +185,7 @@ export const GET = defineApiRoute({
adapter as typeof prisma.verbrauchsausweisWohnen adapter as typeof prisma.verbrauchsausweisWohnen
).update({ ).update({
where: { where: {
uid, id,
}, },
data: { data: {
registriernummer: registriernummer:

View File

@@ -1,4 +1,4 @@
import { GEGNachweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js"; import { UUidWithPrefix } from "#components/Ausweis/types.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { generatePrefixedId } from "#lib/db.js"; import { generatePrefixedId } from "#lib/db.js";
import { exclude } from "#lib/exclude.js"; import { exclude } from "#lib/exclude.js";
@@ -19,7 +19,8 @@ export const PATCH = defineApiRoute({
rechnung_id: true, rechnung_id: true,
storniert: true, storniert: true,
updated_at: true, updated_at: true,
zurueckgestellt: true zurueckgestellt: true,
ausweisart: true
}), }),
output: z.void(), output: z.void(),
headers: { headers: {

View File

@@ -25,7 +25,8 @@ export const PUT = defineApiRoute({
rechnung_id: true, rechnung_id: true,
storniert: true, storniert: true,
updated_at: true, updated_at: true,
zurueckgestellt: true zurueckgestellt: true,
ausweisart: true
}), }),
aufnahme_id: UUidWithPrefix aufnahme_id: UUidWithPrefix
}), }),

View File

@@ -1,9 +1,9 @@
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, VerbrauchsausweisWohnenClient, ZodOverlap } from "#components/Ausweis/types.js"; import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { generatePrefixedId } from "#lib/db.js"; import { generatePrefixedId } from "#lib/db.js";
import { exclude } from "#lib/exclude.js"; import { exclude } from "#lib/exclude.js";
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js"; import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { BedarfsausweisWohnen, prisma } from "#lib/server/prisma.js"; import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { BedarfsausweisWohnenSchema } from "src/generated/zod/bedarfsausweiswohnen.js"; import { BedarfsausweisWohnenSchema } from "src/generated/zod/bedarfsausweiswohnen.js";
import { z } from "zod"; import { z } from "zod";
@@ -19,7 +19,8 @@ export const PATCH = defineApiRoute({
zurueckgestellt: true, zurueckgestellt: true,
created_at: true, created_at: true,
updated_at: true, updated_at: true,
storniert: true storniert: true,
ausweisart: true
}), }),
output: z.void(), output: z.void(),
headers: { headers: {

View File

@@ -29,6 +29,7 @@ export const PUT = defineApiRoute({
created_at: true, created_at: true,
updated_at: true, updated_at: true,
storniert: true, storniert: true,
ausweisart: true
}), }),
aufnahme_id: UUidWithPrefix, aufnahme_id: UUidWithPrefix,
}), }),

View File

@@ -1,4 +1,4 @@
import { GEGNachweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js"; import { UUidWithPrefix } from "#components/Ausweis/types.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { generatePrefixedId } from "#lib/db.js"; import { generatePrefixedId } from "#lib/db.js";
import { exclude } from "#lib/exclude.js"; import { exclude } from "#lib/exclude.js";
@@ -19,7 +19,8 @@ export const PATCH = defineApiRoute({
rechnung_id: true, rechnung_id: true,
storniert: true, storniert: true,
updated_at: true, updated_at: true,
zurueckgestellt: true zurueckgestellt: true,
ausweisart: true
}), }),
output: z.void(), output: z.void(),
headers: { headers: {

View File

@@ -25,7 +25,8 @@ export const PUT = defineApiRoute({
rechnung_id: true, rechnung_id: true,
storniert: true, storniert: true,
updated_at: true, updated_at: true,
zurueckgestellt: true zurueckgestellt: true,
ausweisart: true
}), }),
aufnahme_id: UUidWithPrefix aufnahme_id: UUidWithPrefix
}), }),

View File

@@ -19,7 +19,8 @@ export const PATCH = defineApiRoute({
rechnung_id: true, rechnung_id: true,
storniert: true, storniert: true,
updated_at: true, updated_at: true,
zurueckgestellt: true zurueckgestellt: true,
ausweisart: true
}), }),
output: z.void(), output: z.void(),
headers: { headers: {

View File

@@ -25,7 +25,8 @@ export const PUT = defineApiRoute({
rechnung_id: true, rechnung_id: true,
storniert: true, storniert: true,
updated_at: true, updated_at: true,
zurueckgestellt: true zurueckgestellt: true,
ausweisart: true
}), }),
aufnahme_id: UUidWithPrefix aufnahme_id: UUidWithPrefix
}), }),

View File

@@ -52,9 +52,6 @@ export const PUT = defineApiRoute({
}) })
} }
console.log(nachweis);
if (!nachweis || nachweis.benutzer_id !== user.id) { if (!nachweis || nachweis.benutzer_id !== user.id) {
throw new APIError({ throw new APIError({
code: "BAD_REQUEST", code: "BAD_REQUEST",

View File

@@ -101,6 +101,19 @@ export const PUT = defineApiRoute({
betrag, betrag,
bezahlmethode: bezahlmethode, bezahlmethode: bezahlmethode,
status: Enums.Rechnungsstatus.open, status: Enums.Rechnungsstatus.open,
abweichende_versand_adresse: input.abweichende_versand_adresse,
email: input.email,
empfaenger: input.empfaenger,
ort: input.ort,
plz: input.plz,
strasse: input.strasse,
telefon: input.telefon,
versand_ort: input.versand_ort,
versand_empfaenger: input.versand_empfaenger,
versand_plz: input.versand_plz,
versand_strasse: input.versand_strasse,
versand_zusatzzeile: input.versand_zusatzzeile,
zusatzzeile: input.zusatzzeile,
verbrauchsausweis_wohnen: { verbrauchsausweis_wohnen: {
connect: { connect: {
id: ausweis_id id: ausweis_id
@@ -118,6 +131,19 @@ export const PUT = defineApiRoute({
betrag, betrag,
bezahlmethode: bezahlmethode, bezahlmethode: bezahlmethode,
status: Enums.Rechnungsstatus.open, status: Enums.Rechnungsstatus.open,
abweichende_versand_adresse: input.abweichende_versand_adresse,
email: input.email,
empfaenger: input.empfaenger,
ort: input.ort,
plz: input.plz,
strasse: input.strasse,
telefon: input.telefon,
versand_ort: input.versand_ort,
versand_empfaenger: input.versand_empfaenger,
versand_plz: input.versand_plz,
versand_strasse: input.versand_strasse,
versand_zusatzzeile: input.versand_zusatzzeile,
zusatzzeile: input.zusatzzeile,
verbrauchsausweis_gewerbe: { verbrauchsausweis_gewerbe: {
connect: { connect: {
id: ausweis_id id: ausweis_id
@@ -135,6 +161,19 @@ export const PUT = defineApiRoute({
betrag, betrag,
bezahlmethode: bezahlmethode, bezahlmethode: bezahlmethode,
status: Enums.Rechnungsstatus.open, status: Enums.Rechnungsstatus.open,
abweichende_versand_adresse: input.abweichende_versand_adresse,
email: input.email,
empfaenger: input.empfaenger,
ort: input.ort,
plz: input.plz,
strasse: input.strasse,
telefon: input.telefon,
versand_ort: input.versand_ort,
versand_empfaenger: input.versand_empfaenger,
versand_plz: input.versand_plz,
versand_strasse: input.versand_strasse,
versand_zusatzzeile: input.versand_zusatzzeile,
zusatzzeile: input.zusatzzeile,
bedarfsausweis_wohnen: { bedarfsausweis_wohnen: {
connect: { connect: {
id: ausweis_id id: ausweis_id
@@ -178,7 +217,7 @@ export const PUT = defineApiRoute({
method: input.bezahlmethode as PaymentMethod, method: input.bezahlmethode as PaymentMethod,
description: "Verbrauchsausweis Wohnen 2016", description: "Verbrauchsausweis Wohnen 2016",
redirectUrl: `https://online-energieausweis.org/payment/success?a=${ausweis.id}&r=${rechnung.id}`, redirectUrl: `https://online-energieausweis.org/payment/success?a=${ausweis.id}&r=${rechnung.id}`,
webhookUrl: `https://online-energieausweis.org/api/webhooks/mollie?uid=${rechnung.id}`, webhookUrl: `https://online-energieausweis.org/api/webhooks/mollie`,
cancelUrl: `https://online-energieausweis.org/kundendaten?a=${ausweis.id}&r=${rechnung.id}` cancelUrl: `https://online-energieausweis.org/kundendaten?a=${ausweis.id}&r=${rechnung.id}`
}); });

View File

@@ -3,6 +3,7 @@ import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { generatePrefixedId } from "#lib/db.js"; import { generatePrefixedId } from "#lib/db.js";
import { adminMiddleware, authorizationMiddleware } from "#lib/middleware/authorization.js"; import { adminMiddleware, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { hashPassword } from "#lib/password.js"; import { hashPassword } from "#lib/password.js";
import { createLexOfficeCustomer } from "#lib/server/lexoffice.js";
import { sendRegisterMail } from "#lib/server/mail/registrierung.js"; import { sendRegisterMail } from "#lib/server/mail/registrierung.js";
import { prisma } from "#lib/server/prisma.js"; import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { APIError, defineApiRoute } from "astro-typesafe-api/server";
@@ -117,6 +118,17 @@ export const PUT = defineApiRoute({
} }
}) })
const lex_office_id = await createLexOfficeCustomer(user);
await prisma.benutzer.update({
where: {
id: user.id
},
data: {
lex_office_id
}
})
await sendRegisterMail(user) await sendRegisterMail(user)
return { id } return { id }

View File

@@ -14,7 +14,8 @@ export const PATCH = defineApiRoute({
benutzer_id: true, benutzer_id: true,
aufnahme_id: true, aufnahme_id: true,
updated_at: true, updated_at: true,
created_at: true created_at: true,
ausweisart: true
}).merge(z.object({ }).merge(z.object({
startdatum: z.coerce.date().nullable(), startdatum: z.coerce.date().nullable(),
})), })),

View File

@@ -21,7 +21,8 @@ export const PUT = defineApiRoute({
aufnahme_id: true, aufnahme_id: true,
rechnung_id: true, rechnung_id: true,
updated_at: true, updated_at: true,
created_at: true created_at: true,
ausweisart: true
}).merge(z.object({ }).merge(z.object({
startdatum: z.coerce.date().nullable() startdatum: z.coerce.date().nullable()
})), })),

View File

@@ -15,7 +15,8 @@ export const PATCH = defineApiRoute({
aufnahme_id: true, aufnahme_id: true,
rechnung_id: true, rechnung_id: true,
created_at: true, created_at: true,
updated_at: true updated_at: true,
ausweisart: true
}).merge(z.object({ }).merge(z.object({
startdatum: z.coerce.date().nullable() startdatum: z.coerce.date().nullable()
})), })),

View File

@@ -26,7 +26,8 @@ export const PUT = defineApiRoute({
aufnahme_id: true, aufnahme_id: true,
rechnung_id: true, rechnung_id: true,
created_at: true, created_at: true,
updated_at: true updated_at: true,
ausweisart: true
}), }),
aufnahme_id: UUidWithPrefix aufnahme_id: UUidWithPrefix
}), }),

View File

@@ -19,7 +19,7 @@ export const POST = defineApiRoute({
// Wir holen uns die Transaktion von Mollie. // Wir holen uns die Transaktion von Mollie.
const payment = await mollieClient.payments.get(id); const payment = await mollieClient.payments.get(id);
const metadata = payment.metadata as { rechnung_uid: string } const metadata = payment.metadata as { rechnung_id: string }
if (!payment) { if (!payment) {
throw new APIError({ throw new APIError({
@@ -28,7 +28,7 @@ export const POST = defineApiRoute({
}); });
} }
if (!metadata.rechnung_uid) { if (!metadata.rechnung_id) {
throw new APIError({ throw new APIError({
code: "BAD_REQUEST", code: "BAD_REQUEST",
message: "Rechnung UID nicht gefunden.", message: "Rechnung UID nicht gefunden.",
@@ -38,7 +38,7 @@ export const POST = defineApiRoute({
// Wir holen uns die Rechnung aus unserer Datenbank. // Wir holen uns die Rechnung aus unserer Datenbank.
const rechnung = await prisma.rechnung.findUnique({ const rechnung = await prisma.rechnung.findUnique({
where: { where: {
uid: metadata.rechnung_uid, id: metadata.rechnung_id,
}, },
}); });
@@ -57,6 +57,7 @@ export const POST = defineApiRoute({
data: { data: {
status: payment.status as Enums.Rechnungsstatus, status: payment.status as Enums.Rechnungsstatus,
transaktions_referenz: payment.id, transaktions_referenz: payment.id,
bezahlt_am: new Date()
}, },
}); });
}, },

View File

@@ -10,7 +10,6 @@ import ImpersonateUserModule from "#modules/ImpersonateUserModule.svelte";
const caller = createCaller(Astro) const caller = createCaller(Astro)
const params = Astro.params; const params = Astro.params;
const page = Number(params.page)
const user = await caller.user.self.GET.fetch(undefined, { const user = await caller.user.self.GET.fetch(undefined, {
headers: { headers: {

View File

@@ -22,15 +22,15 @@ if (user.rolle !== Enums.BenutzerRolle.ADMIN) {
return Astro.redirect("/dashboard") return Astro.redirect("/dashboard")
} }
const uid = Astro.url.searchParams.get("uid") const id = Astro.url.searchParams.get("id")
if (!uid) { if (!id) {
return Astro.redirect("/404") return Astro.redirect("/404")
} }
const searchedUser = await prisma.benutzer.findUnique({ const searchedUser = await prisma.benutzer.findUnique({
where: { where: {
uid id
} }
}) })
@@ -40,12 +40,12 @@ if (!searchedUser) {
const refreshTokenExpiry = moment().add(30, "days"); const refreshTokenExpiry = moment().add(30, "days");
const accessToken = encodeToken({ const accessToken = encodeToken({
uid: searchedUser.uid, id: searchedUser.id,
typ: TokenType.Access, typ: TokenType.Access,
exp: moment().add(30, "minutes").valueOf(), exp: moment().add(30, "minutes").valueOf(),
}); });
const refreshToken = encodeToken({ const refreshToken = encodeToken({
uid: searchedUser.uid, id: searchedUser.id,
typ: TokenType.Refresh, typ: TokenType.Refresh,
exp: refreshTokenExpiry.valueOf(), exp: refreshTokenExpiry.valueOf(),
}); });
@@ -60,7 +60,6 @@ Astro.cookies.set(API_ACCESS_TOKEN_COOKIE_NAME, accessToken, {
path: "/", path: "/",
expires: moment().add(30, "minutes").toDate() expires: moment().add(30, "minutes").toDate()
}) })
Astro.cookies.set("uid", searchedUser.uid)
return Astro.redirect("/dashboard") return Astro.redirect("/dashboard")
--- ---

View File

@@ -1,21 +0,0 @@
---
import UserLayout from "#layouts/DashboardLayout.astro";
import DashboardAusweiseModule from "#modules/Dashboard/DashboardAusweiseModule.svelte";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import { createCaller } from "src/astro-typesafe-api-caller";
const accessTokenValid = await validateAccessTokenServer(Astro);
if (!accessTokenValid) {
return Astro.redirect("/auth/login")
}
const caller = createCaller(Astro);
const user = await caller.v1.benutzer.self();
---
<UserLayout title="Dashboard">
<DashboardAusweiseModule user={user} client:load></DashboardAusweiseModule>
</UserLayout>

View File

@@ -1,23 +1,15 @@
--- ---
import UserLayout from "#layouts/DashboardLayout.astro"; import UserLayout from "#layouts/DashboardLayout.astro";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
import { Enums, prisma } from "#lib/server/prisma"; import { Enums, prisma } from "#lib/server/prisma";
import { createCaller } from "src/astro-typesafe-api-caller";
import DashboardModule from "#modules/Dashboard/DashboardModule.svelte"; import DashboardModule from "#modules/Dashboard/DashboardModule.svelte";
import { getCurrentUser } from "#lib/server/user";
const caller = createCaller(Astro)
const params = Astro.params; const params = Astro.params;
const page = Number(params.page) const page = Number(params.page)
const id = Astro.url.searchParams.get("id") || undefined; const id = Astro.url.searchParams.get("id") || undefined;
const user = await getCurrentUser(Astro)
const user = await caller.user.self.GET.fetch(undefined, {
headers: {
"Authorization": `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
}
});
if (!user) { if (!user) {
return Astro.redirect("/auth/login") return Astro.redirect("/auth/login")

View File

@@ -27,7 +27,7 @@ if (id) {
ausweis = await getBedarfsausweisWohnen(id) as BedarfsausweisWohnen ausweis = await getBedarfsausweisWohnen(id) as BedarfsausweisWohnen
ausweistyp = ausweis.ausweistyp; ausweistyp = ausweis.ausweistyp;
if (!ausweis || ausweis.benutzer_id !== user.id) { if (!ausweis || (ausweis.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) {
// Der Ausweis scheint nicht zu existieren. // Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne ID weiter. // Wir leiten auf die generische Ausweisseite ohne ID weiter.
return Astro.redirect( return Astro.redirect(

View File

@@ -27,7 +27,7 @@ if (id) {
ausweis = await getVerbrauchsausweisGewerbe(id) as VerbrauchsausweisGewerbe ausweis = await getVerbrauchsausweisGewerbe(id) as VerbrauchsausweisGewerbe
ausweistyp = ausweis.ausweistyp; ausweistyp = ausweis.ausweistyp;
if (!ausweis || ausweis.benutzer_id !== user.id) { if (!ausweis || (ausweis.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) {
// Der Ausweis scheint nicht zu existieren. // Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne ID weiter. // Wir leiten auf die generische Ausweisseite ohne ID weiter.
return Astro.redirect( return Astro.redirect(

View File

@@ -1,7 +1,6 @@
--- ---
import AusweisLayout from "#layouts/AusweisLayoutDaten.astro"; import AusweisLayout from "#layouts/AusweisLayoutDaten.astro";
import VerbrauchsausweisWohnenModule from "#modules/VerbrauchsausweisWohnen/VerbrauchsausweisWohnenModule.svelte"; import VerbrauchsausweisWohnenModule from "#modules/VerbrauchsausweisWohnen/VerbrauchsausweisWohnenModule.svelte";
import { AufnahmeClient, BildClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
import { Aufnahme, Bild, Enums, Objekt, VerbrauchsausweisWohnen } from "#lib/server/prisma"; import { Aufnahme, Bild, Enums, Objekt, VerbrauchsausweisWohnen } from "#lib/server/prisma";
import { getAufnahme, getBilder, getObjekt, getVerbrauchsausweisWohnen } from "#lib/server/db"; import { getAufnahme, getBilder, getObjekt, getVerbrauchsausweisWohnen } from "#lib/server/db";
import { getCurrentUser } from "#lib/server/user"; import { getCurrentUser } from "#lib/server/user";
@@ -27,7 +26,7 @@ if (id) {
ausweis = await getVerbrauchsausweisWohnen(id) as VerbrauchsausweisWohnen ausweis = await getVerbrauchsausweisWohnen(id) as VerbrauchsausweisWohnen
ausweistyp = ausweis.ausweistyp; ausweistyp = ausweis.ausweistyp;
if (!ausweis || ausweis.benutzer_id !== user.id) { if (!ausweis || (ausweis.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) {
// Der Ausweis scheint nicht zu existieren. // Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne ID weiter. // Wir leiten auf die generische Ausweisseite ohne ID weiter.
return Astro.redirect( return Astro.redirect(
@@ -82,5 +81,5 @@ if (id) {
--- ---
<AusweisLayout title="Verbrauchsausweis erstellen"> <AusweisLayout title="Verbrauchsausweis erstellen">
<VerbrauchsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} {id} {ausweistyp} {user} loadFromDatabase={id !== null} /> <VerbrauchsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} {id} {ausweistyp} {user} loadFromDatabase={id !== null} partner_code="" />
</AusweisLayout> </AusweisLayout>