idLang = $idLang ?: (int)Configuration::get('PS_LANG_DEFAULT'); } protected function select($where, $order) { $hasCaspos = (bool)Db::getInstance()->getValue('SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = \''._DB_PREFIX_.'casposbridge_job\''); $sql = 'SELECT bd.`id`, bd.`id_order`, bd.`id_room`, bd.`room_num`, bd.`room_type_name`, bd.`id_status`, bd.`adults`, bd.`children`, DATE(bd.`date_from`) AS date_from, DATE(bd.`date_to`) AS date_to, bd.`check_in`, bd.`check_out`, c.`firstname`, c.`lastname`, c.`email`, o.`reference`, srcl.`name` AS source_name, src.`code` AS source_code' .($hasCaspos ? ', (SELECT COUNT(*) FROM `'._DB_PREFIX_.'casposbridge_job` j WHERE j.`id_htl_booking` = bd.`id` AND j.`status` = \'done\') AS pos_done, (SELECT COUNT(*) FROM `'._DB_PREFIX_.'casposbridge_job` j WHERE j.`id_htl_booking` = bd.`id` AND j.`status` = \'failed\') AS pos_failed' : '').' FROM `'._DB_PREFIX_.'htl_booking_detail` bd LEFT JOIN `'._DB_PREFIX_.'customer` c ON c.`id_customer` = bd.`id_customer` LEFT JOIN `'._DB_PREFIX_.'orders` o ON o.`id_order` = bd.`id_order` LEFT JOIN `'._DB_PREFIX_.'source` src ON src.`id_source` = o.`id_source` LEFT JOIN `'._DB_PREFIX_.'source_lang` srcl ON srcl.`id_source` = src.`id_source` AND srcl.`id_lang` = '.(int)$this->idLang.' WHERE bd.`is_back_order` = 0 AND '.$where .(method_exists('OrderReturn', 'getRefundedBookingIdsSubquery') ? ' AND bd.`id` NOT IN ('.OrderReturn::getRefundedBookingIdsSubquery().')' : '') .' ORDER BY '.$order; return (array)Db::getInstance()->executeS($sql); } /** Guests arriving on $day: still to check in, and those already checked in that day. */ public function arrivals($day) { return $this->select('DATE(bd.`date_from`) = \''.pSQL($day).'\' AND bd.`id_status` IN ('.self::ASSIGNED.', '.self::CHECKED_IN.')', 'bd.`id_status`, bd.`room_num`'); } /** Guests due to leave on $day (still in house) and those already checked out that day. */ public function departures($day) { return $this->select('DATE(bd.`date_to`) = \''.pSQL($day).'\' AND bd.`id_status` IN ('.self::CHECKED_IN.', '.self::CHECKED_OUT.')', 'FIELD(bd.`id_status`, '.self::CHECKED_IN.', '.self::CHECKED_OUT.'), bd.`room_num`'); } /** Guests in house who neither arrive nor leave on $day. */ public function inHouse($day) { return $this->select('bd.`id_status` = '.self::CHECKED_IN.' AND DATE(bd.`date_from`) < \''.pSQL($day).'\' AND DATE(bd.`date_to`) > \''.pSQL($day).'\'', 'bd.`room_num`'); } /** Overdue: should have arrived before $day but are still only booked. */ public function overdue($day) { return $this->select('bd.`id_status` = '.self::ASSIGNED.' AND DATE(bd.`date_from`) < \''.pSQL($day).'\' AND DATE(bd.`date_to`) > \''.pSQL($day).'\'', 'bd.`date_from`, bd.`room_num`'); } /** * @param string $action checkin | checkout | undo_checkin | undo_checkout * @return array [bool ok, string message] */ public function act($idBooking, $action, $idEmployee = 0) { $b = new HotelBookingDetail((int)$idBooking); if (!Validate::isLoadedObject($b)) { return array(false, 'Buchung nicht gefunden.'); } $guest = trim((string)Db::getInstance()->getValue('SELECT CONCAT(`firstname`, " ", `lastname`) FROM `'._DB_PREFIX_.'customer` WHERE `id_customer` = '.(int)$b->id_customer)); $who = ($guest ?: 'Gast').' (Zimmer '.$b->room_num.')'; $now = date('Y-m-d H:i:s'); $params = array('id_employee' => (int)$idEmployee, 'remark' => 'Rezeption'); switch ($action) { case 'checkin': if ((int)$b->id_status !== self::ASSIGNED) { return array(false, $who.' ist nicht im Status „gebucht“.'); } $b->check_in = $now; $b->check_out = ''; $ok = $b->changeStatus(self::CHECKED_IN, $params); return array($ok, $ok ? $who.' ist eingecheckt.' : 'Einchecken hat nicht geklappt.'); case 'checkout': if ((int)$b->id_status !== self::CHECKED_IN) { return array(false, $who.' ist nicht eingecheckt.'); } $b->check_out = $now; // billing happens at the POS (CASPOS); the QloApps payment state is not checked here $ok = $b->changeStatus(self::CHECKED_OUT, $params); return array($ok, $ok ? $who.' ist ausgecheckt.' : 'Auschecken hat nicht geklappt.'); case 'undo_checkin': if ((int)$b->id_status !== self::CHECKED_IN) { return array(false, $who.' ist nicht eingecheckt.'); } $b->check_in = ''; $b->check_out = ''; $ok = $b->changeStatus(self::ASSIGNED, $params); return array($ok, $ok ? 'Einchecken von '.$who.' zurückgenommen.' : 'Zurücknehmen hat nicht geklappt.'); case 'undo_checkout': if ((int)$b->id_status !== self::CHECKED_OUT) { return array(false, $who.' ist nicht ausgecheckt.'); } $b->check_out = ''; $ok = $b->changeStatus(self::CHECKED_IN, $params); return array($ok, $ok ? 'Auschecken von '.$who.' zurückgenommen.' : 'Zurücknehmen hat nicht geklappt.'); } return array(false, 'Unbekannte Aktion.'); } }