Endstand alter Zähler fließt in Verbrauchsberechnung ein

Bisher wurde "Letzter Stand alter Zähler" zwar in
ContractMeter.finalReading gespeichert, aber nirgends ausgewertet.

Neuer Helper recordPredecessorFinalReading legt am Wechseldatum
einen regulären MeterReading-Eintrag für den Vorgänger an
(idempotent, mit Validierung gegen vorhandene Stände). Aufgerufen
aus addSuccessorMeter (Vertragsansicht) und createMeter mit
successorOf (Kundenakte).

Folge: Der Endstand erscheint in der Zählerstände-Liste des alten
Zählers und fließt automatisch über calculateMultiMeterConsumption
in den Verbrauch (Zeitraum bis removedAt ist inklusive).

UI-Hinweise in beiden Folgezähler-Forms erklären den Effekt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 14:14:03 +02:00
parent 34e106f253
commit 61ce35821d
5 changed files with 151 additions and 1 deletions
+35
View File
@@ -97,6 +97,41 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
## ✅ Erledigt
- [x] **🆕 Endstand alter Zähler fließt in Verbrauchsberechnung ein**
- Bisher wurde der Wert „Letzter Stand alter Zähler" zwar als
`ContractMeter.finalReading` gespeichert, aber nirgends gelesen
weder in der UI noch in `calculateMultiMeterConsumption`.
- Neuer Helper `recordPredecessorFinalReading(meterId, switchAt, value)`
in customer.service.ts: legt am Wechseldatum einen regulären
`MeterReading`-Eintrag für den Vorgänger an (Notes:
„Endstand bei Zählerwechsel"). Idempotent: existiert am
Wechseltag schon ein Reading, wird nichts geschrieben.
Validierung (monoton-steigend) wird vorab durchgeführt
Konflikt führt zu sprechender 400-Fehlermeldung, ohne
halb-geschriebene Zustände zu hinterlassen.
- Wird aus beiden Pfaden aufgerufen: `addSuccessorMeter` im
contract.controller (Vertragsansicht → „Folgezähler hinzufügen")
und `createMeter` mit `successorOf` im customer.service
(Kundenakte → „Als Folgezähler deklarieren").
- Folge: Der Endstand erscheint jetzt in der Zählerstände-Liste
des Vorgänger-Zählers und fließt über
`calculateMultiMeterConsumption` automatisch in den Verbrauch
(Zeitraum bis `removedAt` ist inklusive).
- UI-Hinweise im Folgezähler-Form (Vertragsansicht + MeterModal)
erklären den neuen Effekt.
- [x] **🆕 Folgezähler-Button auch bei Single-Meter-Verträgen**
- Bisher nur sichtbar im Multi-Meter-Zweig (`contractMeters.length > 0`)
Folgeverträge ohne ContractMeter-Eintrag konnten so keinen
Folgezähler bekommen.
- Fix: Button wird jetzt aus dem if/else-Block gerendert, sobald
entweder ein Single-Meter (`energyDetails.meter`) oder
ContractMeter-Einträge vorhanden sind.
- Im Backend `addSuccessorMeter`: bei Single-Meter-Verträgen wird
der bisherige `energyDetails.meterId` automatisch als
ContractMeter (position 0, `removedAt` = Wechseldatum) backfillt,
damit der alte Zähler nicht aus der Vertragshistorie verschwindet.
- [x] **🆕 Folgezähler-Deklaration in der Kundenakte (Auto-Propagation)**
- **Backend**: Neues Feld `Meter.predecessorMeterId`
(Self-Relation, `ON DELETE SET NULL`). Migration