diff --git a/Abrechnung/module.php b/Abrechnung/module.php index c9b7701..a553ec2 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -248,75 +248,87 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) IPS_LogMessage('Abrechnung', "Meter {$meter['name']} ($type) von " . date('d.m.Y H:i', $from) . " bis " . date('d.m.Y H:i', $to) . ": start=$startValTotal, end=$endValTotal"); - if ($startValTotal === null || $endValTotal === null) return ['row' => '', 'value' => 0]; + if ($startValTotal === null || $endValTotal === null) { + return ['row' => '', 'value' => 0]; + } $totalDiff = max(0, $endValTotal - $startValTotal); - if ($totalDiff <= 0) return ['row' => '', 'value' => 0]; + if ($totalDiff <= 0) { + return ['row' => '', 'value' => 0]; + } $rows = ''; $totalCost = 0.0; - $foundTariff = false; - foreach ($tariffs as $t) { - // Einheit auflösen (ignoriere Groß/Kleinschreibung, evtl. Synonyme) - $unitType = strtolower($t['unit_type']); - $meterType = strtolower($type); - if ($meterType === 'strombezug') $meterType = 'strom'; - if ($meterType === 'warmwasser') $meterType = 'wasser'; - if ($unitType !== $meterType) continue; + // Filtere Tarife nur für den relevanten Typ (z. B. Strom / Wasser) + $tariffs = array_filter($tariffs, function($t) use ($type) { + return strtolower($t['unit_type']) == strtolower($type); + }); - $tariffStart = strtotime($t['start']); - $tariffEnd = strtotime($t['end']); + // Sortiere Tarife chronologisch + usort($tariffs, function($a, $b) { + return strtotime($a['start']) <=> strtotime($b['start']); + }); - // Überschneidung - $sectionStart = max($from, $tariffStart); - $sectionEnd = min($to, $tariffEnd); - if ($sectionEnd <= $sectionStart) continue; + $currentStart = $from; + $currentStartVal = $startValTotal; - $sectionFraction = ($sectionEnd - $sectionStart) / ($to - $from); - $sectionDiff = $totalDiff * $sectionFraction; + while ($currentStart < $to) { + // passenden Tarif zum aktuellen Zeitpunkt finden + $activeTariff = null; + foreach ($tariffs as $t) { + $tariffStart = strtotime($t['start']); + $tariffEnd = strtotime($t['end']); + if ($currentStart >= $tariffStart && $currentStart < $tariffEnd) { + $activeTariff = $t; + break; + } + } - $sectionStartVal = $startValTotal + $totalDiff * (($sectionStart - $from) / ($to - $from)); - $sectionEndVal = $sectionStartVal + $sectionDiff; + if ($activeTariff === null) { + // kein Tarif gefunden – nehme Nulltarif bis zum nächsten bekannten Start oder Ende + $nextTariffStart = $to; + foreach ($tariffs as $t) { + $ts = strtotime($t['start']); + if ($ts > $currentStart && $ts < $nextTariffStart) { + $nextTariffStart = $ts; + } + } + $segmentEnd = min($nextTariffStart, $to); + $segmentTariff = 0.0; + } else { + $segmentEnd = min(strtotime($activeTariff['end']), $to); + $segmentTariff = floatval($activeTariff['price']); + } - $tariffRp = floatval($t['price']); // Preis in Rappen pro Einheit - $costCHF = ($tariffRp / 100) * $sectionDiff; + // Verbrauchsanteil über Zeitverhältnis + $segmentFraction = ($segmentEnd - $currentStart) / ($to - $from); + $segmentDiff = $totalDiff * $segmentFraction; + + $segmentStartVal = $currentStartVal; + $segmentEndVal = $segmentStartVal + $segmentDiff; + + $segmentCostCHF = ($segmentTariff / 100) * $segmentDiff; $rows .= "