feat(backend): Rechnungsempfaenger im Haushalt konfigurierbar #216

Closed
opened 2026-07-03 20:57:48 +02:00 by niboer · 0 comments
Owner

Ziel

Haushaltsmitglieder (oder der Gruender) sollen festlegen koennen, wer die Rechnung fuer den Haushalt erhaelt. Standard ist der Gruender (group.createdBy).

Motivation

Im ZUGFeRD-Rechnungsmodul (Issue #16) wird pro Haushalt eine Rechnung erstellt. Der Rechnungsempfaenger ist aktuell der Gruender des Haushalts. In vielen Faellen soll aber eine andere Person im Haushalt die Rechnung erhalten (z. B. der Partner, der die Zahlung abwickelt).

Umsetzung

Neues Prisma-Model

model GroupInvoiceRecipient {
  groupId  String @db.Uuid
  personId String @db.Uuid

  group  Group  @relation(fields: [groupId], references: [groupId], onDelete: Cascade)
  person Person @relation(fields: [personId], references: [personId], onDelete: Cascade)

  @@id([groupId, personId])
  @@map("groupInvoiceRecipients")
}

Endpunkte

Endpunkt Auth Beschreibung
GET /api/v1/groups/{groupId}/invoice-recipients requireGroupMember Aktuelle Empfaenger-Liste abrufen
PUT /api/v1/groups/{groupId}/invoice-recipients requireGroupMember Empfaenger setzen, Body: { personIds: string[] }

Regeln:

  • Nur Personen, die Mitglied des Haushalts sind, duerfen gesetzt werden
  • Leeres Array = Zurueckfall auf group.createdBy (Default-Verhalten)
  • Haushaltsmitglieder untereinander koennen die Liste aendern (kein Admin required)

Integration in #16

Im Invoice-Run (processInvoiceJob):

// Vor Fallback auf group.createdBy:
const recipients = await prisma.groupInvoiceRecipient.findMany({
  where: { groupId: group.groupId }
});
const recipientPersonId = recipients.length > 0
  ? recipients[0].personId
  : group.createdBy;

Es wird der erste Eintrag aus recipients verwendet. Moechte der Haushalt mehrere Empfaenger, wird eine Rechnung pro Empfaenger erstellt (Feature-Erweiterung, hier zunaechst nur einer).

Abhaengigkeit

Dieser Issue kann unabhaengig von #16 umgesetzt werden. Er stellt die Daten bereit; #16 integriert sie dann.

Labels

  • component/backend
  • prio/medium
  • type/feature
## Ziel Haushaltsmitglieder (oder der Gruender) sollen festlegen koennen, wer die Rechnung fuer den Haushalt erhaelt. Standard ist der Gruender (`group.createdBy`). ## Motivation Im ZUGFeRD-Rechnungsmodul (Issue #16) wird pro Haushalt eine Rechnung erstellt. Der Rechnungsempfaenger ist aktuell der Gruender des Haushalts. In vielen Faellen soll aber eine andere Person im Haushalt die Rechnung erhalten (z. B. der Partner, der die Zahlung abwickelt). ## Umsetzung ### Neues Prisma-Model ```prisma model GroupInvoiceRecipient { groupId String @db.Uuid personId String @db.Uuid group Group @relation(fields: [groupId], references: [groupId], onDelete: Cascade) person Person @relation(fields: [personId], references: [personId], onDelete: Cascade) @@id([groupId, personId]) @@map("groupInvoiceRecipients") } ``` ### Endpunkte | Endpunkt | Auth | Beschreibung | |----------|------|-------------| | `GET /api/v1/groups/{groupId}/invoice-recipients` | `requireGroupMember` | Aktuelle Empfaenger-Liste abrufen | | `PUT /api/v1/groups/{groupId}/invoice-recipients` | `requireGroupMember` | Empfaenger setzen, Body: `{ personIds: string[] }` | **Regeln:** - Nur Personen, die Mitglied des Haushalts sind, duerfen gesetzt werden - Leeres Array = Zurueckfall auf `group.createdBy` (Default-Verhalten) - Haushaltsmitglieder untereinander koennen die Liste aendern (kein Admin required) ### Integration in #16 Im Invoice-Run (`processInvoiceJob`): ```typescript // Vor Fallback auf group.createdBy: const recipients = await prisma.groupInvoiceRecipient.findMany({ where: { groupId: group.groupId } }); const recipientPersonId = recipients.length > 0 ? recipients[0].personId : group.createdBy; ``` Es wird der erste Eintrag aus `recipients` verwendet. Moechte der Haushalt mehrere Empfaenger, wird eine Rechnung pro Empfaenger erstellt (Feature-Erweiterung, hier zunaechst nur einer). ## Abhaengigkeit Dieser Issue kann unabhaengig von #16 umgesetzt werden. Er stellt die Daten bereit; #16 integriert sie dann. ## Labels - `component/backend` - `prio/medium` - `type/feature`
Sign in to join this conversation.
No description provided.