diff --git a/Abrechnung/module.php b/Abrechnung/module.php index b9344ae..ddc4fcb 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -95,11 +95,10 @@ class Abrechnung extends IPSModule $pdf->SetAutoPageBreak(true, 20); $pdf->SetFont('dejavusans', '', 9); - foreach ($users as $user) { - $pdf->AddPage(); - $html = $this->BuildUserInvoice($user, $power, $water, $tariffs, $from, $to); - $pdf->writeHTML($html); - } + foreach ($users as $user) { + IPS_LogMessage('Abrechnung', '→ Erstelle Seite für Benutzer: ' . $user['name']); + $this->BuildUserInvoice($pdf, $user, $power, $water, $tariffs, $from, $to); + } return $pdf->Output('Abrechnung.pdf', 'S'); } @@ -107,122 +106,104 @@ class Abrechnung extends IPSModule // =========================================================== // 🧱 Layout / PDF-Aufbau pro Benutzerseite // =========================================================== - private function BuildUserInvoice($user, $power, $water, $tariffs, $from, $to) + private function CalculatePowerCosts(array $powerMeters, array $tariffs, int $userId, int $from, int $to): array { - $stromRows = ''; - $stromTotal = 0.0; - $stromTariffsUsed = []; + $html = " + + + + + + + + + + + "; + $total = 0.0; - $nebenRows = ''; - $nebenTotal = 0.0; - $nebenTariffsUsed = []; - - // ---------- Stromkosten ---------- - foreach ($power as $m) { - if ($m['user_id'] != $user['id']) continue; - $res = $this->AddMeterToPDFRow($m, $tariffs, $from, $to, 'Strombezug'); - $stromRows .= $res['row']; - $stromTotal += $res['value']; + foreach ($powerMeters as $m) { + if ($m['user_id'] != $userId) continue; + $cost = $this->AddMeterToPDFRow($m, $tariffs, $from, $to, 'Strombezug'); + $html .= $cost['row']; + $total += $cost['value']; } - // ---------- Nebenkosten ---------- - foreach ($water as $m) { - if ($m['user_id'] != $user['id']) continue; + $html .= " + + + + +
ZählerTypStartEndeZählerstand StartZählerstand EndeVerbrauchTarif (Rp)Kosten (CHF)
Total Stromkosten:" . number_format($total, 2) . "

"; + + return ['html' => $html, 'sum' => $total]; +} + +private function CalculatePowerCosts(array $powerMeters, array $tariffs, int $userId, int $from, int $to): array +{ + $html = " + + + + + + + + + + + "; + $total = 0.0; + + foreach ($powerMeters as $m) { + if ($m['user_id'] != $userId) continue; + $cost = $this->AddMeterToPDFRow($m, $tariffs, $from, $to, 'Strombezug'); + $html .= $cost['row']; + $total += $cost['value']; + } + + $html .= " + + + + +
ZählerTypStartEndeZählerstand StartZählerstand EndeVerbrauchTarif (Rp)Kosten (CHF)
Total Stromkosten:" . number_format($total, 2) . "

"; + + return ['html' => $html, 'sum' => $total]; +} + +private function CalculateAdditionalCosts(array $waterMeters, array $tariffs, int $userId, int $from, int $to): array +{ + $html = " + + + + + + + + + + + "; + $total = 0.0; + + foreach ($waterMeters as $m) { + if ($m['user_id'] != $userId) continue; $type = $m['meter_type'] ?? 'Warmwasser'; - $res = $this->AddMeterToPDFRow($m, $tariffs, $from, $to, $type); - $nebenRows .= $res['row']; - $nebenTotal += $res['value']; + $cost = $this->AddMeterToPDFRow($m, $tariffs, $from, $to, $type); + $html .= $cost['row']; + $total += $cost['value']; } - // ---------- Alle Tarife gruppieren ---------- - $tariffGroups = []; - foreach ($tariffs as $t) { - $type = ucfirst(strtolower($t['unit_type'] ?? 'Unbekannt')); - $sTs = $this->toUnixTs($t['start'], false); - $eTs = $this->toUnixTs($t['end'], true); - if ($sTs && $eTs) { - $period = date('d.m.Y', $sTs) . ' – ' . date('d.m.Y', $eTs); - $price = number_format(floatval($t['price']), 2); - $tariffGroups[$type][] = "{$period}: {$price} Rp"; - } - } - - // ---------- Gesamtsummen ---------- - $gesamtTotal = $stromTotal + $nebenTotal; - - // ---------- Tabellenstil ---------- - $tableStyle = "border-collapse:collapse;width:100%;font-size:8px;"; - $cellStyle = "border:0.3px solid #bbb;padding:3px;vertical-align:middle;"; - - // ---------- Kopfbereich ---------- - $html = " -

Rechnung für {$user['name']}

-

{$user['address']}
{$user['city']}

-

Abrechnungszeitraum: " . date('d.m.Y', $from) . " – " . date('d.m.Y', $to) . "

"; - - // ---------- Stromkosten ---------- $html .= " -

⚡ Stromkosten

-
ZählerTypStartEndeZählerstand StartZählerstand EndeVerbrauchTarif (Rp)Kosten (CHF)
- - - - - - - - - - + + + - {$stromRows} - - - - -
ZählerTypStartzeitEndzeitStartEndeVerbrauchTarif (Rp)Kosten (CHF)
Total Nebenkosten:" . number_format($total, 2) . "
Total Stromkosten:" . number_format($stromTotal, 2) . "
"; +
"; - // ---------- Nebenkosten ---------- - $html .= " -

💧 Nebenkosten (Wasser & Wärme)

- - - - - - - - - - - - - {$nebenRows} - - - - -
ZählerTypStartzeitEndzeitStartEndeVerbrauchTarif (Rp)Kosten (CHF)
Total Nebenkosten:" . number_format($nebenTotal, 2) . "
"; - - // ---------- Tarife (alle Typen) ---------- - if (!empty($tariffGroups)) { - $html .= "

📋 Angewendete Tarife

"; - foreach ($tariffGroups as $type => $entries) { - $html .= ""; - foreach ($entries as $line) { - $html .= ""; - } - } - $html .= "
{$type}
{$line}
"; - } - - // ---------- Gesamttotal ---------- - $html .= " -

- 💰 Gesamttotal: " . number_format($gesamtTotal, 2) . " CHF -

"; - - return $html; + return ['html' => $html, 'sum' => $total]; } @@ -302,7 +283,7 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) date_default_timezone_set('Europe/Zurich'); - // 🔹 Passende Tarife nach Typ filtern + // 🔹 Filtere relevante Tarife nach Typ $filteredTariffs = array_filter($tariffs, function ($t) use ($type) { return strtolower(trim($t['unit_type'] ?? '')) === strtolower(trim($type)); }); @@ -312,7 +293,7 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) return ['row' => '', 'value' => 0]; } - // 🔹 Zeitstempel konvertieren und sortieren + // 🔹 Normiere Zeiträume foreach ($filteredTariffs as &$t) { $t['start_ts'] = $this->toUnixTs($t['start'], false); $t['end_ts'] = $this->toUnixTs($t['end'], true); @@ -323,6 +304,7 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) $currentStart = $from; while ($currentStart < $to) { + // 🔹 Aktiven Tarif suchen $activeTariff = null; foreach ($filteredTariffs as $t) { if (($t['start_ts'] ?? 0) <= $currentStart && $currentStart <= ($t['end_ts'] ?? 0)) { @@ -342,32 +324,35 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) $tariffEnd = intval($activeTariff['end_ts']); $tariffPrice = floatval($activeTariff['price']); + $tariffLabel = number_format($tariffPrice, 2, ',', ''); - $startValue = $this->GetValueAt($varId, $currentStart, true); - $segmentEnd = ($tariffEnd < $to) ? $tariffEnd : $to; - $endValue = $this->GetValueAt($varId, $segmentEnd, true); + // 🔹 Werte aus Archiv lesen + $startValue = $this->GetValueAt($varId, $currentStart, true); + $segmentEnd = ($tariffEnd < $to) ? $tariffEnd : $to; + $endValue = $this->GetValueAt($varId, $segmentEnd, true); if ($startValue === null || $endValue === null) break; - $verbrauch = max(0, $endValue - $startValue); - $kosten = round(($tariffPrice / 100) * $verbrauch, 2); - $totalCost += $kosten; + $verbrauch = max(0, $endValue - $startValue); + $kosten = round(($tariffPrice / 100) * $verbrauch, 2); + $totalCost += $kosten; + // 🔹 Kurze Datumsangaben $startDate = date('d.m.Y', $currentStart); $endDate = date('d.m.Y', $segmentEnd); - // 🧾 TCPDF-kompatible Tabellenzeile (sichtbare Linien) + // 🔹 Tabellenzeile mit sichtbaren Linien $rows .= " - - {$meter['name']} - {$type} - {$startDate} - {$endDate} - " . number_format($startValue, 2) . " - " . number_format($endValue, 2) . " - " . number_format($verbrauch, 2) . " - " . number_format($tariffPrice, 2) . " - " . number_format($kosten, 2) . " + + {$meter['name']} + {$type} + {$startDate} + {$endDate} + " . number_format($startValue, 2) . " + " . number_format($endValue, 2) . " + " . number_format($verbrauch, 2) . " + " . $tariffLabel . " + " . number_format($kosten, 2) . " "; if ($tariffEnd < $to) { @@ -377,36 +362,26 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) } } - // Fallback (keine Segmente) + // 🔹 Fallback – kein Segment gefunden if ($rows === '') { $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', $from) . " - " . date('d.m.Y', $to) . " - " . number_format($startVal, 2) . " - " . number_format($endVal, 2) . " - " . number_format($verbrauch, 2) . " - 0.00 - 0.00 + + {$meter['name']} + {$type} + " . date('d.m.Y', $from) . " + " . date('d.m.Y', $to) . " + " . number_format($startVal, 2) . " + " . number_format($endVal, 2) . " + " . number_format($verbrauch, 2) . " + 0.00 + 0.00 "; } - // 🧾 Totalsumme in separater, deutlich sichtbarer Zeile - $rows .= " - - Total {$type}: - " . number_format($totalCost, 2) . " - "; - - // Komplett in eine sichtbare Tabelle einbetten (damit TCPDF Linien rendert) - $table = "{$rows}
"; - - return ['row' => $table, 'value' => $totalCost]; + return ['row' => $rows, 'value' => $totalCost]; }