Datenbank und ID Generierung

This commit is contained in:
Moritz Utcke
2025-04-07 15:33:30 -04:00
parent 32d8e2383e
commit 2abb143cfe
66 changed files with 906 additions and 6309 deletions

4
.gitignore vendored
View File

@@ -35,3 +35,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/users.csv
src/testing/rechnungen.csv

View File

@@ -1,4 +1,4 @@
.PHONY: dev online-energieausweis all prod backup run-database build-database install-dependencies wait-for-database prod database prisma-studio .PHONY: dev online-energieausweis all prod backup run-database build-database install-dependencies wait-for-database prod database prisma-studio backup-database-cronjob
DB_CONTAINER_NAME := database DB_CONTAINER_NAME := database
DB_NAME := main DB_NAME := main
@@ -57,10 +57,15 @@ all:
mkdir -p ~/logs mkdir -p ~/logs
bun run dev 2>&1 | tee ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log bun run dev 2>&1 | tee ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log
prod: install-dependencies prisma-studio prod: install-dependencies prisma-studio backup-database-cronjob
bun run build bun run build
mkdir -p ~/logs mkdir -p ~/logs
mkdir -p ~/persistent/online-energieausweis mkdir -p ~/persistent/online-energieausweis
- pm2 delete online-energieausweis - pm2 delete online-energieausweis
NODE_ENV="production" pm2 start --name "online-energieausweis" --update-env --log ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log --time bun -- run ./server.ts NODE_ENV="production" pm2 start --name "online-energieausweis" --update-env --log ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log --time bun -- run ./server.ts
pm2 save
backup-database-cronjob:
- pm2 delete daily-db-backup
pm2 start backup-database.bash --name "daily-db-backup" --cron "0 0 * * *"

17
backup-database.bash Normal file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
FILE_NAME=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_dumpall -c -U main | brotli --best > $FILE_NAME
# Das wird benötigt für AWS Ionos Kompatibilität.
export AWS_REQUEST_CHECKSUM_CALCULATION=when_required
export AWS_RESPONSE_CHECKSUM_VALIDATION=when_required
# IMPORTANT: Dieser Befehl benötigt das `ionos` Profil, sonst wird er nicht funktionieren.
# 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
aws s3 cp $FILE_NAME s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD
# Wir entfernen das Backup
rm $FILE_NAME

View File

@@ -1,2 +0,0 @@
-- AlterTable
ALTER TABLE "VerbrauchsausweisGewerbe" ALTER COLUMN "stromverbrauch_enthaelt_sonstige" SET DATA TYPE VARCHAR(255);

View File

@@ -1,2 +0,0 @@
-- AlterTable
ALTER TABLE "Rechnung" ADD COLUMN "lex_office_id" TEXT;

View File

@@ -1,2 +0,0 @@
-- DropIndex
DROP INDEX "Rechnung_transaktions_referenz_key";

View File

@@ -39,7 +39,7 @@ CREATE TYPE "Service" AS ENUM ('Telefonberatung', 'Aushang', 'Qualitaetsdruck',
-- CreateTable -- CreateTable
CREATE TABLE "Anteilshaber" ( CREATE TABLE "Anteilshaber" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"rolle" VARCHAR, "rolle" VARCHAR,
"privilegien" BIGINT, "privilegien" BIGINT,
"benutzer_id" TEXT NOT NULL, "benutzer_id" TEXT NOT NULL,
@@ -50,7 +50,7 @@ CREATE TABLE "Anteilshaber" (
-- CreateTable -- CreateTable
CREATE TABLE "ApiRequests" ( CREATE TABLE "ApiRequests" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"date" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, "date" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"ip" VARCHAR(50) NOT NULL, "ip" VARCHAR(50) NOT NULL,
"method" VARCHAR(10) NOT NULL, "method" VARCHAR(10) NOT NULL,
@@ -66,7 +66,7 @@ CREATE TABLE "ApiRequests" (
-- CreateTable -- CreateTable
CREATE TABLE "Aufnahme" ( CREATE TABLE "Aufnahme" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"benutzer_id" TEXT, "benutzer_id" TEXT,
"gebaeudetyp" VARCHAR, "gebaeudetyp" VARCHAR,
"gebaeudeteil" VARCHAR, "gebaeudeteil" VARCHAR,
@@ -124,7 +124,7 @@ CREATE TABLE "Aufnahme" (
-- CreateTable -- CreateTable
CREATE TABLE "BedarfsausweisGewerbe" ( CREATE TABLE "BedarfsausweisGewerbe" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"ausstellgrund" "Ausstellgrund", "ausstellgrund" "Ausstellgrund",
"keller_beheizt" BOOLEAN, "keller_beheizt" BOOLEAN,
"storniert" BOOLEAN DEFAULT false, "storniert" BOOLEAN DEFAULT false,
@@ -154,7 +154,8 @@ CREATE TABLE "BedarfsausweisGewerbe" (
-- CreateTable -- CreateTable
CREATE TABLE "BedarfsausweisWohnen" ( CREATE TABLE "BedarfsausweisWohnen" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"alte_ausweis_id" INTEGER,
"benutzer_id" TEXT, "benutzer_id" TEXT,
"ausstellgrund" "Ausstellgrund", "ausstellgrund" "Ausstellgrund",
"registriernummer" VARCHAR, "registriernummer" VARCHAR,
@@ -245,7 +246,8 @@ CREATE TABLE "BedarfsausweisWohnen" (
-- CreateTable -- CreateTable
CREATE TABLE "benutzer" ( CREATE TABLE "benutzer" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"alte_id" INTEGER,
"name" VARCHAR(100), "name" VARCHAR(100),
"vorname" VARCHAR(50), "vorname" VARCHAR(50),
"email" VARCHAR(255) NOT NULL, "email" VARCHAR(255) NOT NULL,
@@ -266,7 +268,7 @@ CREATE TABLE "benutzer" (
-- CreateTable -- CreateTable
CREATE TABLE "Bild" ( CREATE TABLE "Bild" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"kategorie" "BilderKategorie" NOT NULL, "kategorie" "BilderKategorie" NOT NULL,
"name" TEXT NOT NULL, "name" TEXT NOT NULL,
"aufnahme_id" TEXT, "aufnahme_id" TEXT,
@@ -276,7 +278,7 @@ CREATE TABLE "Bild" (
-- CreateTable -- CreateTable
CREATE TABLE "Event" ( CREATE TABLE "Event" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"date" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, "date" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"title" VARCHAR(255) NOT NULL, "title" VARCHAR(255) NOT NULL,
"description" TEXT, "description" TEXT,
@@ -288,7 +290,7 @@ CREATE TABLE "Event" (
-- CreateTable -- CreateTable
CREATE TABLE "GEGEinpreisung" ( CREATE TABLE "GEGEinpreisung" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"empfaenger" VARCHAR, "empfaenger" VARCHAR,
"strasse" VARCHAR, "strasse" VARCHAR,
"plz" VARCHAR, "plz" VARCHAR,
@@ -310,7 +312,7 @@ CREATE TABLE "GEGEinpreisung" (
-- CreateTable -- CreateTable
CREATE TABLE "GEGNachweisGewerbe" ( CREATE TABLE "GEGNachweisGewerbe" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"ausstellgrund" "Ausstellgrund", "ausstellgrund" "Ausstellgrund",
"keller_beheizt" BOOLEAN, "keller_beheizt" BOOLEAN,
"storniert" BOOLEAN DEFAULT false, "storniert" BOOLEAN DEFAULT false,
@@ -330,7 +332,7 @@ CREATE TABLE "GEGNachweisGewerbe" (
-- CreateTable -- CreateTable
CREATE TABLE "GEGNachweisWohnen" ( CREATE TABLE "GEGNachweisWohnen" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"ausstellgrund" "Ausstellgrund", "ausstellgrund" "Ausstellgrund",
"keller_beheizt" BOOLEAN, "keller_beheizt" BOOLEAN,
"storniert" BOOLEAN DEFAULT false, "storniert" BOOLEAN DEFAULT false,
@@ -361,7 +363,7 @@ CREATE TABLE "Klimafaktoren" (
-- CreateTable -- CreateTable
CREATE TABLE "Objekt" ( CREATE TABLE "Objekt" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"latitude" DOUBLE PRECISION, "latitude" DOUBLE PRECISION,
"longitude" DOUBLE PRECISION, "longitude" DOUBLE PRECISION,
"plz" VARCHAR(5), "plz" VARCHAR(5),
@@ -388,7 +390,8 @@ CREATE TABLE "Postleitzahlen" (
-- CreateTable -- CreateTable
CREATE TABLE "Rechnung" ( CREATE TABLE "Rechnung" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"alte_id" INTEGER,
"empfaenger" VARCHAR, "empfaenger" VARCHAR,
"strasse" VARCHAR, "strasse" VARCHAR,
"plz" VARCHAR, "plz" VARCHAR,
@@ -411,6 +414,7 @@ CREATE TABLE "Rechnung" (
"storniert_am" TIMESTAMP(3), "storniert_am" TIMESTAMP(3),
"transaktions_referenz" VARCHAR, "transaktions_referenz" VARCHAR,
"partner_code" TEXT, "partner_code" TEXT,
"lex_office_id" TEXT,
"benutzer_id" TEXT NOT NULL, "benutzer_id" TEXT NOT NULL,
CONSTRAINT "Rechnung_pkey" PRIMARY KEY ("id") CONSTRAINT "Rechnung_pkey" PRIMARY KEY ("id")
@@ -429,7 +433,7 @@ CREATE TABLE "RefreshTokens" (
-- CreateTable -- CreateTable
CREATE TABLE "Tickets" ( CREATE TABLE "Tickets" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3), "updated_at" TIMESTAMP(3),
"deleted_at" TIMESTAMP(3), "deleted_at" TIMESTAMP(3),
@@ -447,7 +451,7 @@ CREATE TABLE "Tickets" (
-- CreateTable -- CreateTable
CREATE TABLE "Unterlage" ( CREATE TABLE "Unterlage" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"name" TEXT, "name" TEXT,
"kategorie" TEXT, "kategorie" TEXT,
"mime" TEXT NOT NULL, "mime" TEXT NOT NULL,
@@ -458,7 +462,8 @@ CREATE TABLE "Unterlage" (
-- CreateTable -- CreateTable
CREATE TABLE "VerbrauchsausweisGewerbe" ( CREATE TABLE "VerbrauchsausweisGewerbe" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"alte_ausweis_id" INTEGER,
"ausstellgrund" "Ausstellgrund", "ausstellgrund" "Ausstellgrund",
"registriernummer" VARCHAR, "registriernummer" VARCHAR,
"zusaetzliche_heizquelle" BOOLEAN, "zusaetzliche_heizquelle" BOOLEAN,
@@ -484,7 +489,7 @@ CREATE TABLE "VerbrauchsausweisGewerbe" (
"stromverbrauch_enthaelt_lueftung" BOOLEAN, "stromverbrauch_enthaelt_lueftung" BOOLEAN,
"stromverbrauch_enthaelt_beleuchtung" BOOLEAN, "stromverbrauch_enthaelt_beleuchtung" BOOLEAN,
"stromverbrauch_enthaelt_kuehlung" BOOLEAN, "stromverbrauch_enthaelt_kuehlung" BOOLEAN,
"stromverbrauch_enthaelt_sonstige" VARCHAR(50), "stromverbrauch_enthaelt_sonstige" VARCHAR(255),
"kuehlung_enthalten" BOOLEAN, "kuehlung_enthalten" BOOLEAN,
"anteil_kuehlung_1" DOUBLE PRECISION, "anteil_kuehlung_1" DOUBLE PRECISION,
"anteil_kuehlung_2" DOUBLE PRECISION, "anteil_kuehlung_2" DOUBLE PRECISION,
@@ -530,7 +535,8 @@ CREATE TABLE "VerbrauchsausweisGewerbe" (
-- CreateTable -- CreateTable
CREATE TABLE "VerbrauchsausweisWohnen" ( CREATE TABLE "VerbrauchsausweisWohnen" (
"id" VARCHAR(10) NOT NULL, "id" VARCHAR(11) NOT NULL,
"alte_ausweis_id" INTEGER,
"ausstellgrund" "Ausstellgrund", "ausstellgrund" "Ausstellgrund",
"registriernummer" VARCHAR, "registriernummer" VARCHAR,
"zusaetzliche_heizquelle" BOOLEAN, "zusaetzliche_heizquelle" BOOLEAN,
@@ -705,9 +711,6 @@ CREATE UNIQUE INDEX "Objekt_id_key" ON "Objekt"("id");
-- CreateIndex -- CreateIndex
CREATE UNIQUE INDEX "Rechnung_id_key" ON "Rechnung"("id"); CREATE UNIQUE INDEX "Rechnung_id_key" ON "Rechnung"("id");
-- CreateIndex
CREATE UNIQUE INDEX "Rechnung_transaktions_referenz_key" ON "Rechnung"("transaktions_referenz");
-- CreateIndex -- CreateIndex
CREATE UNIQUE INDEX "RefreshTokens_token_key" ON "RefreshTokens"("token"); CREATE UNIQUE INDEX "RefreshTokens_token_key" ON "RefreshTokens"("token");

View File

@@ -0,0 +1,14 @@
/*
Warnings:
- Added the required column `updated_at` to the `Rechnung` table without a default value. This is not possible if the table is not empty.
- Added the required column `updated_at` to the `benutzer` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Rechnung" ADD COLUMN "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updated_at" TIMESTAMP(3) NOT NULL;
-- AlterTable
ALTER TABLE "benutzer" ADD COLUMN "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updated_at" TIMESTAMP(3) NOT NULL;

View File

@@ -0,0 +1,9 @@
/*
Warnings:
- Added the required column `updated_at` to the `Bild` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Bild" ADD COLUMN "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updated_at" TIMESTAMP(3) NOT NULL;

View File

@@ -1,5 +1,5 @@
model Anteilshaber { model Anteilshaber {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
rolle String? @db.VarChar rolle String? @db.VarChar
privilegien BigInt? privilegien BigInt?

View File

@@ -1,6 +1,6 @@
model ApiRequests { model ApiRequests {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
date DateTime @default(now()) @db.Timestamp(6) date DateTime @default(now()) @db.Timestamp(6)
ip String @db.VarChar(50) ip String @db.VarChar(50)
method String @db.VarChar(10) method String @db.VarChar(10)

View File

@@ -13,7 +13,7 @@ enum Lueftungskonzept {
} }
model Aufnahme { model Aufnahme {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
benutzer_id String? benutzer_id String?
benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction) benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
/// @zod.describe("Art des Gebäudes und seiner primären Nutzungsart") /// @zod.describe("Art des Gebäudes und seiner primären Nutzungsart")

View File

@@ -1,5 +1,5 @@
model BedarfsausweisGewerbe { model BedarfsausweisGewerbe {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
/// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf") /// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf")
ausstellgrund Ausstellgrund? ausstellgrund Ausstellgrund?

View File

@@ -1,6 +1,7 @@
model BedarfsausweisWohnen { model BedarfsausweisWohnen {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
alte_ausweis_id Int?
benutzer_id String? benutzer_id String?
ausstellgrund Ausstellgrund? ausstellgrund Ausstellgrund?
registriernummer String? @db.VarChar registriernummer String? @db.VarChar

View File

@@ -5,7 +5,8 @@ enum BenutzerRolle {
} }
model Benutzer { model Benutzer {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
alte_id Int?
name String? @db.VarChar(100) name String? @db.VarChar(100)
vorname String? @db.VarChar(50) vorname String? @db.VarChar(50)
email String @unique(map: "benutzer_email_idx") @db.VarChar(255) email String @unique(map: "benutzer_email_idx") @db.VarChar(255)
@@ -40,6 +41,8 @@ model Benutzer {
geg_nachweise_wohnen GEGNachweisWohnen[] geg_nachweise_wohnen GEGNachweisWohnen[]
bedarfsausweise_gewerbe BedarfsausweisGewerbe[] bedarfsausweise_gewerbe BedarfsausweisGewerbe[]
created_at DateTime @default(now())
updated_at DateTime @updatedAt
ErstellteTickets Tickets[] @relation("ErstellteTickets") ErstellteTickets Tickets[] @relation("ErstellteTickets")

View File

@@ -8,10 +8,13 @@ enum BilderKategorie {
} }
model Bild { model Bild {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
kategorie BilderKategorie kategorie BilderKategorie
name String name String
created_at DateTime @default(now())
updated_at DateTime @updatedAt
aufnahme_id String? aufnahme_id String?
aufnahme Aufnahme? @relation(fields: [aufnahme_id], references: [id], onDelete: NoAction, onUpdate: NoAction) aufnahme Aufnahme? @relation(fields: [aufnahme_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
} }

View File

@@ -3,7 +3,7 @@
// Hier werden beispielsweise Events wie "Nachricht Verschickt" gespeichert. // Hier werden beispielsweise Events wie "Nachricht Verschickt" gespeichert.
// Diese Events werden dann in der Admin-Oberfläche angezeigt. // Diese Events werden dann in der Admin-Oberfläche angezeigt.
model Event { model Event {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
date DateTime @default(now()) @db.Timestamp(6) date DateTime @default(now()) @db.Timestamp(6)
title String @db.VarChar(255) title String @db.VarChar(255)

View File

@@ -6,7 +6,7 @@ enum Einpreisungsstatus {
} }
model GEGEinpreisung { model GEGEinpreisung {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
empfaenger String? @db.VarChar empfaenger String? @db.VarChar
strasse String? @db.VarChar strasse String? @db.VarChar

View File

@@ -1,5 +1,5 @@
model GEGNachweisGewerbe { model GEGNachweisGewerbe {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
/// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf") /// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf")
ausstellgrund Ausstellgrund? ausstellgrund Ausstellgrund?

View File

@@ -1,5 +1,5 @@
model GEGNachweisWohnen { model GEGNachweisWohnen {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
/// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf") /// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf")
ausstellgrund Ausstellgrund? ausstellgrund Ausstellgrund?

View File

@@ -1,5 +1,5 @@
model Objekt { model Objekt {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
latitude Float? latitude Float?
longitude Float? longitude Float?

View File

@@ -27,7 +27,8 @@ enum AusweisTyp {
} }
model Rechnung { model Rechnung {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
alte_id Int?
empfaenger String? @db.VarChar empfaenger String? @db.VarChar
strasse String? @db.VarChar strasse String? @db.VarChar
@@ -55,6 +56,9 @@ model Rechnung {
partner_code String? partner_code String?
lex_office_id String? lex_office_id String?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
benutzer_id String benutzer_id String
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

@@ -8,7 +8,7 @@ enum TicketStatus {
} }
model Tickets { model Tickets {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
created_at DateTime @default(now()) created_at DateTime @default(now())
updated_at DateTime? @updatedAt updated_at DateTime? @updatedAt
deleted_at DateTime? deleted_at DateTime?

View File

@@ -5,7 +5,7 @@ enum UnterlagenKategorie {
} }
model Unterlage { model Unterlage {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
name String? name String?
kategorie String? kategorie String?
mime String mime String

View File

@@ -1,6 +1,7 @@
model VerbrauchsausweisGewerbe { model VerbrauchsausweisGewerbe {
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
alte_ausweis_id Int?
ausstellgrund Ausstellgrund? ausstellgrund Ausstellgrund?
registriernummer String? @db.VarChar registriernummer String? @db.VarChar
zusaetzliche_heizquelle Boolean? zusaetzliche_heizquelle Boolean?

View File

@@ -1,7 +1,8 @@
model VerbrauchsausweisWohnen { model VerbrauchsausweisWohnen {
/// @zod.describe("ID des Ausweises") /// @zod.describe("ID des Ausweises")
id String @id @unique @db.VarChar(10) id String @id @unique @db.VarChar(11)
alte_ausweis_id Int?
/// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf") /// @zod.describe("Ausstellgrund wie z.B. Vermietung oder Verkauf")
ausstellgrund Ausstellgrund? ausstellgrund Ausstellgrund?
/// @zod.describe("Die Registriernummer des Ausweises") /// @zod.describe("Die Registriernummer des Ausweises")

View File

@@ -12,12 +12,11 @@ export const createCaller = createCallerFactory({
"admin/post-ausstellen": await import("../src/pages/api/admin/post-ausstellen.ts"), "admin/post-ausstellen": await import("../src/pages/api/admin/post-ausstellen.ts"),
"admin/registriernummer": await import("../src/pages/api/admin/registriernummer.ts"), "admin/registriernummer": await import("../src/pages/api/admin/registriernummer.ts"),
"admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"), "admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"),
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
"bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"),
"bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"),
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"), "auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
"auth/passwort-vergessen": await import("../src/pages/api/auth/passwort-vergessen.ts"), "auth/passwort-vergessen": await import("../src/pages/api/auth/passwort-vergessen.ts"),
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"), "auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
"ausweise": await import("../src/pages/api/ausweise/index.ts"),
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
"bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"), "bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"),
"bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"), "bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"),
"bedarfsausweis-wohnen/[id]": await import("../src/pages/api/bedarfsausweis-wohnen/[id].ts"), "bedarfsausweis-wohnen/[id]": await import("../src/pages/api/bedarfsausweis-wohnen/[id].ts"),
@@ -28,16 +27,16 @@ export const createCaller = createCallerFactory({
"geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"), "geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"),
"geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"), "geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"),
"objekt": await import("../src/pages/api/objekt/index.ts"), "objekt": await import("../src/pages/api/objekt/index.ts"),
"ticket": await import("../src/pages/api/ticket/index.ts"),
"user": await import("../src/pages/api/user/index.ts"),
"user/self": await import("../src/pages/api/user/self.ts"),
"verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"),
"verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"),
"rechnung/[id]": await import("../src/pages/api/rechnung/[id].ts"), "rechnung/[id]": await import("../src/pages/api/rechnung/[id].ts"),
"rechnung/anfordern": await import("../src/pages/api/rechnung/anfordern.ts"), "rechnung/anfordern": await import("../src/pages/api/rechnung/anfordern.ts"),
"rechnung": await import("../src/pages/api/rechnung/index.ts"), "rechnung": await import("../src/pages/api/rechnung/index.ts"),
"ticket": await import("../src/pages/api/ticket/index.ts"),
"user": await import("../src/pages/api/user/index.ts"),
"user/self": await import("../src/pages/api/user/self.ts"),
"verbrauchsausweis-gewerbe/[id]": await import("../src/pages/api/verbrauchsausweis-gewerbe/[id].ts"), "verbrauchsausweis-gewerbe/[id]": await import("../src/pages/api/verbrauchsausweis-gewerbe/[id].ts"),
"verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.ts"), "verbrauchsausweis-gewerbe": await import("../src/pages/api/verbrauchsausweis-gewerbe/index.ts"),
"verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"),
"verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"),
"webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"), "webhooks/mollie": await import("../src/pages/api/webhooks/mollie.ts"),
"aufnahme/[id]/bilder": await import("../src/pages/api/aufnahme/[id]/bilder.ts"), "aufnahme/[id]/bilder": await import("../src/pages/api/aufnahme/[id]/bilder.ts"),
"aufnahme/[id]": await import("../src/pages/api/aufnahme/[id]/index.ts"), "aufnahme/[id]": await import("../src/pages/api/aufnahme/[id]/index.ts"),

View File

@@ -45,7 +45,7 @@ export const AufnahmeSchema = z.object({
isolier_verglasung: z.boolean().describe("Falls die Fenster des Gebäudes isolier Verglasung haben, sollte dieser Wert auf true stehen").nullish(), isolier_verglasung: z.boolean().describe("Falls die Fenster des Gebäudes isolier Verglasung haben, sollte dieser Wert auf true stehen").nullish(),
tueren_undicht: z.boolean().describe("Falls die Türen des Gebäudes undicht sind, sollte dieser Wert auf true stehen").nullish(), tueren_undicht: z.boolean().describe("Falls die Türen des Gebäudes undicht sind, sollte dieser Wert auf true stehen").nullish(),
tueren_dicht: z.boolean().describe("Falls die Türen des Gebäudes dicht sind, sollte dieser Wert auf true stehen").nullish(), tueren_dicht: z.boolean().describe("Falls die Türen des Gebäudes dicht sind, sollte dieser Wert auf true stehen").nullish(),
dachgeschoss_gedaemmt: z.boolean().describe("Falls das Dachgeschoss des Gebäudes gedämmt ist, sollte dieser Wert auf true stehen").nullish(), dachgeschoss_gedaemmt: z.boolean().describe("Falls das Dachgeschoss des Gebäudes ged<EFBFBD><EFBFBD>mmt ist, sollte dieser Wert auf true stehen").nullish(),
keller_decke_gedaemmt: z.boolean().describe("Falls die Kellerdecke des Gebäudes gedämmt ist, sollte dieser Wert auf true stehen").nullish(), keller_decke_gedaemmt: z.boolean().describe("Falls die Kellerdecke des Gebäudes gedämmt ist, sollte dieser Wert auf true stehen").nullish(),
keller_wand_gedaemmt: z.boolean().describe("Falls die Kellerwände des Gebäudes gedämmt sind, sollte dieser Wert auf true stehen").nullish(), keller_wand_gedaemmt: z.boolean().describe("Falls die Kellerwände des Gebäudes gedämmt sind, sollte dieser Wert auf true stehen").nullish(),
aussenwand_gedaemmt: z.boolean().describe("Falls die Außenwände des Gebäudes gedämmt sind, sollte dieser Wert auf true stehen").nullish(), aussenwand_gedaemmt: z.boolean().describe("Falls die Außenwände des Gebäudes gedämmt sind, sollte dieser Wert auf true stehen").nullish(),

View File

@@ -3,6 +3,7 @@ import { Ausstellgrund, AusweisTyp } from "@prisma/client"
export const BedarfsausweisWohnenSchema = z.object({ export const BedarfsausweisWohnenSchema = z.object({
id: z.string(), id: z.string(),
alte_ausweis_id: z.number().int().nullish(),
benutzer_id: z.string().nullish(), benutzer_id: z.string().nullish(),
ausstellgrund: z.nativeEnum(Ausstellgrund).nullish(), ausstellgrund: z.nativeEnum(Ausstellgrund).nullish(),
registriernummer: z.string().nullish(), registriernummer: z.string().nullish(),

View File

@@ -3,6 +3,7 @@ import { BenutzerRolle } from "@prisma/client"
export const BenutzerSchema = z.object({ export const BenutzerSchema = z.object({
id: z.string(), id: z.string(),
alte_id: z.number().int().nullish(),
name: z.string().nullish(), name: z.string().nullish(),
vorname: z.string().nullish(), vorname: z.string().nullish(),
email: z.string(), email: z.string(),
@@ -17,4 +18,6 @@ export const BenutzerSchema = z.object({
firma: z.string().nullish(), firma: z.string().nullish(),
lex_office_id: z.string().nullish(), lex_office_id: z.string().nullish(),
verified: z.boolean(), verified: z.boolean(),
created_at: z.date(),
updated_at: z.date(),
}) })

View File

@@ -5,5 +5,7 @@ export const BildSchema = z.object({
id: z.string(), id: z.string(),
kategorie: z.nativeEnum(BilderKategorie), kategorie: z.nativeEnum(BilderKategorie),
name: z.string(), name: z.string(),
created_at: z.date(),
updated_at: z.date(),
aufnahme_id: z.string().nullish(), aufnahme_id: z.string().nullish(),
}) })

View File

@@ -3,6 +3,7 @@ import { Bezahlmethoden, Rechnungsstatus, Service } from "@prisma/client"
export const RechnungSchema = z.object({ export const RechnungSchema = z.object({
id: z.string(), id: z.string(),
alte_id: z.number().int().nullish(),
empfaenger: z.string().nullish(), empfaenger: z.string().nullish(),
strasse: z.string().nullish(), strasse: z.string().nullish(),
plz: z.string().nullish(), plz: z.string().nullish(),
@@ -26,5 +27,7 @@ export const RechnungSchema = z.object({
transaktions_referenz: z.string().nullish(), transaktions_referenz: z.string().nullish(),
partner_code: z.string().nullish(), partner_code: z.string().nullish(),
lex_office_id: z.string().nullish(), lex_office_id: z.string().nullish(),
created_at: z.date(),
updated_at: z.date(),
benutzer_id: z.string(), benutzer_id: z.string(),
}) })

View File

@@ -3,6 +3,7 @@ import { Ausstellgrund, AusweisTyp } from "@prisma/client"
export const VerbrauchsausweisGewerbeSchema = z.object({ export const VerbrauchsausweisGewerbeSchema = z.object({
id: z.string(), id: z.string(),
alte_ausweis_id: z.number().int().nullish(),
ausstellgrund: z.nativeEnum(Ausstellgrund).nullish(), ausstellgrund: z.nativeEnum(Ausstellgrund).nullish(),
registriernummer: z.string().nullish(), registriernummer: z.string().nullish(),
zusaetzliche_heizquelle: z.boolean().nullish(), zusaetzliche_heizquelle: z.boolean().nullish(),

View File

@@ -3,6 +3,7 @@ import { Ausstellgrund, AusweisTyp } 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"),
alte_ausweis_id: z.number().int().nullish(),
ausstellgrund: z.nativeEnum(Ausstellgrund).describe("Ausstellgrund wie z.B. Vermietung oder Verkauf").nullish(), ausstellgrund: z.nativeEnum(Ausstellgrund).describe("Ausstellgrund wie z.B. Vermietung oder Verkauf").nullish(),
registriernummer: z.string().describe("Die Registriernummer des Ausweises").nullish(), registriernummer: z.string().describe("Die Registriernummer des Ausweises").nullish(),
zusaetzliche_heizquelle: z.boolean().describe("Falls eine sekundäre Heizquelle existiert, sollte dieser Wert auf true stehen").nullish(), zusaetzliche_heizquelle: z.boolean().describe("Falls eine sekundäre Heizquelle existiert, sollte dieser Wert auf true stehen").nullish(),

View File

@@ -140,7 +140,7 @@ export async function endEnergieVerbrauchVerbrauchsausweis_2016(
} }
let durchschnittsKlimafaktor = let durchschnittsKlimafaktor =
(klimafaktoren[0].klimafaktor + klimafaktoren[1].klimafaktor + klimafaktoren[2].klimafaktor) / 3 || 1; ((klimafaktoren[0].klimafaktor + klimafaktoren[1].klimafaktor + klimafaktoren[2].klimafaktor) / 3) || 1;
let energieVerbrauchHeizungBereinigt_1 = let energieVerbrauchHeizungBereinigt_1 =
energieVerbrauchHeizung_1 * durchschnittsKlimafaktor; energieVerbrauchHeizung_1 * durchschnittsKlimafaktor;

View File

@@ -39,7 +39,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Aufnahme) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Aufnahme)
const aufnahme = await prisma.aufnahme.create({ const aufnahme = await prisma.aufnahme.create({
data: { data: {

View File

@@ -119,7 +119,7 @@ export const DELETE = defineApiRoute({
} }
}) })
const event_id = generatePrefixedId(6, VALID_UUID_PREFIXES.Ticket) const event_id = generatePrefixedId(9, VALID_UUID_PREFIXES.Ticket)
// Wir erstellen ein Event, dass der Nachweis storniert wurde // Wir erstellen ein Event, dass der Nachweis storniert wurde
// Dann können wir das in der Historie anzeigen // Dann können wir das in der Historie anzeigen

View File

@@ -46,7 +46,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.BedarfsausweisGewerbe) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.BedarfsausweisGewerbe)
const nachweis = await prisma.bedarfsausweisGewerbe.create({ const nachweis = await prisma.bedarfsausweisGewerbe.create({
data: { data: {

View File

@@ -122,7 +122,7 @@ export const DELETE = defineApiRoute({
} }
}) })
const event_id = generatePrefixedId(6, VALID_UUID_PREFIXES.Ticket) const event_id = generatePrefixedId(9, VALID_UUID_PREFIXES.Ticket)
// Wir erstellen ein Event, dass der Ausweis storniert wurde // Wir erstellen ein Event, dass der Ausweis storniert wurde
// Dann können wir das in der Historie anzeigen // Dann können wir das in der Historie anzeigen

View File

@@ -37,7 +37,7 @@ export const PUT = defineApiRoute({
); );
const buffer = Buffer.from(dataWithoutPrefix, "base64"); const buffer = Buffer.from(dataWithoutPrefix, "base64");
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Bild) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Bild)
const bild = await prisma.bild.create({ const bild = await prisma.bild.create({
data: { data: {

View File

@@ -120,7 +120,7 @@ export const DELETE = defineApiRoute({
}) })
const event_id = generatePrefixedId(6, VALID_UUID_PREFIXES.Ticket) const event_id = generatePrefixedId(9, VALID_UUID_PREFIXES.Ticket)
// Wir erstellen ein Event, dass der Nachweis storniert wurde // Wir erstellen ein Event, dass der Nachweis storniert wurde
// Dann können wir das in der Historie anzeigen // Dann können wir das in der Historie anzeigen
await prisma.event.create({ await prisma.event.create({

View File

@@ -50,7 +50,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.GEGNachweisGewerbe) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.GEGNachweisGewerbe)
const nachweis = await prisma.gEGNachweisGewerbe.create({ const nachweis = await prisma.gEGNachweisGewerbe.create({
data: { data: {

View File

@@ -125,7 +125,7 @@ export const DELETE = defineApiRoute({
// Dann können wir das in der Historie anzeigen // Dann können wir das in der Historie anzeigen
await prisma.event.create({ await prisma.event.create({
data: { data: {
id: generatePrefixedId(6, VALID_UUID_PREFIXES.Event), id: generatePrefixedId(9, VALID_UUID_PREFIXES.Event),
title: "Nachweis storniert", title: "Nachweis storniert",
description: ((user.rolle === "ADMIN") && (nachweis.benutzer_id !== user.id)) ? "Nachweis wurde von einem Administrator storniert." : "Nachweis wurde vom Besitzer storniert.", description: ((user.rolle === "ADMIN") && (nachweis.benutzer_id !== user.id)) ? "Nachweis wurde von einem Administrator storniert." : "Nachweis wurde vom Besitzer storniert.",
benutzer: { benutzer: {

View File

@@ -50,7 +50,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.GEGNachweisWohnen) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.GEGNachweisWohnen)
const nachweis = await prisma.gEGNachweisWohnen.create({ const nachweis = await prisma.gEGNachweisWohnen.create({
data: { data: {

View File

@@ -17,7 +17,7 @@ export const PUT = defineApiRoute({
}), }),
middleware: authorizationMiddleware, middleware: authorizationMiddleware,
async fetch(input, context, user) { async fetch(input, context, user) {
const id = generatePrefixedId(6, "OB") const id = generatePrefixedId(9, "OB")
console.log(id); console.log(id);

View File

@@ -62,7 +62,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.GEGEinpreisung) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.GEGEinpreisung)
if (ausweisart === Enums.Ausweisart.GEGNachweisWohnen) { if (ausweisart === Enums.Ausweisart.GEGNachweisWohnen) {
einpreisung = await prisma.gEGEinpreisung.create({ einpreisung = await prisma.gEGEinpreisung.create({

View File

@@ -37,6 +37,8 @@ export const PUT = defineApiRoute({
betrag: true, betrag: true,
storniert_am: true, storniert_am: true,
transaktions_referenz: true, transaktions_referenz: true,
created_at: true,
updated_at: true
}) })
), ),
output: z.object({ output: z.object({
@@ -87,7 +89,7 @@ export const PUT = defineApiRoute({
betrag += servicePriceList[service] betrag += servicePriceList[service]
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Rechnung); const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Rechnung);
// Wir erstellen eine neue Rechnung in unserer Datenbank. // Wir erstellen eine neue Rechnung in unserer Datenbank.
let rechnung: Rechnung | null = null; let rechnung: Rechnung | null = null;
@@ -176,7 +178,8 @@ 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: `http://online-energieausweis.org/api/webhooks/mollie?uid=${rechnung.id}`, webhookUrl: `https://online-energieausweis.org/api/webhooks/mollie?uid=${rechnung.id}`,
cancelUrl: `https://online-energieausweis.org/kundendaten?a=${ausweis.id}&r=${rechnung.id}`
}); });
const checkoutUrl = payment.getCheckoutUrl(); const checkoutUrl = payment.getCheckoutUrl();

View File

@@ -28,7 +28,7 @@ export const PUT = defineApiRoute({
id: UUidWithPrefix, id: UUidWithPrefix,
}), }),
async fetch(input, ctx) { async fetch(input, ctx) {
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Ticket) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Ticket)
const ticket = await prisma.tickets.create({ const ticket = await prisma.tickets.create({
data: { data: {

View File

@@ -29,7 +29,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Unterlage) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Unterlage)
await prisma.unterlage.create({ await prisma.unterlage.create({
data: { data: {

View File

@@ -13,7 +13,9 @@ export const POST = defineApiRoute({
input: BenutzerSchema.omit({ input: BenutzerSchema.omit({
id: true, id: true,
lex_office_id: true, lex_office_id: true,
rolle: true rolle: true,
created_at: true,
updated_at: true
}), }),
middleware: authorizationMiddleware, middleware: authorizationMiddleware,
async fetch(input, context, user) { async fetch(input, context, user) {
@@ -103,7 +105,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.User); const id = generatePrefixedId(9, VALID_UUID_PREFIXES.User);
const user = await prisma.benutzer.create({ const user = await prisma.benutzer.create({
data: { data: {

View File

@@ -120,7 +120,7 @@ export const DELETE = defineApiRoute({
// Dann können wir das in der Historie anzeigen // Dann können wir das in der Historie anzeigen
await prisma.event.create({ await prisma.event.create({
data: { data: {
id: generatePrefixedId(6, VALID_UUID_PREFIXES.Event), id: generatePrefixedId(9, VALID_UUID_PREFIXES.Event),
title: "Ausweis storniert", title: "Ausweis storniert",
description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.", description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.",
benutzer: { benutzer: {

View File

@@ -48,7 +48,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.VerbrauchsausweisGewerbe) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.VerbrauchsausweisGewerbe)
const createdAusweis = await prisma.verbrauchsausweisGewerbe.create({ const createdAusweis = await prisma.verbrauchsausweisGewerbe.create({
data: { data: {

View File

@@ -121,7 +121,7 @@ export const DELETE = defineApiRoute({
// Dann können wir das in der Historie anzeigen // Dann können wir das in der Historie anzeigen
await prisma.event.create({ await prisma.event.create({
data: { data: {
id: generatePrefixedId(6, VALID_UUID_PREFIXES.Event), id: generatePrefixedId(9, VALID_UUID_PREFIXES.Event),
title: "Ausweis storniert", title: "Ausweis storniert",
description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.", description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.",
benutzer: { benutzer: {

View File

@@ -51,7 +51,7 @@ export const PUT = defineApiRoute({
}) })
} }
const id = generatePrefixedId(6, "VW"); const id = generatePrefixedId(9, "VW");
const createdAusweis = await prisma.verbrauchsausweisWohnen.create({ const createdAusweis = await prisma.verbrauchsausweisWohnen.create({
data: { data: {

View File

@@ -4,6 +4,8 @@ import KundendatenModule from "#modules/KundendatenModule.svelte";
import AusweisLayout from "#layouts/AusweisLayoutPruefung.astro"; import AusweisLayout from "#layouts/AusweisLayoutPruefung.astro";
import { Enums } from "#lib/client/prisma"; import { Enums } from "#lib/client/prisma";
import { getCurrentUser } from "#lib/server/user"; import { getCurrentUser } from "#lib/server/user";
import { getAusweisartFromId } from "#components/Ausweis/types";
import { getAufnahme, getBedarfsausweisWohnen, getBilder, getObjekt, getUnterlagen, getVerbrauchsausweisGewerbe, getVerbrauchsausweisWohnen } from "#lib/server/db";
// Man sollte nur auf diese Seite kommen, wenn ein Ausweis bereits vorliegt und in der Datenbank abgespeichert wurde. // Man sollte nur auf diese Seite kommen, wenn ein Ausweis bereits vorliegt und in der Datenbank abgespeichert wurde.
@@ -11,12 +13,38 @@ const user = await getCurrentUser(Astro) || {}
// POST Body // POST Body
const params = new URLSearchParams(await Astro.request.text()); const params = new URLSearchParams(await Astro.request.text());
const searchParams = Astro.url.searchParams;
let ausweis, aufnahme, objekt, ausweisart, bilder, unterlagen, partner_code;
if (!params.has("ausweis") || !params.has("aufnahme") || !params.has("objekt") || !params.has("bilder") || !params.has("ausweisart")) { if (!params.has("ausweis") || !params.has("aufnahme") || !params.has("objekt") || !params.has("bilder") || !params.has("ausweisart")) {
// Rechnung und Ausweis als GET parameter
if (searchParams.has("a") && searchParams.has("r")) {
const id = searchParams.get("id") as string
const ausweisart = getAusweisartFromId(id)
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
ausweis = await getVerbrauchsausweisWohnen(id)
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
ausweis = await getVerbrauchsausweisGewerbe(id)
} else if (ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) {
ausweis = await getBedarfsausweisWohnen(id)
}
if (!ausweis || ausweis.benutzer_id !== user.id) {
// Ausweis gehört nicht diesem Benutzer oder existiert nicht
return Astro.redirect("/404") return Astro.redirect("/404")
} }
let ausweis, aufnahme, objekt, ausweisart, bilder, unterlagen, partner_code; aufnahme = await getAufnahme(ausweis.aufnahme_id)
objekt = await getObjekt(aufnahme?.objekt_id)
bilder = await getBilder(ausweis.aufnahme_id)
unterlagen = await getUnterlagen(ausweis.aufnahme_id)
} else {
// Nichts ist vorhanden
return Astro.redirect("/404")
}
} else {
try { try {
ausweis = JSON.parse(params.get("ausweis") || "") ausweis = JSON.parse(params.get("ausweis") || "")
aufnahme = JSON.parse(params.get("aufnahme") || "") aufnahme = JSON.parse(params.get("aufnahme") || "")
@@ -32,6 +60,7 @@ try {
} catch(e){ } catch(e){
return Astro.redirect("/404") return Astro.redirect("/404")
} }
}
--- ---

BIN
src/testing/ausweise.csv.br Normal file

Binary file not shown.

View File

@@ -1,57 +1,92 @@
import moment from "moment"; import moment from "moment";
import newUserIdMap from "./new-user-id-map.json" with { type: "json" }; import { Enums, prisma } from "#lib/server/prisma.js";
import processed from "./new-ausweis-id-map.json" with { type: "json" };
import { Benutzer, Enums, prisma } from "#lib/server/prisma.js";
import * as fs from "fs"; import * as fs from "fs";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
import { hashPassword } from "#lib/password.js"; import { hashPassword } from "#lib/password.js";
import Papa from "papaparse" import Papa from "papaparse";
import { generatePrefixedId } from "#lib/db.js"; import { generatePrefixedId } from "#lib/db.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { tryCatch } from "#lib/tryCatch.js";
const saveUserMap = () => { const path = fileURLToPath(new URL("./ausweise.csv", import.meta.url));
fs.writeFileSync(
fileURLToPath(new URL("./new-user-id-map.json", import.meta.url)),
JSON.stringify(newUserIdMap)
);
};
const path = fileURLToPath(new URL("./temp_ausweise.csv", import.meta.url));
if (!fs.existsSync(path)) { if (!fs.existsSync(path)) {
throw new Error(`${path} existiert nicht.`) throw new Error(`${path} existiert nicht.`);
} }
let i = 0
const file = fs.createReadStream(path, "utf8"); const file = fs.createReadStream(path, "utf8");
Papa.parse(file, { Papa.parse(file, {
header: true, header: true,
async complete(results, file) { async complete(results, file) {
for (const dataset of results.data as any) { for (const dataset of results.data as any) {
if (dataset.id in processed) { i++
if (i % 50 === 0) {
console.log(`Processed ${i} of ${results.data.length}, ${Math.round(i / results.data.length * 100)}%`)
}
const existing_ausweis = await prisma.aufnahme.findFirst({
where: {
OR: [{
verbrauchsausweise_gewerbe: {
some: {
alte_ausweis_id: parseInt(dataset.id),
},
},
}, {
verbrauchsausweise_wohnen: {
some: {
alte_ausweis_id: parseInt(dataset.id),
},
},
}, {
bedarfsausweise_wohnen: {
some: {
alte_ausweis_id: parseInt(dataset.id),
},
},
}]
},
});
if (existing_ausweis) {
console.log(`Ausweis für ${dataset.id} existiert bereits, überspringen.`);
continue; continue;
} }
const user_id = dataset.user_id; const user_id = dataset.user_id;
const email =
dataset.email ||
dataset.rechnung_email ||
dataset.versand_email;
let user: Benutzer | null = null; let user = await prisma.benutzer.findFirst({
if (!(user_id in newUserIdMap)) {
console.log(`Missing user ${user_id}`);
const email = dataset.email || dataset.rechnung_email || dataset.versand_email
if (email) {
user = await prisma.benutzer.findUnique({
where: { where: {
email OR: [
} {
}) alte_id: parseInt(user_id),
},
{
email,
},
],
},
});
if (!user) { if (!user) {
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.User) console.log(`Missing user ${user_id}`);
if (email) {
const id = generatePrefixedId(9, VALID_UUID_PREFIXES.User);
user = await prisma.benutzer.create({ user = await prisma.benutzer.create({
data: { data: {
id, id,
email, email,
passwort: hashPassword(Math.random().toString(36).slice(-8)), passwort: hashPassword(
Math.random().toString(36).slice(-8)
),
adresse: dataset.strasse, adresse: dataset.strasse,
ort: dataset.ort, ort: dataset.ort,
plz: dataset.plz, plz: dataset.plz,
@@ -61,27 +96,16 @@ Papa.parse(file, {
telefon: dataset.telefonnummer, telefon: dataset.telefonnummer,
}, },
}); });
}
newUserIdMap[user_id] = user.id;
saveUserMap();
}
} else { } else {
user = await prisma.benutzer.findUnique({ console.log(
where: { `Benutzer für ausweis ${dataset.id} konnte nicht gefunden werden`
id: newUserIdMap[user_id], );
},
});
}
if (!user) {
saveProcessed();
console.log(`Benutzer für ausweis ${dataset.id} konnte nicht gefunden werden`)
continue; continue;
} }
}
const objekt_id = generatePrefixedId(6, VALID_UUID_PREFIXES.Objekt) const objekt_id = generatePrefixedId(9, VALID_UUID_PREFIXES.Objekt);
const objekt = await prisma.objekt.create({ const [objekt, objekt_error] = await tryCatch(prisma.objekt.create({
data: { data: {
id: objekt_id, id: objekt_id,
adresse: dataset.objekt_strasse, adresse: dataset.objekt_strasse,
@@ -94,9 +118,29 @@ Papa.parse(file, {
}, },
}, },
}, },
}); }))
const aufnahme_id = generatePrefixedId(6, VALID_UUID_PREFIXES.Objekt) if (objekt_error) {
console.log(objekt_error);
console.log({
id: objekt_id,
adresse: dataset.objekt_strasse,
erstellungsdatum: moment(dataset.erstellungsdatum).toDate(),
ort: dataset.objekt_ort,
plz: dataset.objekt_plz,
benutzer: {
connect: {
id: user.id,
},
},
});
continue;
}
const aufnahme_id = generatePrefixedId(
6,
VALID_UUID_PREFIXES.Objekt
);
const aufnahme = await prisma.aufnahme.create({ const aufnahme = await prisma.aufnahme.create({
data: { data: {
@@ -108,9 +152,15 @@ Papa.parse(file, {
aussenwand_gedaemmt: dataset.aussenwand_gedaemmt == "1", aussenwand_gedaemmt: dataset.aussenwand_gedaemmt == "1",
aussenwand_min_12cm_gedaemmt: aussenwand_min_12cm_gedaemmt:
dataset.aussenwand_min_12cm_gedaemmt == "1", dataset.aussenwand_min_12cm_gedaemmt == "1",
baujahr_gebaeude: parseInt(dataset.baujahr_gebaeude) ? [parseInt(dataset.baujahr_gebaeude)] : [], baujahr_gebaeude: parseInt(dataset.baujahr_gebaeude)
baujahr_heizung: parseInt(dataset.baujahr_anlage) ? [parseInt(dataset.baujahr_anlage)] : [], ? [parseInt(dataset.baujahr_gebaeude)]
baujahr_klima: parseInt(dataset.baujahr_klimaanlage) ? [parseInt(dataset.baujahr_klimaanlage)] : [], : [],
baujahr_heizung: parseInt(dataset.baujahr_anlage)
? [parseInt(dataset.baujahr_anlage)]
: [],
baujahr_klima: parseInt(dataset.baujahr_klimaanlage)
? [parseInt(dataset.baujahr_klimaanlage)]
: [],
benutzer: { benutzer: {
connect: { connect: {
id: user.id, id: user.id,
@@ -144,7 +194,8 @@ Papa.parse(file, {
nutzflaeche: parseFloat(dataset.nutzflaeche), nutzflaeche: parseFloat(dataset.nutzflaeche),
gebaeudeteil: dataset.objekt_gebaeudeteil, gebaeudeteil: dataset.objekt_gebaeudeteil,
gebaeudetyp: dataset.objekt_typ, gebaeudetyp: dataset.objekt_typ,
heizungsrohre_gedaemmt: dataset.heizungsrohre_gedaemmt == "1", heizungsrohre_gedaemmt:
dataset.heizungsrohre_gedaemmt == "1",
isolier_verglasung: dataset.isolier_verglasung == "1", isolier_verglasung: dataset.isolier_verglasung == "1",
keller: keller:
dataset.keller_beheizt == "Beheizt" dataset.keller_beheizt == "Beheizt"
@@ -171,15 +222,18 @@ Papa.parse(file, {
? Enums.Lueftungskonzept ? Enums.Lueftungskonzept
.LueftungsanlageOhneWaermerueckgewinnung .LueftungsanlageOhneWaermerueckgewinnung
: Enums.Lueftungskonzept.Schachtlueftung, : Enums.Lueftungskonzept.Schachtlueftung,
niedertemperatur_kessel: dataset.niedertemperatur_kessel == "1", niedertemperatur_kessel:
dataset.niedertemperatur_kessel == "1",
oberste_geschossdecke_gedaemmt: oberste_geschossdecke_gedaemmt:
dataset.oberste_geschossdecke_gedaemmt == "1", dataset.oberste_geschossdecke_gedaemmt == "1",
oberste_geschossdecke_min_12cm_gedaemmt: oberste_geschossdecke_min_12cm_gedaemmt:
dataset.oberste_geschossdecke_min_12cm_gedaemmt == "1", dataset.oberste_geschossdecke_min_12cm_gedaemmt == "1",
photovoltaik: dataset.photovoltaik == "1", photovoltaik: dataset.photovoltaik == "1",
raum_temperatur_regler: dataset.raum_temperatur_regler == "1", raum_temperatur_regler:
dataset.raum_temperatur_regler == "1",
saniert: dataset.objekt_saniert == "1", saniert: dataset.objekt_saniert == "1",
solarsystem_warmwasser: dataset.solarsystem_warmwasser == "1", solarsystem_warmwasser:
dataset.solarsystem_warmwasser == "1",
standard_kessel: dataset.standard_kessel == "1", standard_kessel: dataset.standard_kessel == "1",
tueren_dicht: dataset.tueren_dicht == "1", tueren_dicht: dataset.tueren_dicht == "1",
tueren_undicht: dataset.tueren_undicht == "1", tueren_undicht: dataset.tueren_undicht == "1",
@@ -192,37 +246,47 @@ Papa.parse(file, {
}); });
/* -------------------------------- Bilder ------------------------------- */ /* -------------------------------- Bilder ------------------------------- */
try {
const images: Record<string, string[]> = JSON.parse(dataset.images); const images: Record<string, string[]> = JSON.parse(dataset.images);
for (const kategorie in images) { for (const kategorie in images) {
for (const image of images[kategorie]) { for (const image of images[kategorie]) {
const categoryMap = { const categoryMap = {
"daemmung": Enums.BilderKategorie.Daemmung, daemmung: Enums.BilderKategorie.Daemmung,
"fenster": Enums.BilderKategorie.Fenster, fenster: Enums.BilderKategorie.Fenster,
"general": Enums.BilderKategorie.Gebaeude, general: Enums.BilderKategorie.Gebaeude,
"heizung": Enums.BilderKategorie.Heizung heizung: Enums.BilderKategorie.Heizung,
} };
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Bild) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Bild);
const img = await prisma.bild.create({ const img = await prisma.bild.create({
data: { data: {
id, id,
kategorie: categoryMap[kategorie as keyof typeof categoryMap], kategorie:
categoryMap[
kategorie as keyof typeof categoryMap
],
aufnahme: { aufnahme: {
connect: { connect: {
id: aufnahme.id id: aufnahme.id,
}
}, },
name: image },
name: image,
},
});
} }
})
} }
} catch(e) {
} }
if (dataset.ausweisart === "VA") { if (dataset.ausweisart === "VA") {
const ausweis = await prisma.verbrauchsausweisWohnen.create({ const ausweis = await prisma.verbrauchsausweisWohnen.create({
data: { data: {
id: VALID_UUID_PREFIXES.VerbrauchsausweisWohnen + dataset.id, id:
VALID_UUID_PREFIXES.VerbrauchsausweisWohnen +
dataset.id,
alte_ausweis_id: parseInt(dataset.id),
alternative_heizung: dataset.alheizung == "1", alternative_heizung: dataset.alheizung == "1",
alternative_kuehlung: dataset.alkuehlung == "1", alternative_kuehlung: dataset.alkuehlung == "1",
alternative_lueftung: dataset.allueftung == "1", alternative_lueftung: dataset.allueftung == "1",
@@ -260,7 +324,13 @@ Papa.parse(file, {
}, },
kontrolldatei_angefragt: dataset.kontrolldatei == "1", kontrolldatei_angefragt: dataset.kontrolldatei == "1",
registriernummer: dataset.regnummer, registriernummer: dataset.regnummer,
startdatum: moment().set("year", dataset.energieverbrauch_zeitraum_jahr).set("month", dataset.energieverbrauch_zeitraum_monat).toDate(), startdatum: moment()
.set("year", dataset.energieverbrauch_zeitraum_jahr)
.set(
"month",
dataset.energieverbrauch_zeitraum_monat
)
.toDate(),
verbrauch_1: parseFloat( verbrauch_1: parseFloat(
dataset.energieverbrauch_1_heizquelle_1 dataset.energieverbrauch_1_heizquelle_1
), ),
@@ -281,22 +351,30 @@ Papa.parse(file, {
), ),
warmwasser_anteil_bekannt: warmwasser_anteil_bekannt:
dataset.warmwasser_anteil_bekannt == "1", dataset.warmwasser_anteil_bekannt == "1",
warmwasser_enthalten: dataset.warmwasser_enthalten == "1", warmwasser_enthalten:
dataset.warmwasser_enthalten == "1",
zurueckgestellt: dataset.zurueckGestellt == "1", zurueckgestellt: dataset.zurueckGestellt == "1",
zusaetzliche_heizquelle: zusaetzliche_heizquelle:
dataset.zusaetzliche_heizquelle == "1", dataset.zusaetzliche_heizquelle == "1",
ausstellungsdatum: moment(dataset.bestelldatum).isValid() ? moment(dataset.bestelldatum).toDate() : new Date(), ausstellungsdatum: moment(
dataset.bestelldatum
).isValid()
? moment(dataset.bestelldatum).toDate()
: new Date(),
ausweistyp: Enums.AusweisTyp.Standard, ausweistyp: Enums.AusweisTyp.Standard,
brennstoff_1: dataset.energietraeger_1, brennstoff_1: dataset.energietraeger_1,
brennstoff_2: dataset.energietraeger_2, brennstoff_2: dataset.energietraeger_2,
boxpruefung: dataset.boxpruefung == "1", boxpruefung: dataset.boxpruefung == "1",
created_at: moment(dataset.erstellungsdatum).toDate(), created_at: moment(dataset.erstellungsdatum).toDate()
}, },
}); });
} else if (dataset.ausweisart === "VANW") { } else if (dataset.ausweisart === "VANW") {
const ausweis = await prisma.verbrauchsausweisGewerbe.create({ const ausweis = await prisma.verbrauchsausweisGewerbe.create({
data: { data: {
id: VALID_UUID_PREFIXES.VerbrauchsausweisGewerbe + dataset.id, id:
VALID_UUID_PREFIXES.VerbrauchsausweisGewerbe +
dataset.id,
alte_ausweis_id: parseInt(dataset.id),
alternative_heizung: dataset.alheizung == "1", alternative_heizung: dataset.alheizung == "1",
alternative_kuehlung: dataset.alkuehlung == "1", alternative_kuehlung: dataset.alkuehlung == "1",
alternative_lueftung: dataset.allueftung == "1", alternative_lueftung: dataset.allueftung == "1",
@@ -327,6 +405,7 @@ Papa.parse(file, {
einheit_1: dataset.energietraeger_einheit_heizquelle_1, einheit_1: dataset.energietraeger_einheit_heizquelle_1,
einheit_2: dataset.energietraeger_einheit_heizquelle_2, einheit_2: dataset.energietraeger_einheit_heizquelle_2,
storniert: dataset.erledigt == "4", storniert: dataset.erledigt == "4",
keller_beheizt: dataset.keller_beheizt === "Beheizt",
benutzer: { benutzer: {
connect: { connect: {
id: user.id, id: user.id,
@@ -334,7 +413,13 @@ Papa.parse(file, {
}, },
kontrolldatei_angefragt: dataset.kontrolldatei == "1", kontrolldatei_angefragt: dataset.kontrolldatei == "1",
registriernummer: dataset.regnummer, registriernummer: dataset.regnummer,
startdatum: moment().set("year", dataset.energieverbrauch_zeitraum_jahr).set("month", dataset.energieverbrauch_zeitraum_monat).toDate(), startdatum: moment()
.set("year", dataset.energieverbrauch_zeitraum_jahr)
.set(
"month",
dataset.energieverbrauch_zeitraum_monat
)
.toDate(),
verbrauch_1: parseFloat( verbrauch_1: parseFloat(
dataset.energieverbrauch_1_heizquelle_1 dataset.energieverbrauch_1_heizquelle_1
), ),
@@ -353,25 +438,40 @@ Papa.parse(file, {
verbrauch_6: parseFloat( verbrauch_6: parseFloat(
dataset.energieverbrauch_3_heizquelle_2 dataset.energieverbrauch_3_heizquelle_2
), ),
anteil_kuehlung_1: parseFloat(dataset.anteil_kuehlung_1), anteil_kuehlung_1: parseFloat(
anteil_kuehlung_2: parseFloat(dataset.anteil_kuehlung_2), dataset.anteil_kuehlung_1
),
anteil_kuehlung_2: parseFloat(
dataset.anteil_kuehlung_2
),
brennstoff_1: dataset.energietraeger_1, brennstoff_1: dataset.energietraeger_1,
brennstoff_2: dataset.energietraeger_2, brennstoff_2: dataset.energietraeger_2,
strom_1: parseFloat(dataset.vanw_strom_1), strom_1: parseFloat(dataset.vanw_strom_1),
strom_2: parseFloat(dataset.vanw_strom_2), strom_2: parseFloat(dataset.vanw_strom_2),
strom_3: parseFloat(dataset.vanw_strom_3), strom_3: parseFloat(dataset.vanw_strom_3),
kuehlung_enthalten: dataset.wird_gekuehlt == "1" ? true : false, kuehlung_enthalten:
stromverbrauch_enthaelt_beleuchtung: dataset.nwbeleuchtung == "1", dataset.wird_gekuehlt == "1" ? true : false,
stromverbrauch_enthaelt_heizung: dataset.nwheizung == "1", stromverbrauch_enthaelt_beleuchtung:
stromverbrauch_enthaelt_kuehlung: dataset.nwkuehlung == "1", dataset.nwbeleuchtung == "1",
stromverbrauch_enthaelt_lueftung: dataset.nwlueftung == "1", stromverbrauch_enthaelt_heizung:
dataset.nwheizung == "1",
stromverbrauch_enthaelt_kuehlung:
dataset.nwkuehlung == "1",
stromverbrauch_enthaelt_lueftung:
dataset.nwlueftung == "1",
stromverbrauch_enthaelt_sonstige: dataset.nwsonstiges, stromverbrauch_enthaelt_sonstige: dataset.nwsonstiges,
stromverbrauch_enthaelt_warmwasser: dataset.nwwarmwasser == "1", stromverbrauch_enthaelt_warmwasser:
warmwasser_enthalten: dataset.warmwasser_enthalten == "1", dataset.nwwarmwasser == "1",
warmwasser_enthalten:
dataset.warmwasser_enthalten == "1",
zurueckgestellt: dataset.zurueckGestellt == "1", zurueckgestellt: dataset.zurueckGestellt == "1",
zusaetzliche_heizquelle: zusaetzliche_heizquelle:
dataset.zusaetzliche_heizquelle == "1", dataset.zusaetzliche_heizquelle == "1",
ausstellungsdatum: moment(dataset.bestelldatum).isValid() ? moment(dataset.bestelldatum).toDate() : new Date(), ausstellungsdatum: moment(
dataset.bestelldatum
).isValid()
? moment(dataset.bestelldatum).toDate()
: new Date(),
ausweistyp: Enums.AusweisTyp.Standard, ausweistyp: Enums.AusweisTyp.Standard,
boxpruefung: dataset.boxpruefung == "1", boxpruefung: dataset.boxpruefung == "1",
created_at: moment(dataset.erstellungsdatum).toDate(), created_at: moment(dataset.erstellungsdatum).toDate(),
@@ -380,7 +480,10 @@ Papa.parse(file, {
} else if (dataset.ausweisart === "BA") { } else if (dataset.ausweisart === "BA") {
const ausweis = await prisma.bedarfsausweisWohnen.create({ const ausweis = await prisma.bedarfsausweisWohnen.create({
data: { data: {
id: VALID_UUID_PREFIXES.BedarfsausweisWohnen + dataset.id, id:
VALID_UUID_PREFIXES.BedarfsausweisWohnen +
dataset.id,
alte_ausweis_id: parseInt(dataset.id),
alternative_heizung: dataset.alheizung == "1", alternative_heizung: dataset.alheizung == "1",
alternative_kuehlung: dataset.alkuehlung == "1", alternative_kuehlung: dataset.alkuehlung == "1",
alternative_lueftung: dataset.allueftung == "1", alternative_lueftung: dataset.allueftung == "1",
@@ -411,14 +514,26 @@ Papa.parse(file, {
kontrolldatei_angefragt: dataset.kontrolldatei == "1", kontrolldatei_angefragt: dataset.kontrolldatei == "1",
registriernummer: dataset.regnummer, registriernummer: dataset.regnummer,
zurueckgestellt: dataset.zurueckGestellt == "1", zurueckgestellt: dataset.zurueckGestellt == "1",
anteil_zusatzheizung: parseFloat(dataset.anteil_zusatzheizung), anteil_zusatzheizung: parseFloat(
dataset.anteil_zusatzheizung
),
anzahl_gauben: parseInt(dataset.anzahl_gauben), anzahl_gauben: parseInt(dataset.anzahl_gauben),
anzahl_vollgeschosse: parseInt(dataset.anzahl_vollgeschosse), anzahl_vollgeschosse: parseInt(
dataset.anzahl_vollgeschosse
),
aussenwand_bauart: dataset.aussenwand_bauart, aussenwand_bauart: dataset.aussenwand_bauart,
aussenwand_daemmung: parseFloat(dataset.aussenwand_daemmung), aussenwand_daemmung: parseFloat(
aussenwand_flaeche: parseFloat(dataset.aussenwand_flaeche), dataset.aussenwand_daemmung
aussenwand_u_wert: parseFloat(dataset.aussenwand_u_wert), ),
aussenwandflaeche_unbeheizt: parseFloat(dataset.aussenwandflaeche_unbeheizt), aussenwand_flaeche: parseFloat(
dataset.aussenwand_flaeche
),
aussenwand_u_wert: parseFloat(
dataset.aussenwand_u_wert
),
aussenwandflaeche_unbeheizt: parseFloat(
dataset.aussenwandflaeche_unbeheizt
),
boden_bauart: dataset.boden_bauart, boden_bauart: dataset.boden_bauart,
boden_daemmung: parseFloat(dataset.boden_daemmung), boden_daemmung: parseFloat(dataset.boden_daemmung),
breite_gauben: parseFloat(dataset.breite_gauben), breite_gauben: parseFloat(dataset.breite_gauben),
@@ -427,7 +542,9 @@ Papa.parse(file, {
dach_u_wert: parseFloat(dataset.dach_u_wert), dach_u_wert: parseFloat(dataset.dach_u_wert),
// TODO Das machen wir zwar so aber das ist doch scheiße.... // TODO Das machen wir zwar so aber das ist doch scheiße....
dachfenster_art: parseFloat(dataset.dachfenster_art), dachfenster_art: parseFloat(dataset.dachfenster_art),
dachfenster_flaeche: parseFloat(dataset.dachfenster_flaeche), dachfenster_flaeche: parseFloat(
dataset.dachfenster_flaeche
),
dachflaeche: parseFloat(dataset.dachflaeche), dachflaeche: parseFloat(dataset.dachflaeche),
decke_bauart: dataset.decke_bauart, decke_bauart: dataset.decke_bauart,
decke_daemmung: parseFloat(dataset.decke_daemmung), decke_daemmung: parseFloat(dataset.decke_daemmung),
@@ -436,11 +553,21 @@ Papa.parse(file, {
fenster_art_1: parseFloat(dataset.fenster_art_1), fenster_art_1: parseFloat(dataset.fenster_art_1),
fenster_art_2: parseFloat(dataset.fenster_art_2), fenster_art_2: parseFloat(dataset.fenster_art_2),
deckenflaeche: parseFloat(dataset.deckenflaeche), deckenflaeche: parseFloat(dataset.deckenflaeche),
fenster_flaeche_1: parseFloat(dataset.fenster_flaeche_1), fenster_flaeche_1: parseFloat(
fenster_flaeche_2: parseFloat(dataset.fenster_flaeche_2), dataset.fenster_flaeche_1
fensterflaeche_nw_no: parseFloat(dataset.fensterflaeche_nw_no), ),
fensterflaeche_so_sw: parseFloat(dataset.fensterflaeche_so_sw), fenster_flaeche_2: parseFloat(
fussboden_flaeche: parseFloat(dataset.fussboden_flaeche), dataset.fenster_flaeche_2
),
fensterflaeche_nw_no: parseFloat(
dataset.fensterflaeche_nw_no
),
fensterflaeche_so_sw: parseFloat(
dataset.fensterflaeche_so_sw
),
fussboden_flaeche: parseFloat(
dataset.fussboden_flaeche
),
fussboden_u_wert: parseFloat(dataset.fussboden_u_wert), fussboden_u_wert: parseFloat(dataset.fussboden_u_wert),
geschosshoehe: parseFloat(dataset.geschosshoehe), geschosshoehe: parseFloat(dataset.geschosshoehe),
haustuer_art: parseFloat(dataset.haustuer_art), haustuer_art: parseFloat(dataset.haustuer_art),
@@ -454,30 +581,26 @@ Papa.parse(file, {
masse_d: parseFloat(dataset.masse_d), masse_d: parseFloat(dataset.masse_d),
masse_e: parseFloat(dataset.masse_e), masse_e: parseFloat(dataset.masse_e),
masse_f: parseFloat(dataset.masse_f), masse_f: parseFloat(dataset.masse_f),
kollektor_flaeche: parseFloat(dataset.kollektor_flaeche), kollektor_flaeche: parseFloat(
dataset.kollektor_flaeche
),
volumen: parseFloat(dataset.volumen), volumen: parseFloat(dataset.volumen),
waerme_erzeugung_heizung: dataset.waerme_erzeugung_heizung, waerme_erzeugung_heizung:
dataset.waerme_erzeugung_heizung,
warmwasser_erzeugung: dataset.warmwasser_erzeugung, warmwasser_erzeugung: dataset.warmwasser_erzeugung,
warmwasser_speicherung: dataset.warmwasser_speicherung, warmwasser_speicherung: dataset.warmwasser_speicherung,
warmwasser_verteilung: dataset.warmwasser_verteilung, warmwasser_verteilung: dataset.warmwasser_verteilung,
ausstellungsdatum: moment(dataset.bestelldatum).isValid() ? moment(dataset.bestelldatum).toDate() : new Date(), ausstellungsdatum: moment(
dataset.bestelldatum
).isValid()
? moment(dataset.bestelldatum).toDate()
: new Date(),
ausweistyp: Enums.AusweisTyp.Standard, ausweistyp: Enums.AusweisTyp.Standard,
boxpruefung: dataset.boxpruefung == "1", boxpruefung: dataset.boxpruefung == "1",
created_at: moment(dataset.erstellungsdatum).toDate(), created_at: moment(dataset.erstellungsdatum).toDate(),
}, },
}); });
} }
processed[dataset.id as string] = true;
saveProcessed()
} }
}, },
}); });
function saveProcessed() {
fs.writeFileSync(
fileURLToPath(new URL("./new-ausweis-id-map.json", import.meta.url)),
JSON.stringify(processed)
);
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,3 @@
import newUserIdMap from "./new-user-id-map.json" with { type: "json" };
import { Enums, prisma } from "#lib/server/prisma.js"; import { Enums, prisma } from "#lib/server/prisma.js";
import Papa from "papaparse" import Papa from "papaparse"
import * as fs from "fs"; import * as fs from "fs";
@@ -6,13 +5,6 @@ import { fileURLToPath } from "url";
import { generatePrefixedId } from "#lib/db.js"; import { generatePrefixedId } from "#lib/db.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
const saveUserMap = () => {
fs.writeFileSync(
fileURLToPath(new URL("./new-user-id-map.json", import.meta.url)),
JSON.stringify(newUserIdMap)
);
};
const path = fileURLToPath(new URL("./users.csv", import.meta.url)); const path = fileURLToPath(new URL("./users.csv", import.meta.url));
if (!fs.existsSync(path)) { if (!fs.existsSync(path)) {
@@ -25,24 +17,31 @@ Papa.parse(file, {
async complete(results, file) { async complete(results, file) {
let i = 0; let i = 0;
for (const user of results.data as any) { for (const user of results.data as any) {
if (user.id in newUserIdMap) { i++
continue; if (i % 50 === 0) {
console.log(`Processed ${i} of ${results.data.length}, ${Math.round(i / results.data.length * 100)}%`)
} }
const existing = await prisma.benutzer.findFirst({
if (await prisma.benutzer.findUnique({
where: { where: {
OR: [{
alte_id: parseInt(user.id)
}, {
email: user.email email: user.email
}]
} }
})) { })
continue;
if (existing) {
continue
} }
try { try {
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.User) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.User)
await prisma.benutzer.create({ await prisma.benutzer.create({
data: { data: {
id, id,
alte_id: parseInt(user.id),
email: user.email, email: user.email,
passwort: user.password, passwort: user.password,
adresse: user.adresse, adresse: user.adresse,
@@ -60,28 +59,11 @@ Papa.parse(file, {
telefon: user.phone, telefon: user.phone,
} }
}); });
newUserIdMap[user.id] = id;
} catch (e) { } catch (e) {
saveUserMap(); console.log(e);
console.log(user);
continue; continue;
} }
// Alle 50 werden gespeichert.
if (i % 50 == 0) {
console.log(`Saved ${i} - ${results.data.length - i} left`);
saveUserMap();
}
i++;
} }
} }
}); });
process.on("SIGINT", () => {
console.log("Shutting down.");
saveUserMap()
process.exit(0)
})

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,4 @@
import newRechnungenIdMap from "./new-rechnungen-id-map.json" with { type: "json" }; import { Enums, Prisma, prisma } from "#lib/server/prisma.js";
import newUserIdMap from "./new-user-id-map.json" with { type: "json" };
import { Enums, prisma } from "#lib/server/prisma.js";
import Papa from "papaparse" import Papa from "papaparse"
import * as fs from "fs"; import * as fs from "fs";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
@@ -8,13 +6,6 @@ import { generatePrefixedId } from "#lib/db.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import moment from "moment"; import moment from "moment";
const saveRechnungenMap = () => {
fs.writeFileSync(
fileURLToPath(new URL("./new-rechnungen-id-map.json", import.meta.url)),
JSON.stringify(newRechnungenIdMap)
);
};
const path = fileURLToPath(new URL("./rechnungen.csv", import.meta.url)); const path = fileURLToPath(new URL("./rechnungen.csv", import.meta.url));
if (!fs.existsSync(path)) { if (!fs.existsSync(path)) {
@@ -27,17 +18,34 @@ Papa.parse(file, {
async complete(results, file) { async complete(results, file) {
let i = 0; let i = 0;
for (const rechnung of results.data as any) { for (const rechnung of results.data as any) {
if (rechnung.id in newRechnungenIdMap) { i++
if (i % 50 === 0) {
console.log(`Processed ${i} of ${results.data.length}, ${Math.round(i / results.data.length * 100)}%`)
}
const existing = await prisma.rechnung.findFirst({
where: {
alte_id: parseInt(rechnung.id)
}
})
if (existing) {
console.log(`Rechnung für ${rechnung.id} existiert bereits.`);
continue; continue;
} }
if (!(rechnung.user_id in newUserIdMap)) { const user = await prisma.benutzer.findFirst({
where: {
alte_id: parseInt(rechnung.user_id)
}
})
if (!user) {
console.log(`User ${rechnung.user_id} not found.`); console.log(`User ${rechnung.user_id} not found.`);
continue; continue;
} }
try { try {
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Rechnung) const id = generatePrefixedId(9, VALID_UUID_PREFIXES.Rechnung)
const services: Enums.Service[] = [] const services: Enums.Service[] = []
@@ -79,20 +87,21 @@ Papa.parse(file, {
"SUE-OK": Enums.Bezahlmethoden.sofort, "SUE-OK": Enums.Bezahlmethoden.sofort,
"": Enums.Bezahlmethoden.rechnung "": Enums.Bezahlmethoden.rechnung
} }
await prisma.rechnung.create({
data: { const data: Parameters<typeof prisma.rechnung.create>[0]["data"] = {
id, id,
alte_id: parseInt(rechnung.id),
betrag: parseFloat(rechnung.amount), betrag: parseFloat(rechnung.amount),
bezahlmethode: paymentTypeMap[rechnung.payment_type], bezahlmethode: paymentTypeMap[rechnung.payment_type as keyof typeof paymentTypeMap],
// bedarfsausweis_gewerbe, // bedarfsausweis_gewerbe,
// bedarfsausweis_wohnen, // bedarfsausweis_wohnen,
// benutzer, // benutzer,
// benutzer_id, // benutzer_id,
status: rechnung.status === "storniert" ? Enums.Rechnungsstatus.canceled : rechnung.status, status: rechnung.status === "storniert" ? Enums.Rechnungsstatus.canceled : rechnung.status,
bezahlt_am: moment(rechnung.date_created).toDate(), bezahlt_am: moment(rechnung.date_created).isValid() ? moment(rechnung.date_created).toDate() : new Date(),
email: rechnung.email, email: rechnung.email,
empfaenger: `${rechnung.vorname} ${rechnung.name}`, empfaenger: `${rechnung.vorname} ${rechnung.name}`,
erstellt_am: moment(rechnung.date_created).toDate(), erstellt_am: moment(rechnung.date_created).isValid() ? moment(rechnung.date_created).toDate() : new Date(),
// geg_nachweis_gewerbe, // geg_nachweis_gewerbe,
// geg_nachweis_wohnen, // geg_nachweis_wohnen,
ort: rechnung.ort, ort: rechnung.ort,
@@ -108,31 +117,59 @@ Papa.parse(file, {
versand_plz: rechnung.plz, versand_plz: rechnung.plz,
versand_strasse: rechnung.strasse, versand_strasse: rechnung.strasse,
lex_office_id: rechnung.lex_office_id, lex_office_id: rechnung.lex_office_id,
benutzer_id: newUserIdMap[rechnung.user_id] benutzer: {
connect: {
id: user.id
}
}
} }
});
newRechnungenIdMap[rechnung.id] = id; const verbrauchsausweisWohnen = await prisma.verbrauchsausweisWohnen.findFirst({
where: {
alte_ausweis_id: parseInt(rechnung.ausweis_id)
}
})
if (verbrauchsausweisWohnen) {
data["verbrauchsausweis_wohnen"] = {
connect: {
id: verbrauchsausweisWohnen.id
}
}
} else {
const verbrauchsausweisGewerbe = await prisma.verbrauchsausweisGewerbe.findFirst({
where: {
alte_ausweis_id: parseInt(rechnung.ausweis_id)
}
})
if (verbrauchsausweisGewerbe) {
data["verbrauchsausweis_gewerbe"] = {
connect: {
id: verbrauchsausweisGewerbe.id
}
}
} else {
const bedarfsausweisWohnen = await prisma.bedarfsausweisWohnen.findFirst({
where: {
alte_ausweis_id: parseInt(rechnung.ausweis_id)
}
})
if (bedarfsausweisWohnen) {
data["bedarfsausweis_wohnen"] = {
connect: {
id: bedarfsausweisWohnen.id
}
}
}
}
}
await prisma.rechnung.create({
data
});
} catch (e) { } catch (e) {
saveRechnungenMap(); console.log(e);
continue; continue;
} }
// Alle 50 werden gespeichert.
if (i % 50 == 0) {
console.log(`Saved ${i} - ${results.data.length - i} left`);
saveRechnungenMap();
}
i++;
} }
} }
}); });
process.on("SIGINT", () => {
console.log("Shutting down.");
saveRechnungenMap()
process.exit(0)
})

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
src/testing/users.csv.br Normal file

Binary file not shown.