From f23fabd46027d40f52be1ebd77dfc6a7d10c2265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=A4fliger?= Date: Wed, 5 Nov 2025 14:14:22 +0100 Subject: [PATCH] no message --- Abrechnung/module.php | 120 +++++++++++++----------------------------- 1 file changed, 38 insertions(+), 82 deletions(-) diff --git a/Abrechnung/module.php b/Abrechnung/module.php index 72a1816..74b2a96 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -295,17 +295,14 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) $totalCost = 0.0; $varId = $meter['var_consumption']; - IPS_LogMessage('Abrechnung', "🔧 [AddMeterToPDFRow] Starte für '{$meter['name']}' (Typ: {$type}) von " . date('d.m.Y H:i', $from) . " bis " . date('d.m.Y H:i', $to)); - if (!IPS_VariableExists($varId)) { IPS_LogMessage('Abrechnung', "❌ Variable {$varId} für {$meter['name']} nicht gefunden"); return ['row' => '', 'value' => 0]; } - // Zeitzone setzen, um strtotime()-Abweichungen zu vermeiden date_default_timezone_set('Europe/Zurich'); - // 1️⃣ Relevante Tarife nach Typ filtern + // 🔹 Tarife nach Typ filtern $filteredTariffs = array_filter($tariffs, function ($t) use ($type) { return strtolower(trim($t['unit_type'] ?? '')) === strtolower(trim($type)); }); @@ -315,24 +312,10 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) return ['row' => '', 'value' => 0]; } - // 2️⃣ Zeitstempel konvertieren, JSON-Objekte erkennen & sortieren + // 🔹 Zeitstempel normieren und sortieren foreach ($filteredTariffs as &$t) { - // JSON-Fix: Start/Ende evtl. verschachtelt - if (is_string($t['start']) && str_starts_with(trim($t['start']), '{')) { - $s = json_decode($t['start'], true); - if (is_array($s)) { - $t['start'] = sprintf('%04d-%02d-%02d 00:00:00', $s['year'], $s['month'], $s['day']); - } - } - if (is_string($t['end']) && str_starts_with(trim($t['end']), '{')) { - $e = json_decode($t['end'], true); - if (is_array($e)) { - $t['end'] = sprintf('%04d-%02d-%02d 23:59:59', $e['year'], $e['month'], $e['day']); - } - } - - $t['start_ts'] = is_numeric($t['start']) ? intval($t['start']) : strtotime($t['start']); - $t['end_ts'] = is_numeric($t['end']) ? intval($t['end']) : strtotime($t['end']); + $t['start_ts'] = $this->toUnixTs($t['start'], false); + $t['end_ts'] = $this->toUnixTs($t['end'], true); if (!$t['start_ts'] || !$t['end_ts']) { IPS_LogMessage('Abrechnung', "⚠ Ungültiger Tarifzeitraum: " . json_encode($t)); @@ -346,37 +329,23 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) } } unset($t); - usort($filteredTariffs, fn($a, $b) => $a['start_ts'] <=> $b['start_ts']); + usort($filteredTariffs, fn($a, $b) => ($a['start_ts'] ?? 0) <=> ($b['start_ts'] ?? 0)); - // 3️⃣ Abrechnungslogik $currentStart = $from; $segmentIndex = 1; while ($currentStart < $to) { - IPS_LogMessage('Abrechnung', "➡️ Segment {$segmentIndex} Startzeit: " . date('d.m.Y H:i', $currentStart)); - - // 🔹 Aktiven Tarif bestimmen (FIX: <= auch am Ende erlaubt) + // 🔹 Aktiven Tarif finden $activeTariff = null; foreach ($filteredTariffs as $t) { - $startTs = intval($t['start_ts']); - $endTs = intval($t['end_ts']); - if ($startTs === 0 || $endTs === 0) continue; - - if ($startTs <= $currentStart && $currentStart <= $endTs) { + if (($t['start_ts'] ?? 0) <= $currentStart && $currentStart <= ($t['end_ts'] ?? 0)) { $activeTariff = $t; - IPS_LogMessage('Abrechnung', sprintf( - " ✅ Tarif erkannt: %.2f Rp gültig %s → %s", - floatval($t['price']), - date('d.m.Y H:i', $startTs), - date('d.m.Y H:i', $endTs) - )); break; } } - // 🔹 Falls kein aktiver Tarif → 0 Rp if (!$activeTariff) { - IPS_LogMessage('Abrechnung', "⚠ Kein Tarif aktiv bei " . date('d.m.Y H:i', $currentStart) . " → 0 Rp"); + IPS_LogMessage('Abrechnung', "⚠ Kein Tarif aktiv bei " . date('d.m.Y H:i', $currentStart)); $activeTariff = [ 'start_ts' => $currentStart, 'end_ts' => $to, @@ -389,45 +358,34 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) $tariffPrice = floatval($activeTariff['price']); $tariffLabel = number_format($tariffPrice, 2, ',', ''); - // 🔹 Start- & Endwerte aus Archiv + // 🔹 Werte lesen $startValue = $this->GetValueAt($varId, $currentStart, true); - if ($startValue === null) { - IPS_LogMessage('Abrechnung', "⚠ Kein Startwert für " . date('d.m.Y H:i', $currentStart)); - break; - } - $segmentEnd = ($tariffEnd < $to) ? $tariffEnd : $to; - $endValue = $this->GetValueAt($varId, $segmentEnd, true); - if ($endValue === null) { - IPS_LogMessage('Abrechnung', "⚠ Kein Endwert für " . date('d.m.Y H:i', $segmentEnd)); + $endValue = $this->GetValueAt($varId, $segmentEnd, true); + + if ($startValue === null || $endValue === null) { + IPS_LogMessage('Abrechnung', "⚠ Keine Werte für {$meter['name']} im Zeitraum " . date('d.m.Y H:i', $currentStart)); break; } - // 🔹 Verbrauch & Kosten $verbrauch = max(0, $endValue - $startValue); $kosten = round(($tariffPrice / 100) * $verbrauch, 2); $totalCost += $kosten; - IPS_LogMessage('Abrechnung', sprintf( - " 📊 Segment %d: %.3f → %.3f (Δ=%.3f) | Tarif=%.3f Rp | Kosten=%.2f CHF", - $segmentIndex, $startValue, $endValue, $verbrauch, $tariffPrice, $kosten - )); - - // 🔹 Tabellenzeile + // 🔹 Tabellenzeile formatiert $rows .= " - - {$meter['name']} - {$type} - " . date('d.m.Y H:i', $currentStart) . " - " . date('d.m.Y H:i', $segmentEnd) . " - " . number_format($startValue, 2) . " - " . number_format($endValue, 2) . " - " . number_format($verbrauch, 2) . " - {$tariffLabel} - " . number_format($kosten, 2) . " + + {$meter['name']} + {$type} + " . date('d.m.Y H:i', $currentStart) . " + " . date('d.m.Y H:i', $segmentEnd) . " + " . number_format($startValue, 2) . " + " . number_format($endValue, 2) . " + " . number_format($verbrauch, 2) . " + " . $tariffLabel . " + " . number_format($kosten, 2) . " "; - // 🔹 Neuen Startpunkt setzen (FIX: +1 Sekunde nach Tarifende) if ($tariffEnd < $to) { $currentStart = $tariffEnd + 1; } else { @@ -437,29 +395,27 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) $segmentIndex++; } - // Fallback, falls keine Segmente erzeugt wurden + // Fallback – kein Segment berechnet if ($rows === '') { - IPS_LogMessage('Abrechnung', "⚠ Keine Segmente erzeugt, Fallback auf Gesamtzeitraum"); - $startValue = $this->GetValueAt($varId, $from, false); - $endValue = $this->GetValueAt($varId, $to, true); - $verbrauch = max(0, $endValue - $startValue); + $startVal = $this->GetValueAt($varId, $from, false); + $endVal = $this->GetValueAt($varId, $to, true); + $verbrauch = max(0, $endVal - $startVal); $rows = " - {$meter['name']} - {$type} - " . date('d.m.Y H:i', $from) . " - " . date('d.m.Y H:i', $to) . " - " . number_format($startValue, 2) . " - " . number_format($endValue, 2) . " - " . number_format($verbrauch, 2) . " - 0 - 0.00 + {$meter['name']} + {$type} + " . date('d.m.Y H:i', $from) . " + " . date('d.m.Y H:i', $to) . " + " . number_format($startVal, 2) . " + " . number_format($endVal, 2) . " + " . number_format($verbrauch, 2) . " + 0.00 + 0.00 "; } - IPS_LogMessage('Abrechnung', sprintf("✅ [AddMeterToPDFRow] Fertig: %.2f CHF total, %d Segmente", $totalCost, $segmentIndex - 1)); - return ['row' => $rows, 'value' => $totalCost]; } + } \ No newline at end of file