Fix: Multi-Meter-Verbrauch auf Vertragslaufzeit clampen
Bei Verträgen, die Vorgänger einer Folgevertrags-Kette sind, sind über ContractMeter auch Folgezähler verknüpft, die nach Vertragsende installiert wurden. Die Berechnung nahm cm.installedAt..cm.removedAt 1:1 ohne Clamp gegen Contract.startDate/endDate – damit flossen Zählerstände aus der Folgevertrags-Phase in den Verbrauch dieses Vertrags ein. Fix: meterStart = max(installedAt, contractStart), meterEnd = min(removedAt, contractEnd). Zähler komplett außerhalb der Laufzeit werden übersprungen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -262,13 +262,24 @@ export function calculateMultiMeterConsumption(
|
|||||||
let firstStart: MeterReading | undefined;
|
let firstStart: MeterReading | undefined;
|
||||||
let lastEnd: MeterReading | undefined;
|
let lastEnd: MeterReading | undefined;
|
||||||
|
|
||||||
|
const contractStartMs = new Date(startDate).getTime();
|
||||||
|
const contractEndMs = new Date(endDate).getTime();
|
||||||
|
|
||||||
for (const cm of contractMeters) {
|
for (const cm of contractMeters) {
|
||||||
const readings = cm.meter?.readings || [];
|
const readings = cm.meter?.readings || [];
|
||||||
if (readings.length === 0) continue;
|
if (readings.length === 0) continue;
|
||||||
|
|
||||||
// Zeitraum für diesen Zähler bestimmen
|
// Zeitraum für diesen Zähler bestimmen, GE-CLAMPED auf die Vertragslaufzeit.
|
||||||
const meterStart = cm.installedAt || startDate;
|
// Ohne Clamp würden Folgezähler, die nach Vertragsende installiert wurden
|
||||||
const meterEnd = cm.removedAt || endDate;
|
// (typisch bei Vorgängerverträgen einer Folgevertrags-Kette), zukünftige
|
||||||
|
// Zählerstände in den Verbrauch dieses Vertrags einrechnen.
|
||||||
|
const installedMs = cm.installedAt ? new Date(cm.installedAt).getTime() : contractStartMs;
|
||||||
|
const removedMs = cm.removedAt ? new Date(cm.removedAt).getTime() : contractEndMs;
|
||||||
|
const meterStartMs = Math.max(installedMs, contractStartMs);
|
||||||
|
const meterEndMs = Math.min(removedMs, contractEndMs);
|
||||||
|
if (meterStartMs > meterEndMs) continue; // Zähler liegt komplett außerhalb der Laufzeit
|
||||||
|
const meterStart = new Date(meterStartMs).toISOString();
|
||||||
|
const meterEnd = new Date(meterEndMs).toISOString();
|
||||||
|
|
||||||
const result = calculateConsumption(readings, meterStart, meterEnd, contractType);
|
const result = calculateConsumption(readings, meterStart, meterEnd, contractType);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user