# Kantinensystem Ueberweisung-Zahlungsart und RKSV-Tagesabschluss

## Kontext

Die fachliche Anforderung hat zwei saubere Zielbilder:

1. Wenn es echte Zielrechnungen sind, sollen sie besser gar nicht ueber die Registrierkasse laufen, sondern als normale Ausgangsrechnung im Fakturasystem.
2. Falls die Kasse den Vorgang trotzdem selbst erzeugen muss, braucht sie eine eigene Zahlungsart `Ueberweisung`, die als Nicht-Barumsatz markiert ist, ohne Signatur laeuft, einen klaren Hinweis auf dem Beleg traegt und nicht in den RKSV-Umsatzzaehler eingeht.

Zusatzanforderung:

- eigene Rechnungsnummernreihe `RGYYYYMMDD-01...`
- Tagesabschluss mit sauber getrennten Bloecken fuer signaturpflichtige Umsaetze und unbare Umsaetze

## Aktuelle Repo-Situation

| Bereich | Aktueller Stand | Konsequenz fuer `Ueberweisung` |
| --- | --- | --- |
| `shared/protocol-buffer/src/main/resources/proto/shared/enums.proto` | `PaymentType` kennt `CASH`, `CREDIT`, `DEBIT`, `EPS`, `KLARNA`, `SOFORT`, `APPLE_PAY`, `PAYPAL`, `SINGLE_PURPOSE_VOUCHER`, `MULTI_PURPOSE_VOUCHER`, `DISCOUNT`, `RECHARGEABLE_DEVICE_BALANCE` | Es gibt keinen expliziten Typ fuer `Ueberweisung`. |
| `apps/components/ops_client_commons_component/lib/src/staff_admin_commons/feature/payment/payment_calculator_dialog/` | Auswahlmodell kennt nur `CUSTOMER`, `CARD`, `HOUSE`, `SERVICE`; die Mapping-Logik setzt daraus heute nur `CASH` oder `CREDIT` | Die Kasse kann `Ueberweisung` heute nicht fachlich sauber ausdruecken. |
| `apps/components/ops_client_commons_component/lib/src/protocol_buffers_v2_0/facade/payment_type_facade.dart` | Display-Layer verdichtet die Typen zu `Bar`, `Kartenzahlung`, `Onlinezahlung`, `RFID-Guthaben` usw. | Ein neuer Typ braucht einen sichtbaren Text und eine klare Belegkennzeichnung. |
| `services/payment-service/src/main/java/at/sop/helper/FonChecker.java` | Signatur wird ueber `Payer.CUSTOMER` + FON-Zustand erlaubt | Die Signaturentscheidung ist heute nicht an die Zahlungsart gebunden. |
| `services/payment-service/src/main/java/at/sop/services/DailyCloseOutService.java` | Tagesabschluss summiert alle zu einem Abschluss gezaehlten Zahlungen zusammen | Es gibt keinen eigenen Block fuer unbare Umsaetze. |
| `services/payment-service/src/main/java/at/sop/queries/DailyCloseOutQueries.java` | `calculateDailyCloseOutSum(...)` summiert alle `PaymentTransaction` mit `payer = CUSTOMER` im Abschlussfenster | Eine neue Zahlungsart wuerde sonst automatisch in dieselbe Summe fallen. |
| `services/statistics-service/src/main/java/at/sop/grpc/StatisticsGrpcService.java` | Tages- und Monatsauswertungen arbeiten mit einem einheitlichen Payment-Overview-Modell | Eine Trennung nach RKSV-Relevanz gibt es noch nicht. |
| `apps/components/ops_client_commons_component/lib/src/printer/mapper/printer_mapper_daily_closure_receipt.dart` | Der Tagesabschlussdruck kennt einen einzigen Zahlungsarten-Bericht | Die Ausgabe kann die beiden Bloecke noch nicht getrennt darstellen. |

Wichtige Folgerung:

- Ein neuer UI-Label allein reicht nicht.
- Die Fachlogik muss wissen, ob ein Umsatz RKSV-relevant ist oder nicht.
- Diese Information muss in Backend, Statistik, Druck und UI gleich interpretiert werden.

## Warum ein neuer `PaymentType` allein nicht reicht

Ein bloes neues Enum-Label wuerde nur die Oberflaeche aendern. Die fachliche Wirkung waere weiterhin falsch, weil:

- die Signaturentscheidung heute nicht von der Zahlungsart abhaengt
- die Tagesabschluss-Summe heute alle kundenbezogenen Zahlungen in einen Block zieht
- die Statistik-/PDF-Schicht nur einen Zahlungsartenblock kennt
- der Zahlbereich fuer `locationReceiptId` und der neue Rechnungsnummernkreis semantisch verschiedene Dinge sind

Die saubere Loesung braucht deshalb neben dem sichtbaren Zahlungsmodus eine zweite, fachliche Klassifikation, also zum Beispiel:

- `PaymentType` = wie wurde bezahlt?
- `RksvTurnoverCharacter` oder `rksvRelevant` = geht dieser Umsatz in den signierten RKSV-Umsatzzaehler?

## Saubere Loesung A: echte Zielrechnung im Fakturasystem

Das ist der buchhalterisch klarste Weg fuer echte Zielrechnungen.

### Eigenschaften

- Der Vorgang laeuft nicht ueber die Kasse.
- Es entsteht eine normale Ausgangsrechnung im Fakturasystem.
- Die Kasse bleibt bei Bar-, Karten- und anderen RKSV-relevanten Umsaetzen.
- Es gibt keine Vermischung von Barumsatz und Zielrechnung.

### Vorteile

- klare Buchhaltung
- keine Sonderlogik fuer RKSV-Signatur
- keine Sonderbehandlung im Tagesabschluss
- kein Risiko, dass ein unbarer Umsatz versehentlich in den signierten Zaehlweg rutscht

### Nachteil

- falls im Repo noch keine echte Faktura-Instanz existiert, ist das ein eigener fachlicher Strang und nicht nur ein kleiner UI-Fix

### Repo-Bezug

Im aktuellen Repo gibt es zwar Rechnung/PDF-nahe Bausteine und Sammelrechnungs-Workflows, aber keine durchgaengige, eigenstaendige Faktura-Strecke als First-Class-Domain fuer Zielrechnungen. Deshalb ist diese Option fachlich richtig, aber technisch vermutlich ein neuer Teilprozess.

## Saubere Loesung B: Kasse erzeugt die Rechnung, aber mit eigener unbarer Zahlungsart

Das ist die technische Fallback-Loesung, wenn die Kasse den Beleg trotzdem erzeugen muss.

### Eigenschaften

- neue sichtbare Zahlungsart `Ueberweisung`
- eigener fachlicher Charakter `NON_RKSV` oder `UNBAR`
- Beleghinweis wie `Unbarer Umsatz - Zahlung per Ueberweisung`
- keine Fiskaly-Signatur
- keine Aufnahme in den signierten RKSV-Umsatzzaehler
- separate Rechnungsnummernreihe `RGYYYYMMDD-01...`

### Warum das als eigener Charakter modelliert werden sollte

Wenn nur die Zahlungsart erweitert wird, bleibt die bestehende Signatur- und Abschlusslogik fachlich falsch. Der neue Charakter muss also explizit sein und in den Services ausgewertet werden.

### Mermaid: Zielpfade

```mermaid
flowchart TD
 A["Ist es eine echte Zielrechnung?"] -->|Ja| B["Fakturasystem verwenden"]
 A -->|Nein, Kasse muss erzeugen| C["Kassenbeleg erzeugen"]
 C --> D["PaymentType = Ueberweisung"]
 D --> E["RksvTurnoverCharacter = NON_RKSV"]
 E --> F["Belegtext: Unbarer Umsatz - Zahlung per Ueberweisung"]
 E --> G["Keine Fiskaly-Signatur"]
 E --> H["Eigene Rechnungsnummernreihe"]
```

## Empfohlene Zielarchitektur

Die fachlich beste Kombination ist:

1. Echte Zielrechnungen laufen im Fakturasystem.
2. Falls die Kasse den Beleg trotzdem erzeugen muss, dann nur mit einer echten, expliziten Nicht-RKSV-Klassifikation.

Wichtig ist dabei:

- `PaymentType` bleibt das sichtbare Zahlungsmedium
- `RksvTurnoverCharacter` steuert Signatur, Zaehlweg und Abschlussblock
- die Klassifikation sollte auf `PaymentTransaction`-Ebene landen, nicht nur auf `Payment`-Ebene

Warum `PaymentTransaction`?

- Die Signatur- und Statistiklogik arbeitet heute schon mit Transaktionen.
- Ein Payment kann mehrere Transaktionen tragen.
- Die fachliche Entscheidung sollte deshalb dort ansetzen, wo auch die Verarbeitung stattfindet.

### Praktische Regel fuer das Modell

- `CASH`, `CREDIT`, `DEBIT` und die heutigen Online- und Voucher-Typen bleiben wie sie sind
- `Ueberweisung` wird als neue, sichtbare Zahlungsart eingefuehrt
- `Ueberweisung` ist nicht RKSV-relevant
- gemischte Zahlungen sollten in v1 moeglichst vermieden werden; falls sie doch auftreten, muss die Auswertung nach Transaktionscharakter laufen, nicht nach Zahlungskopf

### Mermaid: gewuenschter Verarbeitungsfluss

```mermaid
flowchart TD
 A["Zahlung in der Kasse"] --> B["PaymentTransaction speichern"]
 B --> C{"RksvTurnoverCharacter?"}
 C -->|RKSV_SIGNED| D["Fiskaly-Signatur anfordern"]
 C -->|NON_RKSV| E["Beleg ohne Fiskaly-Signatur erzeugen"]
 D --> F["Signed Tagesabschluss"]
 E --> G["Unbarer Block im Tagesabschluss"]
 D --> H["RKSV-Umsatzzaehler"]
 E --> I["Nicht in RKSV-Umsatzzaehler"]
```

## Tagesabschluss: fachliche Sollform

Der Tagesabschluss sollte nicht mehr nur eine einzige Summe zeigen, sondern mindestens zwei Bloecke:

| Block | Inhalt | Wirkung |
| --- | --- | --- |
| Signaturpflichtige Umsaetze | Bar + Karte/Bankomat + alle RKSV-relevanten Transaktionen | Geht in den signierten Tagesbeleg und in den RKSV-Umsatzzaehlweg ein |
| Unbare Umsaetze - Ueberweisung | Zahlung per Ueberweisung | Geht nicht in den signierten RKSV-Umsatzzaehlweg ein, muss aber in der Tagessumme enthalten bleiben |

Die heutige Summe in `daily_close_out_sum` sollte dann fachlich eher als Gesamtabschluss verstanden werden, nicht als alleiniger signierter Block.

### Mermaid: Tagesabschluss-Split

```mermaid
flowchart TD
 A["Abschlusslauf starten"] --> B["Bezahlte Transaktionen laden"]
 B --> C["Nach RksvTurnoverCharacter aufteilen"]
 C --> D["Signaturpflichtige Umsaetze"]
 C --> E["Unbare Umsaetze - Ueberweisung"]
 D --> F["Signierter Tagesbeleg / RKSV-Zaehlweg"]
 E --> G["Separat ausgewiesener Block"]
 D --> H["Tagessumme"]
 E --> H
```

## Rechnungsnummernkreis

Der neue Nummernkreis `RGYYYYMMDD-01...` sollte nicht mit `locationReceiptId` vermischt werden.

Empfehlung:

- eigenes backend-generiertes Sequenzfeld oder eigene Nummerntabelle
- Reset pro Tag, wahrscheinlich pro Location
- keine clientseitige Nummernvergabe
- keine Wiederverwendung des bestehenden RKSV-Receipt-Zaehlers

Wenn der Fakturaweg extern geloesst wird, soll dieser Nummernkreis dort verwaltet werden. Wenn die Kasse den Beleg erzeugt, braucht der Kassen-Backend-Pfad eine separate Nummernquelle.

## Likely Touchpoints

| Layer | Vermutlich betroffene Stellen |
| --- | --- |
| Shared proto | `shared/protocol-buffer/src/main/resources/proto/shared/enums.proto`, `shared/protocol-buffer/src/main/resources/proto/order/payment.proto`, `shared/protocol-buffer/src/main/resources/proto/statistics/statistics.proto`, `shared/protocol-buffer/src/main/resources/proto/shared/requests.proto` |
| Flutter UI | `apps/components/ops_client_commons_component/lib/src/staff_admin_commons/feature/payment/payment_calculator_dialog/*`, `apps/components/ops_client_commons_component/lib/src/protocol_buffers_v2_0/facade/payment_type_facade.dart` |
| Receipt / printer | `apps/components/ops_client_commons_component/lib/src/printer/mapper/printer_mapper_payment_receipt.dart`, `apps/components/ops_client_commons_component/lib/src/printer/mapper/printer_mapper_daily_closure_receipt.dart`, `apps/components/ops_client_commons_component/lib/src/staff_admin_commons/service/receipt_invoice_pdf_generator.dart` |
| Payment service | `services/payment-service/src/main/java/at/sop/services/PaymentTransactionApplicationService.java`, `services/payment-service/src/main/java/at/sop/services/FiskalySignService.java`, `services/payment-service/src/main/java/at/sop/helper/FonChecker.java`, `services/payment-service/src/main/java/at/sop/services/DailyCloseOutService.java`, `services/payment-service/src/main/java/at/sop/queries/DailyCloseOutQueries.java` |
| Statistics / PDF | `services/statistics-service/src/main/java/at/sop/grpc/StatisticsGrpcService.java`, `services/statistics-service/src/main/java/at/sop/services/PaymentTypeStatisticService.java`, `services/pdf-service/src/main/java/at/sop/pdf/services/DailyCloseOutPdfDataLoader.java`, `services/pdf-service/src/main/java/at/sop/pdf/services/StatisticsMonthlyOverviewPdfService.java` |

## Open Questions Und Recommended Answers

1. Soll eine echte Zielrechnung ueberhaupt noch durch die Kasse laufen?
 - Empfehlung: nein, wenn es wirklich eine Zielrechnung ist, dann geh in das Fakturasystem. Das ist buchhalterisch am saubersten.

2. Falls die Kasse den Beleg erzeugen muss: soll `Ueberweisung` als sichtbare Zahlungsart eingefuehrt werden?
 - Empfehlung: ja, aber nur zusammen mit einem expliziten Nicht-RKSV-Charakter. Ein reiner UI-Text reicht nicht.

3. Darf `Ueberweisung` einfach als `HOUSE`, `SERVICE` oder `CASH` modelliert werden?
 - Empfehlung: nein. `HOUSE` und `SERVICE` sind bereits fachlich belegt und `CASH` wuerde den Umsatz falsch labeln.

4. Soll `Ueberweisung` signiert werden?
 - Empfehlung: nein. Der Punkt der Anforderung ist gerade, dass dieser Umsatz nicht in den signierten RKSV-Zaehlweg faellt.

5. Soll `Ueberweisung` im Tagesabschluss sichtbar sein?
 - Empfehlung: ja. Sie muss in der Tagessumme enthalten sein, aber getrennt vom signaturpflichtigen Block.

6. Soll der neue Nummernkreis `RGYYYYMMDD-01...` den bestehenden Receipt-Zaehler ersetzen?
 - Empfehlung: nein. Es braucht einen separaten Nummernkreis fuer Rechnungen oder unbare Belege.

7. Soll der neue Zahlungsmodus nur im Standard-Checkout erscheinen?
 - Empfehlung: nein, nur dort, wo fachlich echte Zielrechnungen entstehen. Sonst ist die Gefahr gross, dass Personal den Sonderfall als Normalfall benutzt.

8. Sollen die normalen Karten- und Barumsaetze veraendert werden?
 - Empfehlung: nein. `CASH`, `CREDIT` und `DEBIT` bleiben RKSV-relevant und sollten unveraendert weiterlaufen.

## Verifikation

Wenn diese Aenderung umgesetzt wird, sollten mindestens diese Faelle pruefbar sein:

- `Ueberweisung` wird in der Kasse sichtbar und als eigene Zahlungsart gespeichert
- der Beleg fuer `Ueberweisung` enthaelt den Hinweis `Unbarer Umsatz - Zahlung per Ueberweisung`
- der Beleg wird nicht mit Fiskaly signiert
- der Tagesabschluss zeigt einen getrennten Block fuer `Ueberweisung`
- der RKSV-Umsatzzaehler enthaelt nur den signaturpflichtigen Block
- die neue Rechnungsnummer ist getrennt vom RKSV-Receipt-Zaehler

## Fazit

Die fachlich saubere Loesung ist nicht nur ein neues Label in der Kasse.

Es braucht entweder:

- den echten Zielrechnungsweg ueber das Fakturasystem

oder, falls die Kasse den Beleg erzeugen muss:

- einen sichtbaren Zahlungsmodus `Ueberweisung`
- einen expliziten Nicht-RKSV-Charakter auf Transaktionsebene
- getrennte Signatur- und Tagesabschlusslogik
- einen separaten Rechnungsnummernkreis

Ohne diese Trennung wuerde die Implementierung zwar die Oberflaeche erweitern, aber die fachliche Wirkung wuerde weiterhin falsch bleiben.
