From 41b0c7afb1c733195f97b54513cfa35074ddead6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=A4fliger?= Date: Wed, 5 Nov 2025 07:08:14 +0100 Subject: [PATCH] no message --- Abrechnung/module.php | 108 +++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 48 deletions(-) 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 .= " {$meter['name']} $type - " . date('d.m.Y H:i', $sectionStart) . " - " . date('d.m.Y H:i', $sectionEnd) . " - " . number_format($sectionStartVal, 2) . " - " . number_format($sectionEndVal, 2) . " - " . number_format($sectionDiff, 2) . " - " . number_format($tariffRp, 2) . " - " . number_format($costCHF, 2) . " + " . date('d.m.Y H:i', $currentStart) . " + " . date('d.m.Y H:i', $segmentEnd) . " + " . number_format($segmentStartVal, 2) . " + " . number_format($segmentEndVal, 2) . " + " . number_format($segmentDiff, 2) . " + " . number_format($segmentTariff, 2) . " + " . number_format($segmentCostCHF, 2) . " "; - $totalCost += $costCHF; - $foundTariff = true; - } - - // Falls kein passender Tarif gefunden - if (!$foundTariff) { - $rows .= " - - {$meter['name']} - $type - " . date('d.m.Y H:i', $from) . " - " . date('d.m.Y H:i', $to) . " - " . number_format($startValTotal, 2) . " - " . number_format($endValTotal, 2) . " - " . number_format($totalDiff, 2) . " - 0 - 0.00 - "; + $totalCost += $segmentCostCHF; + $currentStart = $segmentEnd; + $currentStartVal = $segmentEndVal; } return ['row' => $rows, 'value' => $totalCost]; } - } \ No newline at end of file