no message

This commit is contained in:
2025-11-05 08:43:06 +01:00
parent e7eb56c57c
commit 5b2b24f824

View File

@@ -284,168 +284,131 @@ private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type)
{
$rows = '';
$totalCost = 0.0;
$varId = $meter['var_consumption'];
IPS_LogMessage('Abrechnung', "🔧 [AddMeterToPDFRow] Start für Zähler '{$meter['name']}' (Typ: {$type}), Zeitraum: " . date('d.m.Y H:i', $from) . " - " . date('d.m.Y H:i', $to) . ", VarID={$varId}");
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', " [AddMeterToPDFRow] Variable {$varId} für {$meter['name']} nicht gefunden");
IPS_LogMessage('Abrechnung', "❌ Variable {$varId} für {$meter['name']} nicht gefunden");
return ['row' => '', 'value' => 0];
}
// --- Relevante Tarife nach Typ filtern (LOGGING ONLY) ---
// 1 Relevante Tarife für diese Verbrauchsart finden
$filteredTariffs = array_filter($tariffs, function ($t) use ($type) {
$tariffType = strtolower(trim($t['unit_type'] ?? ''));
$typeNorm = strtolower(trim($type));
$map = [
'strombezug' => ['strom', 'strombezug', 'stromzähler', 'stromverbrauch'],
'warmwasser' => ['warmwasser', 'wasser', 'hww'],
'kaltwasser' => ['kaltwasser', 'wasser', 'kww'],
'wärme' => ['wärme', 'heizung', 'heat']
];
return in_array($tariffType, $map[$typeNorm] ?? []) || $tariffType === $typeNorm;
return strtolower(trim($t['unit_type'] ?? '')) === strtolower(trim($type));
});
IPS_LogMessage('Abrechnung', "🔹 [AddMeterToPDFRow] passende Tarife für '{$type}': " . count($filteredTariffs));
if (empty($filteredTariffs)) {
IPS_LogMessage('Abrechnung', " [AddMeterToPDFRow] Keine passenden Tarife für Typ '{$type}' gefunden → 0 Rp");
IPS_LogMessage('Abrechnung', "⚠ Keine passenden Tarife für {$type} gefunden");
return ['row' => '', 'value' => 0];
}
// --- Tarife sicher in Zeiträume umwandeln (LOGGING ONLY) ---
// 2⃣ Zeitlich sortieren
foreach ($filteredTariffs as &$t) {
$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']);
IPS_LogMessage('Abrechnung', sprintf(
" 🕓 Tariffenster: %s → %s | Preis: %s Rp | unit_type='%s'",
$t['start_ts'] ? date('d.m.Y H:i', $t['start_ts']) : '❌',
$t['end_ts'] ? date('d.m.Y H:i', $t['end_ts']) : '❌',
isset($t['price']) ? str_replace('.', ',', (string)$t['price']) : '❌',
$t['unit_type'] ?? '—'
));
}
unset($t);
// Sortiere Tarife nach Startzeit (unverändert)
usort($filteredTariffs, fn($a, $b) => $a['start_ts'] <=> $b['start_ts']);
$current = $from;
$segIndex = 1;
// 3⃣ Startpunkt setzen
$currentStart = $from;
$segmentIndex = 1;
while ($current < $to) {
IPS_LogMessage('Abrechnung', "➡️ [AddMeterToPDFRow] Segment {$segIndex} START: " . date('d.m.Y H:i', $current));
// Schleife bis Abrechnungsende
while ($currentStart < $to) {
// Finde aktiven Tarif für diesen Zeitpunkt (unverändert)
IPS_LogMessage('Abrechnung', "➡️ Segment $segmentIndex: Beginne bei " . date('d.m.Y H:i', $currentStart));
// 🔹 Nächsten geloggten Wert nach Startzeit holen
$startValue = $this->GetValueAt($varId, $currentStart, true);
if ($startValue === null) {
IPS_LogMessage('Abrechnung', "⚠ Kein Startwert gefunden bei " . date('d.m.Y H:i', $currentStart));
break;
}
// 🔹 Aktiven Tarif bestimmen
$activeTariff = null;
foreach ($filteredTariffs as $t) {
if ($t['start_ts'] <= $current && $current <= $t['end_ts']) {
if ($t['start_ts'] <= $currentStart && $currentStart < $t['end_ts']) {
$activeTariff = $t;
break;
}
}
// Wenn kein aktiver Tarif, nimm nächsten oder rechne 0 Rp (unverändert)
// 🔹 Falls kein Tarif aktiv → 0 Rp
if (!$activeTariff) {
$nextStart = $to;
foreach ($filteredTariffs as $t) {
if ($t['start_ts'] > $current && $t['start_ts'] < $nextStart) {
$nextStart = $t['start_ts'];
}
}
$segmentEnd = min($nextStart, $to);
$tariffPrice = 0.0;
$tariffLabel = 'kein Tarif';
IPS_LogMessage('Abrechnung', " ⚠ Kein aktiver Tarif → 0 Rp bis " . date('d.m.Y H:i', $segmentEnd));
} else {
$segmentEnd = min($activeTariff['end_ts'], $to);
$tariffPrice = floatval($activeTariff['price']);
$tariffLabel = number_format($tariffPrice, 2, ',', '');
IPS_LogMessage('Abrechnung', sprintf(
" ✅ Aktiver Tarif: %.3f Rp | gültig bis %s | SegmentEnd=%s",
$tariffPrice,
date('d.m.Y H:i', $activeTariff['end_ts']),
date('d.m.Y H:i', $segmentEnd)
));
IPS_LogMessage('Abrechnung', "⚠ Kein Tarif aktiv bei " . date('d.m.Y H:i', $currentStart) . " → 0 Rp");
$activeTariff = [
'start_ts' => $currentStart,
'end_ts' => $to,
'price' => 0.0,
'unit_type'=> $type
];
}
// Sicherheitsnetz (unverändert)
if ($segmentEnd <= $current) {
IPS_LogMessage('Abrechnung', " ⚠ segmentEnd <= current (" . date('d.m.Y H:i', $segmentEnd) . " <= " . date('d.m.Y H:i', $current) . "), Abbruch der Schleife.");
$tariffEnd = $activeTariff['end_ts'];
$tariffPrice = floatval($activeTariff['price']);
$tariffLabel = number_format($tariffPrice, 2, ',', '');
IPS_LogMessage('Abrechnung', sprintf(
" 🧾 Aktiver Tarif: %.3f Rp (%s - %s)",
$tariffPrice,
date('d.m.Y H:i', $activeTariff['start_ts']),
date('d.m.Y H:i', $activeTariff['end_ts'])
));
// 🔹 Prüfen, ob Tarif vor Abrechnungsende endet
if ($tariffEnd < $to) {
// Tarif endet vor Rechnungsende → Segment bis Tarifende abrechnen
$segmentEnd = $tariffEnd;
} else {
// Tarif reicht bis oder über Rechnungsende → letztes Segment
$segmentEnd = $to;
}
// 🔹 Nächsten Archivwert nach Segmentende lesen
$endValue = $this->GetValueAt($varId, $segmentEnd, true);
if ($endValue === null) {
IPS_LogMessage('Abrechnung', "⚠ Kein Endwert gefunden bei " . date('d.m.Y H:i', $segmentEnd));
break;
}
// --- Verbrauch für diesen Zeitraum (unverändert) ---
IPS_LogMessage('Abrechnung', " 🔎 Hole Startwert @ " . date('d.m.Y H:i', $current) . " (nearestAfter=true)");
$startVal = $this->GetValueAt($varId, $current, true);
IPS_LogMessage('Abrechnung', " 🔎 Hole Endwert @ " . date('d.m.Y H:i', $segmentEnd) . " (nearestAfter=true)");
$endVal = $this->GetValueAt($varId, $segmentEnd, true);
if ($startVal === null || $endVal === null) {
IPS_LogMessage('Abrechnung', " ⚠ Keine Werte gefunden (startVal=" . var_export($startVal, true) . ", endVal=" . var_export($endVal, true) . ") → Segment übersprungen");
$current = $segmentEnd + 1;
$segIndex++;
continue;
}
$diff = max(0, $endVal - $startVal);
$costCHF = round(($tariffPrice / 100) * $diff, 2);
$totalCost += $costCHF;
// 🔹 Verbrauch und Kosten
$verbrauch = max(0, $endValue - $startValue);
$kosten = round(($tariffPrice / 100) * $verbrauch, 2);
$totalCost += $kosten;
IPS_LogMessage('Abrechnung', sprintf(
" 📊 Segment %d: Start=%.3f, Ende=%.3f, Verbrauch=%.3f, Tarif=%s, Kosten=%.2f CHF",
$segIndex, $startVal, $endVal, $diff, $tariffLabel, $costCHF
" 📊 Segment %d: Start=%.3f, Ende=%.3f, Verbrauch=%.3f, Tarif=%.3f Rp → %.2f CHF",
$segmentIndex, $startValue, $endValue, $verbrauch, $tariffPrice, $kosten
));
// --- Ausgabezeile (unverändert) ---
// 🔹 Zeile erzeugen
$rows .= "
<tr>
<td>{$meter['name']}</td>
<td>{$type}</td>
<td>" . date('d.m.Y H:i', $current) . "</td>
<td>" . date('d.m.Y H:i', $currentStart) . "</td>
<td>" . date('d.m.Y H:i', $segmentEnd) . "</td>
<td>" . number_format($startVal, 2) . "</td>
<td>" . number_format($endVal, 2) . "</td>
<td>" . number_format($diff, 2) . "</td>
<td>" . $tariffLabel . "</td>
<td>" . number_format($costCHF, 2) . "</td>
<td>" . number_format($startValue, 2) . "</td>
<td>" . number_format($endValue, 2) . "</td>
<td>" . number_format($verbrauch, 2) . "</td>
<td>{$tariffLabel}</td>
<td>" . number_format($kosten, 2) . "</td>
</tr>";
$current = $segmentEnd + 1; // unverändert
$segIndex++;
// 🔹 Falls Tarif endet → nächster Zyklus startet am Ende des Tarifs
if ($tariffEnd < $to) {
$currentStart = $tariffEnd;
} else {
break; // Letztes Segment erreicht
}
$segmentIndex++;
}
// --- Falls nichts berechnet wurde (unverändert) ---
if ($rows == '') {
IPS_LogMessage('Abrechnung', "⚠ [AddMeterToPDFRow] Keine Segmente berechnet Fallback-Zeile mit 0 Rp");
$startVal = $this->GetValueAt($varId, $from, false);
$endVal = $this->GetValueAt($varId, $to, true);
$diff = max(0, $endVal - $startVal);
IPS_LogMessage('Abrechnung', sprintf(
" 🔁 Fallback: Start=%.3f (@%s), Ende=%.3f (@%s), Verbrauch=%.3f",
$startVal, date('d.m.Y H:i', $from),
$endVal, date('d.m.Y H:i', $to),
$diff
));
$rows = "
<tr>
<td>{$meter['name']}</td>
<td>{$type}</td>
<td>" . date('d.m.Y H:i', $from) . "</td>
<td>" . date('d.m.Y H:i', $to) . "</td>
<td>" . number_format($startVal, 2) . "</td>
<td>" . number_format($endVal, 2) . "</td>
<td>" . number_format($diff, 2) . "</td>
<td>0</td>
<td>0.00</td>
</tr>";
}
IPS_LogMessage('Abrechnung', sprintf("✅ [AddMeterToPDFRow] Fertig für '%s' (%s): Total=%.2f CHF",
$meter['name'], $type, $totalCost
));
IPS_LogMessage('Abrechnung', sprintf("✅ [AddMeterToPDFRow] Fertig: %.2f CHF total, %d Segmente", $totalCost, $segmentIndex - 1));
return ['row' => $rows, 'value' => $totalCost];
}