service = $service; $this->day = $day; $this->today = date('Y-m-d'); $this->actionUrl = $actionUrl; $this->links = $links; } protected static function e($s) { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } public static function longDate($day) { $wd = array('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'); $mo = array(1 => 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'); $t = strtotime($day); return $wd[(int)date('w', $t)].', '.(int)date('j', $t).'. '.$mo[(int)date('n', $t)].' '.date('Y', $t); } /** * @param array|null $flash ['ok' => bool, 'msg' => string, 'undo' => [id, action]] */ public function render($flash = null) { $isToday = $this->day === $this->today; $prev = date('Y-m-d', strtotime($this->day.' -1 day')); $next = date('Y-m-d', strtotime($this->day.' +1 day')); $dayUrl = function ($d) { return $this->actionUrl.'&day='.$d; }; $h = '
'; $h .= '

Rezeption

'.self::e(self::longDate($this->day)) .($isToday ? ' Heute' : '').'

' .'
'; if ($flash) { $h .= '
' .''.($flash['ok'] ? '✓ ' : '✗ ').self::e($flash['msg']).''; if (!empty($flash['undo'])) { $h .= $this->button($flash['undo'][0], $flash['undo'][1], 'Rückgängig', 'fd-btn-light'); } $h .= '
'; } $h .= '
'; if (!empty($this->links['planUrl'])) { $h .= 'Belegungsplan'; } if (!empty($this->links['reserveUrl'])) { $h .= 'Neue Reservierung'; } $h .= '
'; if (!$isToday) { $h .= '

Sie sehen einen anderen Tag. Ein- und Auschecken geht nur heute.

'; } $overdue = $isToday ? $this->service->overdue($this->day) : array(); if ($overdue) { $h .= $this->section('Noch nicht angekommen', 'Diese Gäste hätten schon anreisen sollen.', $overdue, 'arrive', $isToday, 'fd-warn'); } $h .= $this->section('Anreise', 'Gäste, die heute ankommen.', $this->service->arrivals($this->day), 'arrive', $isToday); $h .= $this->section('Abreise', 'Gäste, die heute abreisen. Bezahlt wird an der Kasse.', $this->service->departures($this->day), 'depart', $isToday); $h .= $this->section('Im Haus', 'Gäste, die über Nacht bleiben.', $this->service->inHouse($this->day), 'stay', $isToday); $h .= '
'.self::css(); return $h; } protected function section($title, $sub, array $rows, $kind, $canAct, $extra = '') { $h = '

'.self::e($title).' '.count($rows).'

'.self::e($sub).'

'; if (!$rows) { return $h.'

Niemand.

'; } $h .= ''; } protected function card(array $r, $kind, $canAct) { $name = trim($r['firstname'].' '.$r['lastname']) ?: 'Buchung #'.(int)$r['id_order']; $nights = (int)round((strtotime($r['date_to']) - strtotime($r['date_from'])) / 86400); $people = (int)$r['adults'].' '.((int)$r['adults'] === 1 ? 'Erwachsener' : 'Erwachsene') .((int)$r['children'] ? ', '.(int)$r['children'].' '.((int)$r['children'] === 1 ? 'Kind' : 'Kinder') : ''); $facts = $people.' · '.$nights.' '.($nights === 1 ? 'Nacht' : 'Nächte').' · '.date('d.m.', strtotime($r['date_from'])).'–'.date('d.m.', strtotime($r['date_to'])) .' · '.$r['room_type_name'].($r['source_name'] ? ' · '.$r['source_name'] : ''); $status = (int)$r['id_status']; $action = ''; if ($kind === 'arrive') { if ($status === FrontDeskService::ASSIGNED) { $action = $canAct ? $this->button($r['id'], 'checkin', 'Einchecken', 'fd-btn-go') : 'erwartet'; } else { $action = '✓ Eingecheckt'.($r['check_in'] && $r['check_in'] !== '0000-00-00 00:00:00' ? ' '.date('H:i', strtotime($r['check_in'])) : '').''; } } elseif ($kind === 'depart') { if ($status === FrontDeskService::CHECKED_IN) { $action = $canAct ? $this->button($r['id'], 'checkout', 'Auschecken', 'fd-btn-out') : 'reist ab'; } else { $action = '✓ Ausgecheckt'.($r['check_out'] && $r['check_out'] !== '0000-00-00 00:00:00' ? ' '.date('H:i', strtotime($r['check_out'])) : '').''; } } else { $action = $canAct ? $this->button($r['id'], 'checkout', 'Früher abreisen', 'fd-btn-light') : ''; } $pos = ''; if (isset($r['pos_done'])) { if ((int)$r['pos_failed']) { $pos = 'Kasse: Fehler – bitte Kassenanbindung prüfen'; } elseif ((int)$r['pos_done']) { $pos = 'Kasse: '.(int)$r['pos_done'].' '.((int)$r['pos_done'] === 1 ? 'Nacht' : 'Nächte').' auf Tisch '.self::e($r['room_num']).''; } } $details = !empty($this->links['orderUrl']) && (int)$r['id_order'] ? 'Details' : ''; return '
  • '.self::e($r['room_num']).'
    ' .'
    '.self::e($name).'
    '.self::e($facts).'
    '.$pos.$details.'
    ' .'
    '.$action.'
  • '; } protected function button($idBooking, $action, $label, $class) { return '
    ' .'' .'' .'
    '; } public static function css() { return ''; } }