<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjAdminAvailability extends pjAppController
{
	private function _calendar($selected_date, $room_id=null, $_week_start_date=null)
	{
		$pjBookingModel = pjBookingModel::factory();
		$pjRoomModel = pjRoomModel::factory();
		$pjRoomNumberModel = pjRoomNumberModel::factory();
		$pjBookingRoomModel = pjBookingRoomModel::factory();
	
		$day = date("w", strtotime($selected_date));
	
		if ($day > 1)
		{
			$days = $day - 1;
			$week_start_date = date("Y-m-d", strtotime($selected_date . "-$days days"));
			$week_end_date = date("Y-m-d", strtotime($selected_date . "-$days days") + 24 * 60 * 60 * 7);
		} else {
			$week_start_date = $selected_date;
			$week_end_date = date("Y-m-d", strtotime($week_start_date) + 24 * 60 * 60 * 7);
		}
		if ($_week_start_date != null)
		{
			$week_start_date = $_week_start_date;
			$week_end_date = date("Y-m-d", strtotime($week_start_date) + 24 * 60 * 60 * 7);
		}
		$month_arr = __('months', true);
		$start_month = date('n', strtotime($week_start_date));
		$end_month = date('n', strtotime($week_end_date));
		$month_label = $month_arr[$start_month] . ', ' . date('Y', strtotime($week_start_date));
		if($start_month != $end_month)
		{
			$month_label = $month_arr[$start_month] . ', ' . date('Y', strtotime($week_start_date)) . ' - ' . $month_arr[$end_month] . ', ' . date('Y', strtotime($week_end_date));
		}
	
		if ($room_id != null)
		{
			$pjRoomNumberModel->where('t1.room_id', $room_id);
		}
		$room_number_arr = $pjRoomNumberModel
			->select('t1.*, t3.content AS `type`')
			->join('pjRoom', 't2.id=t1.room_id', 'inner')
			->join('pjBaseMultiLang', sprintf("t3.model='pjRoom' AND t3.foreign_id=t2.id AND t3.field='name' AND t3.locale='%u'", $this->getLocaleId()), 'left outer')
			->orderBy('`type` ASC, t1.id ASC')
			->findAll()
			->getData();

		$_arr = $pjBookingModel
			->select(sprintf("t1.*, t3.name as c_name, t3.email as c_email, 
				(SELECT GROUP_CONCAT(CONCAT_WS('~:~', TRN.id, TRN.number) SEPARATOR '~::~') 
					FROM `%s` AS `TBR`
					INNER JOIN `%s` AS `TRN` ON TBR.room_number_id=TRN.id 
					WHERE TBR.booking_id=t1.id
				) AS `rooms`		
			", $pjBookingRoomModel->getTable(), $pjRoomNumberModel->getTable()))
			->join('pjClient', "t2.id=t1.client_id", 'left outer')
			->join('pjAuthUser', "t3.id=t2.foreign_id", 'left outer')
			->whereIn('t1.status', array('confirmed', 'pending'))
			->where('t1.date_from <=', $week_end_date)
			->where('t1.date_to >=', $week_start_date)
			->orderBy('t1.date_from ASC')
			->findAll()
			->getData();	
	
		$other_rooms = array();
		foreach ($_arr as $v)
		{
			if (!empty($v['rooms']))
			{
				$other_rooms[$v['id']] =  explode("~::~", pjSanitize::clean($v['rooms']));
			}
		}

		$pjBookingModel->reset();
		if ($room_id != null)
		{
			$pjBookingModel
				->select('t1.id, t1.uuid, t1.date_from, t1.date_to, t4.name as c_name, t4.email as c_email, t4.phone as c_phone, t1.status, DATEDIFF(`date_to`, `date_from`) AS `nights`, t2.room_number_id, t2.adults, t2.children')
				->join('pjBookingRoom', sprintf("t2.booking_id=t1.id AND t2.room_id='%u'", $room_id), 'inner')
				->join('pjClient', "t3.id=t1.client_id", 'left outer')
				->join('pjAuthUser', "t4.id=t3.foreign_id", 'left outer');
		} else {
			$pjBookingModel
				->select('t1.id, t1.uuid, t1.date_from, t1.date_to,t4.name as c_name, t4.email as c_email, t4.phone as c_phone, t1.status, DATEDIFF(`date_to`, `date_from`) AS `nights`, t2.room_number_id, t2.adults, t2.children')
				->join('pjBookingRoom', 't2.booking_id=t1.id', 'inner')
				->join('pjClient', "t3.id=t1.client_id", 'left outer')
				->join('pjAuthUser', "t4.id=t3.foreign_id", 'left outer');
		}
		$booking_arr = $pjBookingModel
			->whereIn('t1.status', array('confirmed', 'pending'))
			->where('t1.date_from <=', $week_end_date)
			->where('t1.date_to >=', $week_start_date)
			->orderBy('t1.date_from ASC')
			->findAll()
			->getData();

		$br_arr = array();
		foreach ($booking_arr as $v)
		{
		    $v['over'] = 0;
		    if(strtotime($v['date_from']) < strtotime($week_start_date))
		    {
		        $v['date_from'] = $week_start_date;
		        $v['over'] = 1;
		    }
		    $iso = $v['date_from'];
		    while ($iso <= $v['date_to'])
		    {
		        if($iso == $v['date_from'])
		        {
		            $v['first'] = 1;
		        }else{
		            $v['first'] = 0;
		        }
		        $br_arr[$v['room_number_id']][$iso] = $v;
		        $iso = date('Y-m-d', strtotime($iso . ' +1 day'));
		    }
		}
		$rows = array();
		
		# Restriction
		# Add restrictions as bookings. Then in presentation layer, just check for specific index (restriction_type)
		$rr_arr = pjRestrictionRoomModel::factory()
			->select('t1.room_number_id, t2.date_from, t2.date_to, t2.restriction_type, DATEDIFF(`date_to`, `date_from`) AS `nights`')
			->join('pjRestriction', 't2.id=t1.restriction_id', 'inner')
			->where('t2.date_from <=', $week_end_date)
			->where('t2.date_to >=', $week_start_date)
			->orderBy('t2.date_from ASC')
			->findAll()
			->getData();
        
		$tmp_week_start_date = strtotime($week_start_date);
		$tmp_week_end_date = strtotime($week_end_date);
		foreach ($rr_arr as $item)
		{
			if (!isset($br_arr[$item['room_number_id']]))
			{
				$br_arr[$item['room_number_id']] = array();
			}
			
			if (strtotime($item['date_from']) < $tmp_week_start_date)
			{
				$item['date_from'] = date("Y-m-d", $tmp_week_start_date - 86400);
			}
			if (strtotime($item['date_to']) > $tmp_week_end_date)
			{
				$item['date_to'] = date("Y-m-d", $tmp_week_end_date + 86400);
			}
			$br_arr[$item['room_number_id']][] = $item;
			
			/*Re-order the bookings in each row in case retriction goes before actual bookings*/
			$tmp_arr = $br_arr[$item['room_number_id']];
			
			pjUtil::sortMultiDimensionsArray($tmp_arr, 'date_from');
			foreach($tmp_arr as $v)
			{
			    $v['over'] = 0;
			    if(strtotime($v['date_from']) < strtotime($week_start_date))
			    {
			        $v['date_from'] = $week_start_date;
			        $v['over'] = 1;
			    }
			    $iso = $v['date_from'];
			    while ($iso <= $v['date_to'])
			    {
			        if($iso == $v['date_from'])
			        {
			            $v['first'] = 1;
			        }else{
			            $v['first'] = 0;
			        }
			        $br_arr[$v['room_number_id']][$iso] = $v;
			        $iso = date('Y-m-d', strtotime($iso . ' +1 day'));
			    }
			}
		}
		
		$room_arr = $pjRoomModel
			->reset()
			->select('t1.*, t2.content AS `type`')
			->join('pjBaseMultiLang', sprintf("t2.model='pjRoom' AND t2.foreign_id=t1.id AND t2.locale='%u' AND t2.field='name'", $this->getLocaleId()), 'left outer')
			->orderBy('`type` ASC')
			->findAll()
			->getData();
	
		return compact('week_start_date', 'week_end_date', 'month_label', 'room_number_arr', 'rows', 'other_rooms', 'room_arr', 'br_arr');
	}
	protected function notConfirmed()
	{
		if ($this->option_arr['o_allow_pending_time'] == 1) {
		    pjBookingModel::factory()
		    ->where('`status`', 'pending')
		    ->where(sprintf("UNIX_TIMESTAMP(NOW()) >= UNIX_TIMESTAMP(DATE_ADD(`created`, INTERVAL %u MINUTE))", $this->option_arr['o_pending_time']))
		    ->modifyAll(array('status' => 'not_confirmed'));
		}
	}
	public function pjActionIndex()
	{
	    $this->checkLogin();
	    if (!pjAuth::factory()->hasAccess())
	    {
	        $this->sendForbidden();
	        return;
	    }
	    
		$this->notConfirmed();
			
		$selected_date = date('Y-m-d');
		if ($this->_get->check('selected_date') && !$this->_get->isEmpty('selected_date'))
		{
		    if ($this->_get->check('format') && !$this->_get->isEmpty('format'))
		    {
		        $selected_date = pjDateTime::formatDate($this->_get->toString('selected_date'), $this->_get->toString('format'));
			} else {
				$selected_date = pjDateTime::formatDate($this->_get->toString('selected_date'), $this->option_arr['o_date_format']);
			}
			$this->set('selected_date', pjDateTime::formatDate($selected_date, 'Y-m-d', $this->option_arr['o_date_format']));
		}
		$room_id = $this->_get->toInt('room_id') > 0 ? : null;
		$params = $this->_calendar($selected_date, $room_id, null);

		$this->set('week_start_date', $params['week_start_date']);
		$this->set('week_end_date', $params['week_end_date']);
		$this->set('month_label', $params['month_label']);
		$this->set('room_number_arr', $params['room_number_arr']);
		$this->set('rows', $params['rows']);
		$this->set('other_rooms', $params['other_rooms']);
		$this->set('room_arr', $params['room_arr']);
		$this->set('br_arr', $params['br_arr']);
		
		$this->set('date_format', pjUtil::toBootstrapDate($this->option_arr['o_date_format']));
			
		$this->appendCss('datepicker3.css', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
		$this->appendJs('bootstrap-datepicker.js', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');		
		$this->appendJs('pjAdminAvailability.js');
	}
	
	public function pjActionGetCalendar()
	{
		$this->checkLogin();
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			$selected_date = null;
			$room_id = null;
			$week_start_date = null;
			if ($this->_get->check('selected_date') && !$this->_get->isEmpty('selected_date'))
			{
			    $selected_date = pjDateTime::formatDate($this->_get->toString('selected_date'), $this->option_arr['o_date_format']);
			} else {
				$selected_date = date('Y-m-d');
			}
			if ($this->_get->check('week_start_date') && !$this->_get->isEmpty('week_start_date'))
			{
			    $week_start_date = $this->_get->toString('week_start_date');
			}
			if ($this->_get->toInt('room_id') > 0)
			{
			    $room_id = $this->_get->toInt('room_id');
			}
			$params = $this->_calendar($selected_date, $room_id, $week_start_date);
			
			$this->set('week_start_date', $params['week_start_date']);
			$this->set('week_end_date', $params['week_end_date']);
			$this->set('month_label', $params['month_label']);
			$this->set('room_number_arr', $params['room_number_arr']);
			$this->set('rows', $params['rows']);
			$this->set('other_rooms', $params['other_rooms']);
			$this->set('room_arr', $params['room_arr']);
			$this->set('br_arr', $params['br_arr']);
		}
	}
	
	public function pjActionPrintCalendar()
	{
	    $this->checkLogin();
	    if (!pjAuth::factory()->hasAccess())
	    {
	        $this->sendForbidden();
	        return;
	    }
	    
	    $this->notConfirmed();
	    
        $this->setLayout('pjActionPrint');
        
        $selected_date = null;
        $room_id = null;
        $week_start_date = null;
        
        if ($this->_get->check('selected_date') && !$this->_get->isEmpty('selected_date'))
        {
            $selected_date = pjDateTime::formatDate($this->_get->toString('selected_date'), $this->option_arr['o_date_format']);
        } else {
            $selected_date = date('Y-m-d');
        }
        if ($this->_get->check('week_start_date') && !$this->_get->isEmpty('week_start_date'))
        {
            $week_start_date = $this->_get->toString('week_start_date');
        }
        if ($this->_get->toInt('room_id') > 0)
        {
            $room_id = $this->_get->toInt('room_id');
            
            $room_arr = pjRoomModel::factory()->find($room_id)->getData();
            if (empty($room_arr))
            {
                pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjAdminAvailability&action=pjActionPrintCalendar&err=TODO");
            }
            $this->set('room_arr', $room_arr);
        }
        $params = $this->_calendar($selected_date, $room_id, $week_start_date);
        
        $this->set('week_start_date', $params['week_start_date']);
        $this->set('week_end_date', $params['week_end_date']);
        $this->set('month_label', $params['month_label']);
        $this->set('room_number_arr', $params['room_number_arr']);
        $this->set('rows', $params['rows']);
        $this->set('other_rooms', $params['other_rooms']);
        $this->set('rooms_arr', $params['room_arr']);
        $this->set('br_arr', $params['br_arr']);
	}
}
?>