false, 'qrCodeHeight' => 75, 'qrCodeWidth' => 75, 'version' => -1, 'quietzoneSize' => 1 ]); $Epi = new Epirent(); const APP_TZ = 'Europe/Berlin'; /** Hilfsfunktionen für die Row-Marking-Logik (ohne weitere Änderungen am Rest) */ function dt(?string $s): ?DateTimeImmutable { if (!$s) return null; try { return new DateTimeImmutable($s, new DateTimeZone(APP_TZ)); } catch (Throwable $e) { return null; } } function dayStart(DateTimeImmutable $d): DateTimeImmutable { return $d->setTime(0, 0, 0); } function resolveRowMarkDate($packingjob, $VorbereitungsTimeDetail, $PackingNoteDetail, int $source): ?DateTimeImmutable { $candidate = null; switch ($source) { case 1: $candidate = dt($packingjob->date_start ?? null); break; case 2: $candidate = dt($VorbereitungsTimeDetail->date_start ?? null); break; case 3: $candidate = dt($PackingNoteDetail->date_packing ?? null); break; case 4: $candidate = dt($PackingNoteDetail->date_delivery ?? null); break; default: $candidate = null; break; } if (!$candidate) { $candidate = dt($packingjob->date_start ?? null); } return $candidate ? dayStart($candidate) : null; } 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 ''; } if (UseDeliveredForCheckOutCompleted) { $result = $Epi->requestEpiApi('/v1/packingnote/open?isci=true&cl=' . Epirent_Mandant); } else { $result = $Epi->requestEpiApi('/v1/packingnote/open?isci=False&cl=' . Epirent_Mandant); } $data_output = json_decode($result)->payload; if (SortCheckOut == 2) { // Prüfen, ob $data_output ein Array ist if (is_array($data_output)) { usort($data_output, function ($a, $b) { // Konvertiere time_start von Millisekunden in Sekunden $timeStartA = $a->time_start / 1000; // Zeit in Sekunden $timeStartB = $b->time_start / 1000; // Kombiniere date_start mit time_start $datetimeA = strtotime($a->date_start) + $timeStartA; $datetimeB = strtotime($b->date_start) + $timeStartB; // Vergleich für die Sortierung return $datetimeA <=> $datetimeB; }); // Sortierte Daten ausgeben oder weiterverarbeiten // print_r($data_output); } else { echo "Daten konnten nicht verarbeitet werden."; } } foreach ($data_output as $packingjob) { $PackingNoteDetail = null; if ($packingjob->is_archived != true && UseDeliveredForCheckOutCompleted) { $PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant); $PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0]; } if ( ($packingjob->is_archived ?? false) != true && ( ((int)($PackingNoteDetail->is_all_out ?? 0)) !== 0 || (($PackingNoteDetail->date_delivered ?? "0000-00-00") === "0000-00-00" || (int)($PackingNoteDetail->time_delivered ?? 0) === 0) ) ) { //get OrderDetails $result = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant); $orderdetail_output = json_decode($result)->payload[0]; // get PackingNote Details, aber nur wenn nicht schon vor der schleife geholt. if (!UseDeliveredForCheckOutCompleted) { $PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant); $PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0]; } $VorbereitungsTimeDetail = null; foreach ($orderdetail_output->order_schedule as $scheduledetail) { if ($scheduledetail->name == Vorbereitungs_Zeitvariable) { $VorbereitungsTimeDetail = $scheduledetail; } } // --- Row-Marking Datum bestimmen (konfigurierbar) --- $today = dayStart(new DateTimeImmutable('today', new DateTimeZone(APP_TZ))); $todayFilter = $today; // für die Window-Berechnung $limit = null; if (CheckOut_FutureDays != -1) { $limit = $todayFilter->modify('+' . (int) CheckOut_FutureDays . ' day'); } $markDate = resolveRowMarkDate($packingjob, $VorbereitungsTimeDetail, $PackingNoteDetail, (int) CheckOutRowMarkSource); if (CheckOut_FutureDays == -1 || ($markDate && $markDate <= $limit)) { $trClass = rowClassForDate($markDate, $today); if ($trClass) { echo ""; } else { echo ""; } if (Enable_QR_Code_CheckOut) { echo "" . '
' . (new QRCode($options))->render($packingjob->packingnote_no) . "
"; } else { echo "" . $packingjob->packingnote_no . ""; } echo "" . $packingjob->contact->name . ""; echo "" . $packingjob->event . ""; if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout) { echo "";} if (ShowCheckoutTimeOnCheckout && $packingjob->date_start != null) { echoMarkedTimeLine($packingjob->date_start, (int) $packingjob->time_start, $today, ShowTimesOnCheckout); } if (ShowVorbereitungTimeOnCheckout && $VorbereitungsTimeDetail && $VorbereitungsTimeDetail->date_start != null) { if (ShowCheckoutTimeOnCheckout) { echo "
"; } echoMarkedTimeLine($VorbereitungsTimeDetail->date_start, (int) $VorbereitungsTimeDetail->time_start, $today, ShowTimesOnCheckout); } if (ShowPackagingTimeOnCheckout && $PackingNoteDetail && $PackingNoteDetail->date_packing != null) { if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout) { echo "
"; } echoMarkedTimeLine($PackingNoteDetail->date_packing, (int) $PackingNoteDetail->time_packing, $today, ShowTimesOnCheckout); } if (ShowDeliveryTimeOnCheckout && $PackingNoteDetail && $PackingNoteDetail->date_delivery != null) { if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout) { echo "
"; } echoMarkedTimeLine($PackingNoteDetail->date_delivery, (int) $PackingNoteDetail->time_delivery, $today, ShowTimesOnCheckout); } if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout) { echo ""; } echo ""; if ($packingjob->is_all_out == 0) { echo ""; } else { echo '
'; echo ""; } echo ($packingjob->pieces_sum_total - abs($packingjob->is_all_out)) . "/" . $packingjob->pieces_sum_total; echo ""; if (ShowShippingIcons) { if (UseShippingStatus) { if (($PackingNoteDetail->status == ShippingOutOrganizedStatus) || ($PackingNoteDetail->status == ShippingOrganizedStatus)) { echo ""; } else { echo ""; } if ($PackingNoteDetail->is_self_pickup) { echo ''; } else { if (preg_match('/' . KurierContainsText . '/i', $PackingNoteDetail->shipping_out)) { echo ''; } if (preg_match('/' . SpeditionContainsText . '/i', $PackingNoteDetail->shipping_out)) { echo ''; } if (preg_match('/' . DHLContainsText . '/i', $PackingNoteDetail->shipping_out)) { echo ''; } if (preg_match('/' . LKWContainsText . '/i', $PackingNoteDetail->shipping_out)) { echo ''; } if (preg_match('/' . TransporterContainsText . '/i', $PackingNoteDetail->shipping_out)) { echo ''; } if (preg_match('/' . PKWContainsText . '/i', $PackingNoteDetail->shipping_out)) { echo ''; } } echo ""; } echo ""; } echo ""; } } } function echoMarkedTimeLine(?string $dateStr, ?int $timeSeconds, DateTimeImmutable $today, $ReturnTime): void { if (!$dateStr) return; $d = dt($dateStr); if (!$d) return; $mark = dayStart($d); $cls = rowClassForDate($mark, $today); echo $cls ? "" : ""; echo date_format(new \DateTime($dateStr), 'd.m.Y'); if($ReturnTime){echo " ".getTimeFromSeconds((string) $timeSeconds);} echo $cls ? "" : ""; } function getTimeFromSeconds(string $timestring) { $hours = floor($timestring / 3600); $mins = floor($timestring / 60 % 60); $secs = floor($timestring % 60); $timeFormat = sprintf('%02d:%02d', $hours, $mins); return $timeFormat; } ?>