setTime(0, 0, 0); } function rowClassForDate(?DateTimeImmutable $markDate, ?DateTimeImmutable $today): string { if (!$markDate || !$today) return ''; if ($markDate == $today) return 'text-dark bg-warning'; if ($markDate < $today) return 'bg-danger'; return ''; } /** * Row-Marking Quelle (Check-In) – identisch zu deiner Tabelle: * 1 = $packingjob->date_end * 2 = $NachbereitungsTimeDetail->date_start * 3 = $RePackagingTimeDetail->date_start * 4 = $PackingNoteDetail->date_redelivery * Fallback: $packingjob->date_end */ function resolveRowMarkDateCheckIn( $packingjob, $NachbereitungsTimeDetail, $RePackagingTimeDetail, $PackingNoteDetail, int $source ): ?DateTimeImmutable { $candidate = null; switch ($source) { case 1: $candidate = dt($packingjob->date_end ?? null); break; case 2: $candidate = dt($NachbereitungsTimeDetail->date_start ?? null); break; case 3: $candidate = dt($RePackagingTimeDetail->date_start ?? null); break; case 4: $candidate = dt($PackingNoteDetail->date_redelivery ?? null); break; default: $candidate = null; break; } if (!$candidate) { $candidate = dt($packingjob->date_end ?? null); } return $candidate ? dayStart($candidate) : null; } /** ---------- Daten holen (wie in deiner Check-In-Datei) ---------- */ // Offene Packingnotes für Check-IN-Seite: isco=False $result = $Epi->requestEpiApi('/v1/packingnote/open?isco=False&cl=' . Epirent_Mandant); $data_output = json_decode($result)->payload ?? []; /** ---------- Zähler ---------- */ $today = dayStart(new DateTimeImmutable('today', new DateTimeZone(APP_TZ))); $limit = null; if (CheckIn_FutureDays != -1) { $limit = $today->modify('+' . (int)CheckIn_FutureDays . ' day'); } $cntOverdue = 0; $cntToday = 0; $cntFuture = 0; /** ---------- Zählen mit exakt deiner Logik ---------- */ foreach ($data_output as $packingjob) { if ($packingjob->is_archived == true) continue; // OrderDetails (für Nachbereitung / Rückpacken) $orderRes = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant); $orderdetail_output = json_decode($orderRes)->payload[0] ?? null; // PackingNote Details (für Redelivery) $pnRes = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant); $PackingNoteDetail = json_decode($pnRes)->payload[0] ?? null; // Zeit-Slots aus dem Schedule $NachbereitungsTimeDetail = null; $RePackagingTimeDetail = null; if ($orderdetail_output && !empty($orderdetail_output->order_schedule)) { foreach ($orderdetail_output->order_schedule as $scheduledetail) { if ($scheduledetail->name == Nachbereitung_Zeitvariable) { $NachbereitungsTimeDetail = $scheduledetail; } if ($scheduledetail->name == Rückpacken_Zeitvariable) { $RePackagingTimeDetail = $scheduledetail; } } } // Row-Mark Source (mit Override-Flag) $source = CheckIn_UseDispoEndForRowMarking ? 1 : (int)CheckInRowMarkSource; $markDate = resolveRowMarkDateCheckIn( $packingjob, $NachbereitungsTimeDetail, $RePackagingTimeDetail, $PackingNoteDetail, $source ); if (!$markDate) continue; // Fenster berücksichtigen (gleich wie in deiner Tabelle) if (CheckIn_FutureDays != -1 && $limit && $markDate > $limit) { continue; } // Zählen if ($markDate < $today) { $cntOverdue++; } elseif ($markDate == $today) { $cntToday++; } else { $cntFuture++; } } $ts = (new DateTimeImmutable('now', new DateTimeZone(APP_TZ)))->format('H:i:s'); ?>