Ausweis und weitere Änderungen

This commit is contained in:
Moritz Utcke
2025-02-18 18:17:02 +11:00
parent 8486421f12
commit c8ba17fab3
38 changed files with 1771 additions and 330 deletions

View File

@@ -0,0 +1,80 @@
---
import AusweisLayout from "#layouts/AusweisLayoutDaten.astro";
import { AufnahmeClient, ObjektClient, UploadedGebaeudeBild, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
import { createCaller } from "../../../astro-typesafe-api-caller.js";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken.js";
import GEGNachweisVerbrauchsausweisWohnenModule from "#modules/angebot-anfragen/GEGNachweisVerbrauchsausweisWohnenModule.svelte";
const uid = Astro.url.searchParams.get("uid");
let ausweis: VerbrauchsausweisWohnenClient = {} as VerbrauchsausweisWohnenClient;
let aufnahme: AufnahmeClient = {} as AufnahmeClient;
let objekt: ObjektClient = {} as ObjektClient;
let bilder: UploadedGebaeudeBild[] = []
const valid = validateAccessTokenServer(Astro);
const caller = createCaller(Astro);
if (uid) {
if (!valid) {
return Astro.redirect(
`/auth/login?redirect=${Astro.url.toString()}`
);
}
try {
ausweis = await caller["verbrauchsausweis-wohnen"]._uid.GET.fetch(null, {
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid
}
});
aufnahme = await caller.aufnahme._uid.GET.fetch(null, {
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid: ausweis.uid_aufnahme
}
})
objekt = await caller.objekt._uid.GET.fetch(null, {
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid: ausweis.uid_objekt
}
})
bilder = await caller.objekt._uid.bilder.GET.fetch(null, {
headers: {
authorization: `Bearer ${Astro.cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)?.value}`
},
params: {
uid: ausweis.uid_objekt
}
})
if (!ausweis) {
// Der Ausweis scheint nicht zu existieren.
// Wir leiten auf die generische Ausweisseite ohne UID weiter.
return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-wohnen"
);
}
} catch(e) {
return Astro.redirect(
"/energieausweis-erstellen/verbrauchsausweis-wohnen"
);
}
}
---
<AusweisLayout title="Verbrauchsausweis erstellen">
<GEGNachweisVerbrauchsausweisWohnenModule client:only {ausweis} {objekt} {aufnahme} {bilder} />
</AusweisLayout>

View File

@@ -0,0 +1,209 @@
import { getAusweisartFromUUID } from "#components/Ausweis/types.js";
import { adminMiddleware } from "#lib/middleware/authorization.js";
import { pdfDatenblattVerbrauchsausweisWohnen } from "#lib/pdf/pdfDatenblattVerbrauchsausweisWohnen.js";
import { pdfVerbrauchsausweisWohnen } from "#lib/pdf/pdfVerbrauchsausweisWohnen.js";
import { Enums, prisma } from "@ibcornelsen/database/server";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "astro:content";
import { fileURLToPath } from "url";
import * as fs from "fs";
import { transport } from "#lib/mail.js";
import { BASE_URI } from "#lib/constants.js";
export const GET = defineApiRoute({
input: z.object({
uid: z.string(),
}),
output: z.void(),
middleware: adminMiddleware,
async fetch({ uid }, context, user) {
const ausweisart = getAusweisartFromUUID(uid);
if (ausweisart === "VerbrauchsausweisWohnen") {
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
where: {
uid,
},
include: {
aufnahme: {
include: {
objekt: {
include: {
gebaeude_bilder: true,
benutzer: true,
},
},
},
},
},
});
if (!ausweis) {
throw new APIError({
code: "BAD_REQUEST",
message: "Ausweis existiert nicht.",
});
}
const rechnung = await prisma.rechnung.findFirst({
where: {
aufnahme_id: ausweis.aufnahme.id,
},
orderBy: {
erstellt_am: "desc",
},
});
if (!rechnung) {
throw new APIError({
code: "BAD_REQUEST",
message:
"Die Rechnung wurde noch nicht erstellt, wir können nicht fortfahren.",
});
}
// TODO
// SECTION: Rechnung erstellen (LexOffice)
// Wir wollen die Rechnung an lex office versenden, und uns die ID von da holen.
// Falls die Rechnung bereits existiert ist das nicht nötig.
// if (!$rechnung->lex_office_id) {
// [$lex_office_id, $renr] = createInvoice($ausweis, $rechnung);
// sleep(1); // TODO: Nach der Umstellung von LexOffice auf etwas anderes MUSS das hier unbedingt entfernt werden!
// if (!$lex_office_id || !$renr) {
// die("Bei der Erstellung der Rechnung ist etwas schiefgelaufen - Möglicherweise ist etwas mit LexOffice?");
// }
// $rechnung->lex_office_id = $lex_office_id;
// $rechnung->rechnungsnummer = $renr;
// $rechnung->save();
// }
// TODO
// if ($ausweis->erledigt != 2) {$ausweis->erstellungsdatum = date("Y-m-d H:i:s");}
// $ausweis->erledigt = 2;
// $ausweis->save();
const pdfAusweis = await pdfVerbrauchsausweisWohnen(
ausweis,
ausweis.aufnahme,
ausweis.aufnahme.objekt,
ausweis.aufnahme.objekt.gebaeude_bilder,
ausweis.aufnahme.objekt.benutzer
);
const pdfDatenblatt = await pdfDatenblattVerbrauchsausweisWohnen(
ausweis,
ausweis.aufnahme,
ausweis.aufnahme.objekt,
ausweis.aufnahme.objekt.benutzer
);
const pdfAusweisPath = fileURLToPath(
new URL(
`../../../../persistent/generated/Ausweis-${ausweis.uid}.pdf`,
import.meta.url
)
);
const pdfDatenblattPath = fileURLToPath(
new URL(
`../../../../persistent/generated/Datenblatt-${ausweis.uid}.pdf`,
import.meta.url
)
);
fs.writeFileSync(pdfAusweisPath, pdfAusweis);
fs.writeFileSync(pdfDatenblattPath, pdfDatenblatt);
let text: string;
if (rechnung.status === Enums.Rechnungsstatus.paid) {
text = `
<p>Sehr geehrte*r ${user.vorname} ${user.name},</p>
<p>im Anhang finden Sie Ihren geprüften Energieusweis inkl. Rechnung als PDF-Datei. Den Rechnungsbetrag haben Sie bereits bezahlt. Vielen Dank.</p>
<p>
Mit freundlichen Grüßen,
<br>
Dipl.-Ing. Jens Cornelsen
<br>
<br>
<strong>IB Cornelsen</strong>
<br>
Katendeich 5A
<br>
21035 Hamburg
<br>
www.online-energieausweis.org
<br>
<br>
fon 040 · 209339850
<br>
fax 040 · 209339859
</p>`;
} else {
text = `
<p>Sehr geehrte*r ${user.vorname} ${user.name},</p>
<p>im Anhang finden Sie Ihren geprüften Energieusweis inkl. Rechnung als PDF-Datei. Nachfolgend finden Sie unsere Bankverbindung. Bitte geben Sie als Verwendungszweck die Rechnungsnummer an (siehe unten). Vielen Dank.</p>
<br>
<table>
<tr><td>Kreditinstitut</td><td>:</td><td>\t Commerzbank AG</td>
<tr><td>Empfänger</td><td>:</td><td>\t IB Cornelsen</td>
<tr><td>IBAN</td><td>:<td>\t DE81 2004 0000 0348 6008 00</td>
<tr><td>BIC</td><td>:</td><td>\t COBADEFFXXX</td>
<tr><td>Betrag</td><td>:</td><td>\t <b>${rechnung.betrag}€</b></td>
<tr><td>Verwendungszweck</td><td>:</td><td>\t <b>${rechnung.uid}</b></td>
</table>
<br>
<p>
Alternativ können Sie auch direkt online zahlen indem Sie auf den entsprechenden Link klicken:
</p>
<br>
<table>
<tr><td>Per Einzuglastschrift zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=SEPA'>jetzt per ELV bezahlen</a></td></tr>
<tr><td>Per Sofortüberweisung zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=Sofort'>jetzt per Sofortüberweisung bezahlen</a></td></tr>
<tr><td>Über PayPal zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=PayPal'>jetzt per Paypal bezahlen</a></td></tr>
<tr><td>Per Giropay zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=Giropay'>jetzt per Giropay bezahlen</a></td></tr>
<tr><td>Per Visa oder MasterCard zahlen</td> <td>:</td> <td><a href='${BASE_URI}/energieausweis-erstellen/kaufabschluss-fortsetzen?uid=${ausweis.uid}&p=Kreditkarte'>jetzt per Kreditkarte bezahlen</a></td></tr>
</table>
<br>
<p>
Mit freundlichen Grüßen,
<br>
Dipl.-Ing. Jens Cornelsen
<br>
<br>
<strong>IB Cornelsen</strong>
<br>
Katendeich 5A
<br>
21035 Hamburg
<br>
www.online-energieausweis.org
<br>
<br>
fon 040 · 209339850
<br>
fax 040 · 209339859
</p>`;
}
await transport.sendMail({
from: `"IBCornelsen" <info@online-energieausweis.org>`,
to: user.email,
subject: `Ihr Originalausweis vom Ingenieurbüro Cornelsen (ID: ${ausweis.uid})`,
text,
});
}
},
});

View File

@@ -5,6 +5,7 @@ import { prisma } from "@ibcornelsen/database/server";
import { decodeToken, encodeToken } from "#lib/auth/token.js";
import { TokenType } from "#lib/auth/types.js";
import { hashPassword } from "#lib/password.js";
import { transport } from "#lib/mail.js";
export const GET = defineApiRoute({
input: z.object({
@@ -33,16 +34,6 @@ export const GET = defineApiRoute({
uid: user.uid
})
const transport = nodemailer.createTransport({
host: "smtp.ionos.de",
port: 465,
secure: true,
auth: {
user: "info@online-energieausweis.org",
pass: "Katendeich5a2024!"
}
})
const info = await transport.sendMail({
from: `"IBCornelsen" <info@online-energieausweis.org>`,
to: input.email,

View File

@@ -1,12 +1,12 @@
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js";
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, VerbrauchsausweisWohnenClient, ZodOverlap } from "#components/Ausweis/types.js";
import { exclude } from "#lib/exclude.js";
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { BedarfsausweisWohnenSchema, prisma } from "@ibcornelsen/database/server";
import { BedarfsausweisWohnenSchema, prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
export const PATCH = defineApiRoute({
input: BedarfsausweisWohnenSchema.omit({
input: VerbrauchsausweisWohnenSchema.omit({
uid: true,
id: true,
benutzer_id: true,
@@ -18,7 +18,7 @@ export const PATCH = defineApiRoute({
},
middleware: authorizationMiddleware,
async fetch(input, ctx, user) {
const objekt = await prisma.bedarfsausweisWohnen.findUnique({
const objekt = await prisma.verbrauchsausweisWohnen.findUnique({
where: {
uid: ctx.params.uid,
benutzer: {
@@ -34,7 +34,7 @@ export const PATCH = defineApiRoute({
})
}
await prisma.bedarfsausweisWohnen.update({
await prisma.verbrauchsausweisWohnen.update({
where: {
uid: ctx.params.uid
},
@@ -61,7 +61,7 @@ export const DELETE = defineApiRoute({
// Wir holen uns den Bedarfsausweis
// Dieser MUSS mit dem Nutzer verknüpft sein.
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
where: {
uid,
},
@@ -155,7 +155,7 @@ export const GET = defineApiRoute({
}
}
},
output: ZodOverlap<OptionalNullable<BedarfsausweisWohnenClient>>(BedarfsausweisWohnenSchema.merge(z.object({
output: ZodOverlap<OptionalNullable<VerbrauchsausweisWohnenClient>>(VerbrauchsausweisWohnenSchema.merge(z.object({
uid_aufnahme: UUidWithPrefix,
uid_objekt: UUidWithPrefix,
uid_benutzer: UUidWithPrefix.optional()
@@ -175,7 +175,7 @@ export const GET = defineApiRoute({
})
}
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
where: {
uid,
benutzer_id: user.id

View File

@@ -0,0 +1,217 @@
import { BedarfsausweisWohnenClient, OptionalNullable, UUidWithPrefix, ZodOverlap } from "#components/Ausweis/types.js";
import { exclude } from "#lib/exclude.js";
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { BedarfsausweisWohnenSchema, prisma } from "@ibcornelsen/database/server";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
export const PATCH = defineApiRoute({
input: BedarfsausweisWohnenSchema.omit({
uid: true,
id: true,
benutzer_id: true,
aufnahme_id: true,
}),
output: z.void(),
headers: {
"Authorization": z.string()
},
middleware: authorizationMiddleware,
async fetch(input, ctx, user) {
const objekt = await prisma.bedarfsausweisWohnen.findUnique({
where: {
uid: ctx.params.uid,
benutzer: {
id: user.id
}
}
})
if (!objekt) {
throw new APIError({
code: "NOT_FOUND",
message: "Ausweis konnte nicht gefunden werden oder gehört einem anderen Benutzer."
})
}
await prisma.bedarfsausweisWohnen.update({
where: {
uid: ctx.params.uid
},
data: input
})
},
})
export const DELETE = defineApiRoute({
meta: {
description: "Storniert einen Ausweis"
},
headers: authorizationHeaders,
middleware: authorizationMiddleware,
async fetch(input, ctx, user) {
const { uid } = ctx.params;
if (!UUidWithPrefix.safeParse(uid).success) {
throw new APIError({
code: "BAD_REQUEST",
message: "UID konnte nicht verifiziert werden."
})
}
// Wir holen uns den Bedarfsausweis
// Dieser MUSS mit dem Nutzer verknüpft sein.
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
where: {
uid,
},
include: {
aufnahme: {
select: {
storniert: true
}
}
}
});
if (!ausweis) {
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
throw new APIError({
code: "NOT_FOUND",
message: "Ausweis konnte nicht gefunden werden.",
});
}
// Wir dürfen den Ausweis nur stornieren, wenn er noch nicht ausgestellt wurde
// Außerdem müssen wir schauen, ob wir Admin oder der Besitzer des Ausweises sind.
if ((ausweis.benutzer_id !== user.id) && user.rolle !== "ADMIN") {
// Falls der Ausweis nicht dem Nutzer gehört, werfen wir einen Fehler
throw new APIError({
code: "FORBIDDEN",
message: "Ausweis gehört nicht dem Nutzer.",
});
}
// if (ausweis.erledigt) {
// // Falls der Ausweis bereits ausgestellt wurde, werfen wir einen Fehler
// throw new TRPCError({
// code: "BAD_REQUEST",
// message: "Ausweis wurde bereits ausgestellt.",
// });
// }
if (ausweis.aufnahme.storniert) {
// Falls der Ausweis bereits storniert ist, werfen wir einen Fehler
throw new APIError({
code: "BAD_REQUEST",
message: "Ausweis wurde bereits storniert.",
});
}
await prisma.aufnahme.update({
where: {
id: ausweis.aufnahme_id
},
data: {
storniert: true
}
})
// Wir erstellen ein Event, dass der Ausweis storniert wurde
// Dann können wir das in der Historie anzeigen
await prisma.event.create({
data: {
title: "Ausweis storniert",
description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.",
benutzer: {
connect: {
id: user.id
}
},
aufnahme: {
connect: {
id: ausweis.aufnahme_id
}
}
}
})
},
})
export const GET = defineApiRoute({
meta: {
description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
tags: ["Gebäude"],
headers: {
"Authorization": {
description: "Ein gültiger Authentifizierungstoken",
required: true,
allowEmptyValue: false,
examples: {
Bearer: {
value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
}
}
},
output: ZodOverlap<OptionalNullable<BedarfsausweisWohnenClient>>(BedarfsausweisWohnenSchema.merge(z.object({
uid_aufnahme: UUidWithPrefix,
uid_objekt: UUidWithPrefix,
uid_benutzer: UUidWithPrefix.optional()
})).omit({
id: true,
aufnahme_id: true,
benutzer_id: true
})),
middleware: authorizationMiddleware,
async fetch(input, context, user) {
const { uid } = context.params;
if (!uid) {
throw new APIError({
code: "BAD_REQUEST",
message: "Missing uid in request params"
})
}
const ausweis = await prisma.bedarfsausweisWohnen.findUnique({
where: {
uid,
benutzer_id: user.id
},
include: {
benutzer: {
select: {
uid: true
}
},
aufnahme: {
select: {
uid: true,
objekt: {
select: {
uid: true
}
}
}
}
}
});
if (!ausweis) {
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
throw new APIError({
code: "NOT_FOUND",
message: "Ausweis konnte nicht gefunden werden.",
});
}
return {
uid_aufnahme: ausweis.aufnahme.uid,
uid_objekt: ausweis.aufnahme.objekt.uid,
uid_benutzer: ausweis.benutzer?.uid,
...exclude(ausweis, ["id", "aufnahme_id", "benutzer_id", "aufnahme"])
}
},
});

View File

@@ -0,0 +1,146 @@
import { UUidWithPrefix } from "#components/Ausweis/types.js";
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
import { BedarfsausweisWohnenSchema, prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
export const PUT = defineApiRoute({
meta: {
contentTypes: ["application/json"],
description:
"Erstellt einen neuen GEG Nachweis für Wohngebäude.",
tags: ["GEG Nachweis", "Verbrauchsausweis Wohnen"],
},
input: z.object({
ausweis: VerbrauchsausweisWohnenSchema.omit({
id: true,
benutzer_id: true,
uid: true,
aufnahme_id: true
}),
uid_aufnahme: UUidWithPrefix
}),
output: z.object({
uid: UUidWithPrefix,
objekt_uid: UUidWithPrefix,
aufnahme_uid: UUidWithPrefix,
}),
headers: authorizationHeaders,
middleware: authorizationMiddleware,
async fetch(input, ctx, user) {
const aufnahme = await prisma.aufnahme.findUnique({
where: {
uid: input.uid_aufnahme
}
})
if (!aufnahme || aufnahme.benutzer_id !== user.id) {
throw new APIError({
code: "FORBIDDEN",
message: "Aufnahme konnte nicht gefunden werden oder gehört nicht zu diesem Benutzer."
})
}
const createdAusweis = await prisma.verbrauchsausweisWohnen.create({
data: {
...input.ausweis,
benutzer: {
connect: {
id: user.id,
},
},
aufnahme: {
connect: {
uid: aufnahme.uid,
},
},
},
select: {
uid: true,
aufnahme: {
select: {
uid: true,
objekt: {
select: {
uid: true,
},
},
},
},
},
});
return {
uid: createdAusweis.uid,
objekt_uid: createdAusweis.aufnahme.objekt.uid,
aufnahme_uid: createdAusweis.aufnahme.uid,
};
},
});
export const GET = defineApiRoute({
meta: {
description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
tags: ["Gebäude"],
headers: {
Authorization: {
description: "Ein gültiger Authentifizierungstoken",
required: true,
allowEmptyValue: false,
examples: {
Bearer: {
value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
},
},
},
},
},
middleware: authorizationMiddleware,
async fetch(input, context, user) {
const { uid } = context.params;
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
where: {
uid,
},
include: {
benutzer: true,
aufnahme: {
include: {
objekt: {
include: {
gebaeude_bilder: true,
},
},
rechnungen: true,
events: {
include: {
benutzer: {
select: {
uid: true,
},
},
},
orderBy: {
date: "asc",
},
},
},
},
},
});
if (
!ausweis ||
(ausweis.benutzer_id !== null && ausweis.benutzer_id !== user.id)
) {
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
throw new APIError({
code: "NOT_FOUND",
message: "Ausweis konnte nicht gefunden werden.",
});
}
return ausweis;
},
});

View File

@@ -0,0 +1,116 @@
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
import { prisma, UnterlageSchema } from "@ibcornelsen/database/server";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
import { fileURLToPath } from "url";
import { writeFileSync } from "fs";
export const PUT = defineApiRoute({
input: UnterlageSchema.omit({
objekt_id: true,
id: true,
uid: true
}).merge(z.object({
data: z.string(),
})),
output: z.object({
uid: z.string({ description: "Die UID der Unterlage." })
}),
middleware: authorizationMiddleware,
async fetch({ data, name, kategorie, mime }, ctx, user) {
if (mime !== "application/pdf" && mime !== "image/png" && mime !== "image/jpeg") {
throw new APIError({
code: "BAD_REQUEST",
message: "Nicht unterstützter mimetype, unterstützt werden 'image/jpeg', 'image/png', 'application/pdf'."
})
}
let objekt = await prisma.objekt.findUnique({
where: {
uid: ctx.params.uid,
benutzer_id: user.id
},
});
if (!objekt) {
throw new APIError({
code: "NOT_FOUND",
message: "Objekt nicht gefunden oder gehört einem anderen Benutzer.",
});
}
const buffer = Buffer.from(data, "base64");
const unterlage = await prisma.unterlage.create({
data: {
kategorie: kategorie,
objekt: {
connect: {
id: objekt.id,
},
},
},
select: {
uid: true,
},
});
const filePath = fileURLToPath(new URL(`../../../../../persistent/unterlagen/${unterlage.uid}`, import.meta.url));
try {
writeFileSync(filePath, buffer)
} catch(e) {
// Unterlage wurde nicht gespeichert, wir löschen den Eintrag wieder
await prisma.unterlage.delete({
where: {
uid: unterlage.uid
}
})
// Und geben einen Fehler zurück
throw new APIError({
code: "INTERNAL_SERVER_ERROR",
message: "Unterlage konnte nicht gespeichert werden.",
});
}
return {
uid: unterlage.uid
};
},
})
export const GET = defineApiRoute({
middleware: authorizationMiddleware,
output: z.array(UnterlageSchema.pick({
kategorie: true,
uid: true
})),
async fetch(input, ctx, user) {
const { uid } = ctx.params;
const objekt = await prisma.objekt.findUnique({
where: {
uid,
benutzer_id: user.id
},
select: {
benutzer_id: true,
unterlagen: {
select: {
kategorie: true,
uid: true
}
}
}
})
if (!objekt) {
throw new APIError({
code: "FORBIDDEN",
message: "Objekt existiert nicht oder gehört einem anderen Benutzer."
})
}
return objekt.unterlagen
},
})

View File

@@ -3,8 +3,8 @@ import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken.js";
import { prisma } from "@ibcornelsen/database/server";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { fileURLToPath } from "bun";
import * as fs from "fs";
import { fileURLToPath } from "url";
export const GET = defineApiRoute({
async fetch(input, context, transfer) {

View File

@@ -1,25 +0,0 @@
---
import UserLayout from "../../../layouts/UserLayout.astro";
import { validateAccessTokenServer } from "#server/lib/validateAccessToken";
import DashboardAusweisePruefenModule from "#modules/Dashboard/DashboardAusweisePruefenModule.svelte";
import { prisma } from "@ibcornelsen/database/server";
import { createCaller } from "#lib/caller";
const accessTokenValid = await validateAccessTokenServer(Astro);
if (!accessTokenValid) {
return Astro.redirect("/auth/login")
}
// TODO: Nutzer darf nur auf diese Seite, wenn er die Rolle "admin" hat
const caller = createCaller(Astro);
const ausweise = await caller.v1.verbrauchsausweisWohnen.getMany({
limit: 25,
});
---
<UserLayout title="Dashboard">
<DashboardAusweisePruefenModule ausweise={ausweise} client:load></DashboardAusweisePruefenModule>
</UserLayout>

View File

@@ -3,7 +3,7 @@ import { AufnahmeClient, BenutzerClient, ObjektClient, UploadedGebaeudeBild, Ver
import UserLayout from "#layouts/UserLayout.astro";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants";
import DashboardAusweisePruefenModule from "#modules/Dashboard/DashboardAusweisePruefenModule.svelte";
import { prisma } from "@ibcornelsen/database/server";
import { Enums, prisma } from "@ibcornelsen/database/server";
import { createCaller } from "src/astro-typesafe-api-caller";
const caller = createCaller(Astro)
@@ -20,6 +20,10 @@ try {
return Astro.redirect("/auth/login")
}
if (user.rolle !== Enums.BenutzerRolle.ADMIN) {
return Astro.redirect("/dashboard")
}
const ausweise = await prisma.verbrauchsausweisWohnen.findMany({
where: {
benutzer: {

View File

@@ -74,9 +74,9 @@ export const GET: APIRoute = async (Astro) => {
let pdf: Uint8Array<ArrayBufferLike> | null = null;
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
pdf = await pdfVerbrauchsausweisWohnen(ausweis, aufnahme, objekt, bilder, user);
pdf = await pdfVerbrauchsausweisWohnen(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt, bilder, user);
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
pdf = await pdfVerbrauchsausweisGewerbe(ausweis, aufnahme, objekt, bilder, user);
pdf = await pdfVerbrauchsausweisGewerbe(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt, bilder, user);
}
return new Response(pdf, {
@@ -92,10 +92,10 @@ export const POST: APIRoute = async (Astro) => {
const caller = createCaller(Astro);
const ausweis = JSON.parse(params.get("ausweis"));
const aufnahme = JSON.parse(params.get("aufnahme"));
const objekt = JSON.parse(params.get("objekt"));
const bilder = JSON.parse(params.get("bilder"));
const ausweis = JSON.parse(params.get("ausweis") || "{}");
const aufnahme = JSON.parse(params.get("aufnahme") || "{}");
const objekt = JSON.parse(params.get("objekt") || "{}");
const bilder = JSON.parse(params.get("bilder") || "{}");
const ausweisart: Enums.Ausweisart = params.get("ausweisart")
let user: BenutzerClient = {};