Empfänger und Stammdaten speichern

This commit is contained in:
Moritz Utcke
2025-10-17 18:05:53 -04:00
parent 77a71d8f6c
commit af4bc5b282
12 changed files with 55 additions and 21 deletions

View File

@@ -0,0 +1,9 @@
/*
Warnings:
- You are about to drop the column `anrede` on the `benutzer` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "benutzer" DROP COLUMN "anrede",
ADD COLUMN "empfaenger" VARCHAR(100);

View File

@@ -17,7 +17,7 @@ model Benutzer {
ort String? @db.VarChar(50) ort String? @db.VarChar(50)
adresse String? @db.VarChar(150) adresse String? @db.VarChar(150)
telefon String? @db.VarChar(50) telefon String? @db.VarChar(50)
anrede String? @db.VarChar(50) empfaenger String? @db.VarChar(100)
rolle BenutzerRolle @default(USER) rolle BenutzerRolle @default(USER)
firma String? firma String?
lex_office_id String? lex_office_id String?

View File

@@ -170,7 +170,6 @@ export async function benutzerSpeichern(benutzer: Partial<Benutzer>): Promise<st
email: benutzer.email, email: benutzer.email,
passwort: "", passwort: "",
adresse: benutzer.adresse ?? null, adresse: benutzer.adresse ?? null,
anrede: benutzer.anrede ?? null,
firma: benutzer.firma ?? null, firma: benutzer.firma ?? null,
vorname: benutzer.vorname ?? null, vorname: benutzer.vorname ?? null,
ort: benutzer.ort ?? null, ort: benutzer.ort ?? null,

View File

@@ -13,7 +13,7 @@ export const BenutzerSchema = z.object({
ort: z.string().nullish(), ort: z.string().nullish(),
adresse: z.string().nullish(), adresse: z.string().nullish(),
telefon: z.string().nullish(), telefon: z.string().nullish(),
anrede: z.string().nullish(), empfaenger: z.string().nullish(),
rolle: z.nativeEnum(BenutzerRolle), rolle: z.nativeEnum(BenutzerRolle),
firma: z.string().nullish(), firma: z.string().nullish(),
lex_office_id: z.string().nullish(), lex_office_id: z.string().nullish(),

View File

@@ -11,6 +11,7 @@
let adresse: string; let adresse: string;
let plz: string; let plz: string;
let ort: string; let ort: string;
let empfaenger: string;
export let redirect: string | null = null; export let redirect: string | null = null;
@@ -27,7 +28,7 @@
const { id, passwort } = await api.user.PUT.fetch({ const { id, passwort } = await api.user.PUT.fetch({
vorname, vorname,
name, email, name, email,
adresse, plz, ort adresse, plz, ort, empfaenger
}) })
await loginClient(email, passwort) await loginClient(email, passwort)
@@ -105,6 +106,17 @@
</div> </div>
</div> </div>
<div class="flex flex-col gap-2">
<h4>Empfänger</h4>
<input
type="text"
placeholder="Max Mustermann"
name="empfaenger"
class="input input-bordered text-base text-base-content font-medium"
bind:value={empfaenger}
required
/>
</div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<h4>Email</h4> <h4>Email</h4>
<input <input

View File

@@ -216,13 +216,29 @@ export const PUT = defineApiRoute({
if (user.rolle !== Enums.BenutzerRolle.ADMIN) { if (user.rolle !== Enums.BenutzerRolle.ADMIN) {
// Wir aktualisieren auch die Rechnungsdaten des Benutzers // Wir aktualisieren auch die Rechnungsdaten des Benutzers
// Das sollte allerdings nur passieren, falls diese noch nicht gesetzt sind.
const data = {
ort: input.ort,
plz: input.plz,
adresse: input.strasse,
telefon: input.telefon,
}
if (user.ort) {
delete data.ort;
}
if (user.plz) {
delete data.plz;
}
if (user.adresse) {
delete data.adresse;
}
if (user.telefon) {
delete data.telefon;
}
await prisma.benutzer.update({ await prisma.benutzer.update({
data: { data,
ort: input.ort,
plz: input.plz,
adresse: input.strasse,
telefon: input.telefon,
},
where: { where: {
id: user.id id: user.id
} }

View File

@@ -1,11 +1,11 @@
import { IDWithPrefix } from "#components/Ausweis/types.js"; import { IDWithPrefix } from "#components/Ausweis/types.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { generateIDWithPrefix } from "#lib/db.js"; import { generateIDWithPrefix } from "#lib/db.js";
import { adminMiddleware, authorizationMiddleware } from "#lib/middleware/authorization.js"; import { authorizationMiddleware } from "#lib/middleware/authorization.js";
import { hashPassword } from "#lib/password.js"; import { hashPassword } from "#lib/password.js";
import { createLexOfficeCustomer } from "#lib/server/lexoffice.js"; import { createLexOfficeCustomer } from "#lib/server/lexoffice.js";
import { sendRegisterMail } from "#lib/server/mail/registrierung.js"; import { sendRegisterMail } from "#lib/server/mail/registrierung.js";
import { Benutzer, prisma } from "#lib/server/prisma.js"; import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { BenutzerSchema } from "src/generated/zod/benutzer.js"; import { BenutzerSchema } from "src/generated/zod/benutzer.js";
import { z } from "zod"; import { z } from "zod";
@@ -26,7 +26,6 @@ export const POST = defineApiRoute({
const updateData: any = {}; const updateData: any = {};
updateData.id = user.id; updateData.id = user.id;
if (input.adresse) updateData.adresse = input.adresse; if (input.adresse) updateData.adresse = input.adresse;
if (input.anrede) updateData.anrede = input.anrede;
if (input.email) updateData.email = input.email; if (input.email) updateData.email = input.email;
if (input.firma) updateData.firma = input.firma; if (input.firma) updateData.firma = input.firma;
if (input.name) updateData.name = input.name; if (input.name) updateData.name = input.name;
@@ -111,13 +110,14 @@ export const PUT = defineApiRoute({
adresse: z.string(), adresse: z.string(),
plz: z.string(), plz: z.string(),
ort: z.string(), ort: z.string(),
empfaenger: z.string()
}), }),
output: z.object({ output: z.object({
id: IDWithPrefix, id: IDWithPrefix,
passwort: z.string().min(8).max(100) passwort: z.string().min(8).max(100)
}), }),
async fetch(input) { async fetch(input) {
let { email, vorname, name, adresse, plz, ort } = input; let { email, vorname, name, adresse, plz, ort, empfaenger } = input;
email = email.toLowerCase(); email = email.toLowerCase();
const existingUser = await prisma.benutzer.findUnique({ const existingUser = await prisma.benutzer.findUnique({
@@ -145,6 +145,7 @@ export const PUT = defineApiRoute({
adresse, adresse,
plz, plz,
ort, ort,
empfaenger,
id id
} }
}) })

View File

@@ -53,7 +53,7 @@ import Layout from "#layouts/Layout.astro";
<div> <div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Kontakt & Gebäudedaten</h3> <h3 class="text-xl font-semibold text-gray-800 mb-2">Kontakt & Gebäudedaten</h3>
<ul class="list-disc list-inside text-gray-700"> <ul class="list-disc list-inside text-gray-700">
<li>Name, Anrede & E-Mail des Ansprechpartners</li> <li>Name & E-Mail des Ansprechpartners</li>
<li>Rechnungs- & Versandadresse</li> <li>Rechnungs- & Versandadresse</li>
<li>Gebäudeangaben: Wohnfläche, Baujahr, Anzahl Geschosse</li> <li>Gebäudeangaben: Wohnfläche, Baujahr, Anzahl Geschosse</li>
</ul> </ul>

View File

@@ -363,7 +363,7 @@ import Layout from "#layouts/Layout.astro";
eingegeben und an uns übermittelt und gespeichert. Eine Weitergabe der Daten an Dritte findet eingegeben und an uns übermittelt und gespeichert. Eine Weitergabe der Daten an Dritte findet
nicht statt. Folgende Daten werden im Rahmen des Registrierungsprozesses erhoben:</p> nicht statt. Folgende Daten werden im Rahmen des Registrierungsprozesses erhoben:</p>
<ol> <ol>
<li>Anrede, Vorname, Name und E-Mail des Ansprechpartners</li> <li>Vorname, Name und E-Mail des Ansprechpartners</li>
<li>Empfänger, E-Mail, Straße, <span class="caps">PLZ</span> und Ort der Rechnungsanschrift <li>Empfänger, E-Mail, Straße, <span class="caps">PLZ</span> und Ort der Rechnungsanschrift
</li> </li>
<li>Optional die Versandanschrift</li> <li>Optional die Versandanschrift</li>
@@ -417,7 +417,7 @@ import Layout from "#layouts/Layout.astro";
Kontaktaufnahme genutzt werden kann. Nimmt ein Nutzer diese Möglichkeit wahr, so werden die in Kontaktaufnahme genutzt werden kann. Nimmt ein Nutzer diese Möglichkeit wahr, so werden die in
der Eingabemaske eingegeben Daten an uns übermittelt und gespeichert. Diese Daten sind:</p> der Eingabemaske eingegeben Daten an uns übermittelt und gespeichert. Diese Daten sind:</p>
<ol> <ol>
<li>Anrede, Vorname, Name und E-Mail des Ansprechpartners</li> <li>Vorname, Name und E-Mail des Ansprechpartners</li>
</ol> Im Zeitpunkt der Absendung der Nachricht werden zudem folgende Daten gespeichert:<ol> </ol> Im Zeitpunkt der Absendung der Nachricht werden zudem folgende Daten gespeichert:<ol>
<li>Die IP-Adresse des Nutzers</li> <li>Die IP-Adresse des Nutzers</li>
<li>Datum und Uhrzeit der Registrierung</li> <li>Datum und Uhrzeit der Registrierung</li>

View File

@@ -55,7 +55,7 @@ import Layout from "#layouts/Layout.astro";
<div> <div>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Kontakt und Gebäudedaten</h3> <h3 class="text-xl font-semibold text-gray-800 mb-2">Kontakt und Gebäudedaten</h3>
<ul class="list-disc list-inside text-gray-700"> <ul class="list-disc list-inside text-gray-700">
<li>Anrede, Vorname, Name und E-Mail des Ansprechpartners</li> <li>Vorname, Name und E-Mail des Ansprechpartners</li>
<li>Empfänger, E-Mail, Straße, PLZ und Ort der Rechnungsanschrift</li> <li>Empfänger, E-Mail, Straße, PLZ und Ort der Rechnungsanschrift</li>
<li>Optionale Versandanschrift</li> <li>Optionale Versandanschrift</li>
<li>Details zur Wohnfläche, Heizung, Baujahr usw.</li> <li>Details zur Wohnfläche, Heizung, Baujahr usw.</li>

View File

@@ -45,7 +45,6 @@ Papa.parse(file, {
email: user.email, email: user.email,
passwort: user.password, passwort: user.password,
adresse: user.adresse, adresse: user.adresse,
anrede: user.anrede,
name: user.name, name: user.name,
vorname: user.vorname, vorname: user.vorname,
ort: user.ort, ort: user.ort,

View File

@@ -338,7 +338,6 @@ export function fakeBenutzer() {
ort: undefined, ort: undefined,
adresse: undefined, adresse: undefined,
telefon: undefined, telefon: undefined,
anrede: undefined,
firma: undefined, firma: undefined,
lex_office_id: undefined, lex_office_id: undefined,
}; };
@@ -356,7 +355,6 @@ export function fakeBenutzerComplete() {
ort: undefined, ort: undefined,
adresse: undefined, adresse: undefined,
telefon: undefined, telefon: undefined,
anrede: undefined,
rolle: BenutzerRolle.USER, rolle: BenutzerRolle.USER,
firma: undefined, firma: undefined,
lex_office_id: undefined, lex_office_id: undefined,