<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjAdminBookings extends pjAdmin
{
	public function pjActionCheckUID()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if (!$this->_get->check('uuid') || $this->_get->toString('uuid') == '')
		{
			echo 'false';
			exit;
		}
		$pjBookingModel = pjBookingModel::factory()->where('t1.uuid', $this->_get->toString('uuid'));
		if ($this->_get->check('id') && $this->_get->toInt('id') > 0)
		{
			$pjBookingModel->where('t1.id !=', $this->_get->toInt('id'));
		}
		echo $pjBookingModel->findCount()->getData() == 0 ? 'true' : 'false';
		exit;
	}
	
	public function pjActionCheckOverwrite()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}

		if (!$this->_post->check('id') || $this->_post->toInt('id') == 0)
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'No ID'));
		}
		
		if (!$this->_post->check('booking_status') || $this->_post->toString('booking_status') == '')
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'No Booking status'));
		}
		
		if ($this->_post->toString('booking_status') == 'confirmed') {
			$pjBookingServiceModel = pjBookingServiceModel::factory();
			$bs_arr = $pjBookingServiceModel
						->where('booking_id', $this->_post->toInt('id'))
						->findAll()
						->getData();
			
			$checked = false;
			if ($bs_arr) {
					
				foreach ($bs_arr as $item)
				{
					$cnt = $pjBookingServiceModel
							->reset()
							->join('pjBooking', sprintf("t1.booking_id=t2.id AND (t2.booking_status='confirmed' OR (t2.booking_status='pending' AND UNIX_TIMESTAMP(t2.created) >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %u MINUTE)) ) )", $this->option_arr['o_pending_time']), 'inner')
							->where('t1.booking_id !=', $this->_post->toInt('id'))
							->whereIn('t1.date', $item['date'])
							->whereIn('t1.service_id', $item['service_id'])
							->whereIn('t1.employee_id', $item['employee_id'])
							->whereIn('t1.start_ts', $item['start_ts'])
							->findCount()
							->getData();
					if ($cnt > 0) {
						$checked = true;
						break;
					}
				}
			}
		
			if ($checked) {
				self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Existed'));
			} else {
				self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => ''));
			}
		} else {
			self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => ''));
		}
	}
	
	public function pjActionCreate()
	{
		$this->checkLogin();
		
		if (!pjAuth::factory()->hasAccess())
		{
			$this->sendForbidden();
			return;
		}
		$summary = $this->getSummary();
		//print_r($summary); die('okk');
		

		if (self::isPost() && $this->_post->toInt('booking_create'))
		{
			$data = array();
			$data['calendar_id'] = $this->getForeignId();
			$data['locale_id'] = $this->getLocaleId();
			$data['ip'] = $_SERVER['REMOTE_ADDR'];
			if ($this->_post->toString('payment_method') != "creditcard")
			{
				$data['cc_type'] = ':NULL';
				$data['cc_num'] = ':NULL';
				$data['cc_code'] = ':NULL';
				$data['cc_exp_year'] = ':NULL';
				$data['cc_exp_month'] = ':NULL';
			}
			$data['booking_price'] = $summary['price'];
			$data['booking_deposit'] = $summary['deposit'];
			$data['booking_tax'] = $summary['tax'];
			$data['booking_total'] = $summary['total'];
			$b_date = $this->_post->toString('date_from');
			$data['date'] = date('Y-m-d', strtotime(str_replace('.', '-', $b_date)));

			$id = pjBookingModel::factory(array_merge($this->_post->raw(), $data))->insert()->getInsertId();
			if ($id !== false && (int) $id > 0)
			{
				if ($this->_post->toString('tmp_hash') != '')
				{
					pjBookingServiceModel::factory()
						->where('tmp_hash', $this->_post->toString('tmp_hash'))
						->modifyAll(array('booking_id' => $id, 'tmp_hash' => ':NULL'));
				}
				
				if ($this->_post->toArray('subservice_id') && $this->_post->toArray('subservice_id') != '')
				{
					$pjBookingSubserviceModel = pjBookingSubserviceModel::factory()->setBatchFields(array('subservice_id', 'booking_id', 'qty'));
					foreach ($this->_post->toArray('subservice_id') as $subservice_id)
					{
						$pjBookingSubserviceModel->addBatchRow(array($subservice_id, $id, 1));
					}
					$pjBookingSubserviceModel->insertBatch();
				}
				
				$err = 'ABK03';
			} else {
				$err = 'ABK04';
			}
			pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjAdminBookings&action=pjActionIndex&err=$err");
		}
		
		if (self::isGet())
		{
			$this->set('country_arr', pjBaseCountryModel::factory()
					->select('t1.*, t2.content AS `name`')
					->join('pjMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.status', 'T')
					->orderBy('`name` ASC')
					->findAll()->getData());
				
			
			$tmp_hash = md5(uniqid(rand(), true));
			
			if($this->_get->check('employee_id') && $this->_get->check('service_id') && $this->_get->check('start_ts'))
			{
				$date = date('Y-m-d', $this->_get->toString('start_ts'));
				
				$service_arr = pjServiceModel::factory()->find($this->_get->toString('service_id'))->getData();
					
				$bs_id = pjBookingServiceModel::factory()->setAttributes(array(
						'tmp_hash' => $tmp_hash,
						'booking_id' => 0,
						'service_id' => $this->_get->toString('service_id'),
						'employee_id' => $this->_get->toString('employee_id'),
						'date' => $date,
						'start' => date("H:i:s", $this->_get->toString('start_ts')),
						'start_ts' => $this->_get->toString('start_ts'),
						'total' => @$service_arr['total'],
						'price' => @$service_arr['price']
				))->insert()->getInsertId();
					
				if ($bs_id !== FALSE && (int) $bs_id > 0)
				{
					$this->set('bs_id', $bs_id);
				}
			}
			
			$this->set('tmp_hash', $tmp_hash);				

			if(pjObject::getPlugin('pjPayments') !== NULL)
			{
				$this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions(NULL));
				$this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
			}
			else
			{
				$this->set('payment_titles', __('payment_methods', true));
			}
							
			$this->set('additional_service_arr', pjAdditionalServiceModel::factory()
					->select('t1.*, t2.content AS `name`')
					->join('pjMultiLang', "t2.model='pjAdditionalService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.status', 'T')
					->orderBy('t2.content ASC')
					->findAll()
					->getData()
			);
			
			$this->appendCss('css/select2.min.css', PJ_THIRD_PARTY_PATH . 'select2/');
			$this->appendJs('js/select2.full.min.js', PJ_THIRD_PARTY_PATH . 'select2/');
			
			$this->appendCss('datepicker.css', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
			$this->appendJs('bootstrap-datepicker.js', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
			
			$this
				->appendJs('jquery.validate.min.js', PJ_THIRD_PARTY_PATH . 'validate/')
				->appendJs('pjAdminBookings.js');
		}
	}
	public function getRequestParam($key)
		{	//print_r($this->_post); die();
			return $this->_post->has($key) ? $this->_post->toString($key) : 
				($this->_get->has($key) ? $this->_get->toString($key) : null);
		}

	protected function getSummary()
	{  
		
		$price_per_peopel = $this->option_arr['o_price_per_people'];
		
		
		// $total_person = $this->_post->toString('number_of_people');
		// $slot_id = $this->_post->toString('slot_id');

		$total_person = $this->getRequestParam('number_of_people');
		$slot_id = $this->getRequestParam('slot_id');

		//print_r($slot_id); die('total_person');
		//$extra_hours = $_SESSION['cart_value']['extra_hours'];
		
		$extra_hours = 0;//isset($_SESSION['cart_value']['extra_hours']) && is_array($_SESSION['cart_value']['extra_hours'])
		// ? array_sum($_SESSION['cart_value']['extra_hours']) // Sum the extra hours prices
		// : 0;

		// Calculate the price based on the number of people
		$price = $price_per_peopel * $total_person;
		
		// Apply multiplier for slot_id 4 or 5
		if ($slot_id == 4 || $slot_id == 5) {
			$price = $price * 2;
		}
		
		 $price += $extra_hours;

		 $discount_price = $price; // Default value (no discount)
		// if (!empty($_SESSION['vcode'][0]) && isset($_SESSION['vcode'][0]['type'], $_SESSION['vcode'][0]['discount'])) {
		// 	switch ($_SESSION['vcode'][0]['type']) {
		// 		case 'percent':
		// 			$discount = ($price * (float) $_SESSION['vcode'][0]['discount']) / 100;
		// 			$discount_price = $price - $discount;
		// 			break;
		// 		case 'amount':
		// 			$discount_price = $price - (float) $_SESSION['vcode'][0]['discount'];
		// 			break;
		// 	}
		// }
		
		if ((float) $this->option_arr['o_tax'] > 0)
		{
			$tax = ($discount_price * (float) $this->option_arr['o_tax']) / 100;
		}
		$sub_total = $discount_price + $tax;
		
		
		switch ($this->option_arr['o_deposit_type'])
		{
			case 'percent':
				$deposit = ($sub_total * (float) $this->option_arr['o_deposit']) / 100;
				break;
			case 'amount':
				$deposit = (float) $this->option_arr['o_deposit'];
				break;
		}
		$total = $sub_total;

		
		return compact('cart', 'services', 'tax', 'total', 'deposit', 'price');
	}

	public function pjActionDeleteBooking()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if (!self::isPost())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'HTTP method not allowed.')); 
		}
		
		if (pjBookingModel::factory()->setAttributes(array('id' => $this->_get->toInt('id')))->erase()->getAffectedRows() == 1)
		{
			pjBookingServiceModel::factory()->where('booking_id', $this->_get->toInt('id'))->eraseAll();
			pjBookingEmployeeModel::factory()->where('booking_id', $this->_get->toInt('id'))->eraseAll();
			self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'deleted 1'));
		}
		self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => ''));
	}
	
	public function pjActionDeleteBookingBulk()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if (!self::isPost())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'HTTP method not allowed.'));
		}
		
		$record = $this->_post->toArray('record');
		if (count($record))
		{
			pjBookingModel::factory()->whereIn('id', $record)->eraseAll();
			pjBookingServiceModel::factory()->whereIn('booking_id', $record)->eraseAll();
			pjBookingEmployeeModel::factory()->whereIn('booking_id', $record)->eraseAll();
			self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => ''));
		}
		self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => ''));
	}
	
	public function pjActionGetBooking()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$pjBookingModel = pjBookingModel::factory();
		$pjBookingServiceModel = pjBookingServiceModel::factory();
			
		if ($q = $this->_get->toString('q'))
		{
			$q = str_replace(array('%', '_'), array('\%', '\_'), trim($q));
			$pjBookingModel->where(sprintf("t1.uuid LIKE '%1\$s' OR t1.c_email LIKE '%1\$s' OR t1.c_name LIKE '%1\$s'", "%$q%"));
		}

		if ($this->_get->check('booking_status') && in_array($this->_get->toString('booking_status'), array('confirmed', 'pending', 'cancelled')))
		{
			$pjBookingModel->where('t1.booking_status', $this->_get->toString('booking_status'));
		}
		
		if ($this->_get->check('employee_id') && $this->_get->toInt('employee_id') > 0)
		{
			$pjBookingModel->where(sprintf("t1.id IN (SELECT `booking_id` FROM `%s` WHERE `employee_id` = '%u')", $pjBookingServiceModel->getTable(), $this->_get->toInt('employee_id')));
		}
		
		if ($this->_get->check('service_id') && $this->_get->toInt('service_id') > 0)
		{
			$pjBookingModel->where(sprintf("t1.id IN (SELECT `booking_id` FROM `%s` WHERE `service_id` = '%u')", $pjBookingServiceModel->getTable(), $this->_get->toInt('service_id')));
		}
		
		if ($this->_get->check('date_from') && $this->_get->check('date_to') && $this->_get->toString('date_from') != '' && $this->_get->toString('date_to') != '') 
		{
			$date_from = pjDateTime::formatDate($this->_get->toString('date_from'), $this->option_arr['o_date_format']);
			$date_to = pjDateTime::formatDate($this->_get->toString('date_to'), $this->option_arr['o_date_format']);
			$pjBookingModel->where(sprintf("t1.id IN (SELECT `booking_id` FROM `%s` WHERE `date` BETWEEN '%s' AND '%s')", $pjBookingServiceModel->getTable(), $date_from, $date_to));
		} else {
			if ($this->_get->check('date_from') && $this->_get->toString('date_from') != '')
			{
				$date_from = pjDateTime::formatDate($this->_get->toString('date_from'), $this->option_arr['o_date_format']);
				$pjBookingModel->where(sprintf("t1.id IN (SELECT `booking_id` FROM `%s` WHERE `date` >= '%s')", $pjBookingServiceModel->getTable(), $date_from));
			}
			if ($this->_get->check('date_to') && $this->_get->toString('date_to') != '')
			{
				$date_to = pjUtil::formatDate($this->_get->toString('date_to'), $this->option_arr['o_date_format']);
				$pjBookingModel->where(sprintf("t1.id IN (SELECT `booking_id` FROM `%s` WHERE `date` <= '%s')", $pjBookingServiceModel->getTable(), $date_to));
			}
		}
		
		$column = 'id';
		$direction = 'DESC';
		if ($this->_get->check('column') && in_array(strtoupper($this->_get->toString('direction')), array('ASC', 'DESC')))
		{
			$column = $this->_get->toString('column');
			$direction = strtoupper($this->_get->toString('direction'));
		}

		$total = $pjBookingModel->findCount()->getData();
		$rowCount = $this->_get->toInt('rowCount') ? $this->_get->toInt('rowCount') : 10;
		$pages = ceil($total / $rowCount);
		$page = $this->_get->toInt('page') ? $this->_get->toInt('page') : 1;
		$offset = ((int) $page - 1) * $rowCount;
		if ($page > $pages)
		{
			$page = $pages;
		}

		$data = $pjBookingModel
			->select(sprintf("t1.*,
				(SELECT GROUP_CONCAT(CONCAT_WS('~.~', bs.service_id, bs.start_ts, m.content) SEPARATOR '~:~')
					FROM `%1\$s` AS `bs`
					LEFT JOIN `%2\$s` AS `m` ON m.model='pjService' AND m.foreign_id=bs.service_id AND m.field='name' AND m.locale='%3\$u'
					WHERE bs.booking_id = t1.id ORDER BY bs.order ASC) AS `items`
				", $pjBookingServiceModel->getTable(), pjMultiLangModel::factory()->getTable(), $this->getLocaleId()))
			->orderBy("$column $direction")->limit($rowCount, $offset)
			->findAll()
			->toArray('items', '~:~')
			->getData();

		foreach ($data as $k => $v)
		{
			// print_r($this->option_arr['o_time_format']);
			foreach ($data[$k]['items'] as $key => $val)
			{
				$tmp = explode('~.~', $val);
				if (isset($tmp[1]))
				{
					$tmp[1] = date($this->option_arr['o_date_format'] . ' ' . $this->option_arr['o_time_format'], $tmp[1]);
					$v['items'][$key] = join("~.~", $tmp);
				}
			}

			$data[$k]['items'] = pjSanitize::clean($v['items']);
			$data[$k]['c_name'] = pjSanitize::clean($v['c_name']);
			$data[$k]['c_email'] = pjSanitize::clean($v['c_email']);
			$data[$k]['c_phone'] = pjSanitize::clean($v['c_phone']);
			$data[$k]['date'] = date($this->option_arr['o_date_format'], strtotime($v['date']));
			$data[$k]['total_formated'] = pjCurrency::formatPrice($v['booking_total']);
			
		}
		self::jsonResponse(compact('data', 'total', 'pages', 'page', 'rowCount', 'column', 'direction'));
	}
	
	public function pjActionGetBookingService()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$pjBookingServiceModel = pjBookingServiceModel::factory()
			->join('pjBooking', 't2.id=t1.booking_id', 'inner');
		if ($this->isApprentice()) {
			$pjBookingServiceModel->where('t1.id IN (SELECT `booking_service_id` FROM `'.pjBookingEmployeeModel::factory()->getTable().'` WHERE `employee_id`='.$this->getUserId().')');
		} else {
			$pjBookingServiceModel->where('t1.employee_id', $this->getUserId());
		}
			
		if ($q = $this->_get->toString('q'))
		{
			$q = str_replace(array('%', '_'), array('\%', '\_'), trim($q));
			$pjBookingServiceModel->where(sprintf("t2.uuid LIKE '%1\$s' OR t2.c_email LIKE '%1\$s' OR t2.c_name LIKE '%1\$s'", "%$q%"));
		}

		if ($this->_get->check('booking_status') && in_array($this->_get->toString('booking_status'), array('confirmed', 'pending', 'cancelled')))
		{
			$pjBookingServiceModel->where('t2.booking_status', $this->_get->toString('booking_status'));
		}
		
		if ($this->_get->check('service_id') && $this->_get->toInt('service_id') > 0)
		{
			$pjBookingServiceModel->where('t1.service_id', $this->_get->toInt('service_id'));
		}
		
		if ($this->_get->check('date_from') && $this->_get->check('date_to') && $this->_get->toString('date_from') != '' && $this->_get->toString('date_to') != '') 
		{
			$date_from = pjDateTime::formatDate($this->_get->toString('date_from'), $this->option_arr['o_date_format']);
			$date_to = pjDateTime::formatDate($this->_get->toString('date_to'), $this->option_arr['o_date_format']);
			$pjBookingServiceModel->where(sprintf("(t1.date BETWEEN '%s' AND '%s')", $date_from, $date_to));
		} else {
			if ($this->_get->check('date_from') && $this->_get->toString('date_from') != '')
			{
				$date_from = pjDateTime::formatDate($this->_get->toString('date_from'), $this->option_arr['o_date_format']);
				$pjBookingServiceModel->where('t1.date >=', $date_from);
			}
			if ($this->_get->check('date_to') && $this->_get->toString('date_to') != '')
			{
				$date_to = pjUtil::formatDate($this->_get->toString('date_to'), $this->option_arr['o_date_format']);
				$pjBookingServiceModel->where('t1.date <=', $date_to);
			}
		}
		
		$column = 't1.date';
		$direction = 'DESC';
		if ($this->_get->check('column') && in_array(strtoupper($this->_get->toString('direction')), array('ASC', 'DESC')))
		{
			$column = $this->_get->toString('column');
			$direction = strtoupper($this->_get->toString('direction'));
		}

		$total = $pjBookingServiceModel->findCount()->getData();
		$rowCount = $this->_get->toInt('rowCount') ? $this->_get->toInt('rowCount') : 10;
		$pages = ceil($total / $rowCount);
		$page = $this->_get->toInt('page') ? $this->_get->toInt('page') : 1;
		$offset = ((int) $page - 1) * $rowCount;
		if ($page > $pages)
		{
			$page = $pages;
		}

		$data = $pjBookingServiceModel
			->select("t1.*, t2.uuid, t2.booking_status, t2.c_name, t2.c_email, t2.c_phone, t3.content AS `service_name`")
			->join('pjMultiLang', "t3.model='pjService' AND t3.foreign_id=t1.service_id AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
			->orderBy("$column $direction")->limit($rowCount, $offset)
			->findAll()
			->getData();

		foreach ($data as $k => $v)
		{
			$data[$k]['time'] = date($this->option_arr['o_date_format'] . ' ' . $this->option_arr['o_time_format'], $v['start_ts']);
			$data[$k]['c_name'] = pjSanitize::clean($v['c_name']);
			$data[$k]['c_email'] = pjSanitize::clean($v['c_email']);
			$data[$k]['c_phone'] = pjSanitize::clean($v['c_phone']);
			$data[$k]['service_name'] = pjSanitize::clean($v['service_name']);
		}
			
		self::jsonResponse(compact('data', 'total', 'pages', 'page', 'rowCount', 'column', 'direction'));
	}
	
	public function pjActionGetPrice()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$additional_service_price = $price = $deposit = $tax = $total = 0;
		
		if ($this->_post->check('id') && $this->_post->toInt('id') > 0)
		{
			$key = 't1.booking_id';
			$value = $this->_post->toInt('id');
		} elseif ($this->_post->check('tmp_hash') && $this->_post->toString('tmp_hash') != '') {
			$key = 't1.tmp_hash';
			$value = $this->_post->toString('tmp_hash');
		}
		
		if (isset($key) && isset($value))
		{
			$bs_arr = pjBookingServiceModel::factory()->where($key, $value)->findAll()->getData();
			if(empty($bs_arr))
			{
				self::jsonResponse(array('status' => 'ERR'));
			}
			foreach ($bs_arr as $service)
			{
				$price += $service['price'];
			}
		}
		
		if ($this->_post->check('additional_service_id') && $this->_post->toInt('additional_service_id') > 0) {
			$additional_service_arr = pjAdditionalServiceModel::factory()->find($this->_post->toInt('additional_service_id'))->getData();
			if ($additional_service_arr) {
				$additional_service_price = $additional_service_arr['price'];
			}
		}
		$price += $additional_service_price;
		if ((float) $this->option_arr['o_tax'] > 0)
		{
			$tax = ($price * (float) $this->option_arr['o_tax']) / 100;
		}
		
		$total = $price + $tax;
		
		switch ($this->option_arr['o_deposit_type'])
		{
			case 'percent':
				$deposit = ($total * (float) $this->option_arr['o_deposit']) / 100;
				break;
			case 'amount':
				$deposit = (float) $this->option_arr['o_deposit'];
				break;
		}
		
		$additional_service_price_format = pjCurrency::formatPrice($additional_service_price);
		$price_format = pjCurrency::formatPrice($price);
		$tax_format = pjCurrency::formatPrice($tax);
		$total_format = pjCurrency::formatPrice($total);
		$deposit_format = pjCurrency::formatPrice($deposit);
		
		$data = compact('additional_service_price', 'price', 'deposit', 'tax', 'total');
		$data = array_map('floatval', $data);
		$data_format = compact('price_format', 'deposit_format', 'tax_format', 'total_format', 'additional_service_price_format');
		
		self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => '', 'data' => $data, 'data_format' => $data_format));
	}
	
	public function pjActionGetService()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if ($this->_get->check('id') && $this->_get->toInt('id') > 0 && $this->_get->check('date') && $this->_get->toString('date') != '')
		{
			$id = $this->_get->toInt('id');
			$date = pjDateTime::formatDate($this->_get->toString('date'), $this->option_arr['o_date_format']);
			
			$pjEmployeeServiceModel = pjEmployeeServiceModel::factory()
				->select("t1.*, t2.calendar_id, t2.avatar, t3.content AS `name`")
				->join('pjEmployee', 't2.id=t1.employee_id AND t2.is_active="T"', 'inner')
				->join('pjMultiLang', "t3.model='pjEmployee' AND t3.foreign_id=t1.employee_id AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.service_id', $id)
				->orderBy('t2.order ASC, t3.content ASC')
				->findAll();
			
			$employee_arr = $pjEmployeeServiceModel->getData();
			$employee_ids = $pjEmployeeServiceModel->getDataPair(null, 'employee_id');
			$bs_arr = array();
			if (!empty($employee_ids))
			{
				$pjBookingServiceModel = pjBookingServiceModel::factory();
				if ($this->_get->check('booking_item_id') && $this->_get->toInt('booking_item_id')) {
					$pjBookingServiceModel->where('t1.id <>', $this->_get->toInt('booking_item_id'));
				}
				$bs_arr = $pjBookingServiceModel
				    ->join('pjBooking', sprintf("t1.booking_id=t2.id AND (t2.booking_status='confirmed' OR (t2.booking_status='pending' AND UNIX_TIMESTAMP(t2.created) >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %u MINUTE)) ) )", $this->option_arr['o_pending_time']), 'inner')
					->whereIn('t1.employee_id', $employee_ids)
					->where('t1.date', $date)
					->findAll()
					->getData();
			}

			foreach ($employee_arr as $k => $employee)
			{
				$employee_arr[$k]['t_arr'] = pjAppController::getRawSlotsPerEmployee($employee['employee_id'], $date, $employee['calendar_id']);
				$employee_arr[$k]['bs_arr'] = array();
				foreach ($bs_arr as $item)
				{
					if ($item['employee_id'] != $employee['employee_id'])
					{
						continue;
					}
					$employee_arr[$k]['bs_arr'][] = $item;
				}
			}

			$this
				->set('service_arr', pjServiceModel::factory()
					->select('t1.*, t2.content AS `name`')
					->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->find($id)
					->getData()
				)
				->set('employee_arr', $employee_arr);
				
			if ($this->_get->check('booking_item_id') && $this->_get->toInt('booking_item_id')) {
				$this->set('bs_arr', pjBookingServiceModel::factory()->find($this->_get->toInt('booking_item_id'))->getData());
			}
		}else{
		    self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => 'Missing headers.'));
		}
	}
	
	public function pjActionIndex()
	{
		
		$this->set('employee_arr', pjEmployeeModel::factory()
			->select('t1.id, t2.content AS `name`')
			->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->where('role_id', 3)
			->orderBy('t1.order ASC, t2.content ASC')
			->findAll()
			->getData()
		);
	
		$this->set('service_arr', pjServiceModel::factory()
			->select('t1.*, t2.content AS `name`')
			->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->orderBy('`name` ASC')
			->findAll()
			->getData()
		);
		
		$this->appendCss('datepicker.css', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
		$this->appendJs('bootstrap-datepicker.js', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
		$this->appendJs('jquery.datagrid.js', PJ_FRAMEWORK_LIBS_PATH . 'pj/js/');
		$this->appendJs('pjAdminBookings.js');
		
		$this->set('has_update', pjAuth::factory('pjAdminBookings', 'pjActionUpdate')->hasAccess());
		$this->set('has_create', pjAuth::factory('pjAdminBookings', 'pjActionCreate')->hasAccess());
		$this->set('has_delete', pjAuth::factory('pjAdminBookings', 'pjActionDeleteBooking')->hasAccess());
		$this->set('has_delete_bulk', pjAuth::factory('pjAdminBookings', 'pjActionDeleteBookingBulk')->hasAccess());
	}
	
	public function pjActionList()
	{
		$pjServiceModel = pjServiceModel::factory();
		if (!$this->isApprentice()) {
			$pjServiceModel->where(sprintf("t1.id IN (SELECT `service_id` FROM `%s` WHERE `employee_id` = '%u')", pjEmployeeServiceModel::factory()->getTable(), $this->getUserId()));
		}
		$this->set('service_arr', $pjServiceModel
			->select('t1.*, t2.content AS `name`')
			->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
			->orderBy('`name` ASC')
			->findAll()
			->getData()
		);

		$this->appendJs('tinymce.min.js', PJ_THIRD_PARTY_PATH . 'tinymce/');
		
		$this->appendCss('datepicker.css', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
		$this->appendJs('bootstrap-datepicker.js', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
		$this->appendJs('jquery.validate.min.js', PJ_THIRD_PARTY_PATH . 'validate/');
		$this->appendJs('jquery.datagrid.js', PJ_FRAMEWORK_LIBS_PATH . 'pj/js/');
		$this->appendJs('pjEmployeeBookings.js');
	}
	
	public function pjActionSaveBooking()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$pjBookingModel = pjBookingModel::factory();
		if (!in_array($this->_post->toString('column'), $pjBookingModel->getI18n()))
		{
			$pjBookingModel->set('id', $this->_get->toInt('id'))->modify(array($this->_post->toString('column') => $this->_post->toString('value')));
		} else {
			pjMultiLangModel::factory()->updateMultiLang(array($this->getLocaleId() => array($this->_post->toString('column') => $this->_post->toString('value'))), $this->_get->toInt('id'), 'pjBooking');
		}
	}
	
	public function pjActionUpdate()
	{
		$pjBookingModel = pjBookingModel::factory();
		
		if ($this->_get->check('id') && $this->_get->toInt('id')) {
			$pjBookingModel->where('t1.id', $this->_get->toInt('id'));
		}
		if ($this->_get->check('uuid') && $this->_get->toString('uuid')) {
			$pjBookingModel->where('t1.uuid', $this->_get->toString('uuid'));
		}

		if ($this->_post->check('id') && $this->_post->toInt('id')) {
			$pjBookingModel->where('t1.id', $this->_post->toInt('id'));
		}

	  // die('ok');
		$summary = $this->getSummary();

		$arr = $pjBookingModel
				->limit(1)
				->findAll()
				->getData();
		
		if (empty($arr))
		{
			pjUtil::redirect($_SERVER['PHP_SELF'] . "?controller=pjAdminBookings&action=pjActionIndex&err=ABK08");
		}
				
		$arr = $arr[0];
		
		if (self::isPost() && $this->_post->toInt('booking_update') > 0)
		{
			$data = array();
			if ($this->_post->toString('payment_method') != "creditcard")
			{
				$data['cc_type'] = ':NULL';
				$data['cc_num'] = ':NULL';
				$data['cc_code'] = ':NULL';
				$data['cc_exp_year'] = ':NULL';
				$data['cc_exp_month'] = ':NULL';
			}

			$data['booking_price'] = $summary['price'];
			$data['booking_deposit'] = $summary['deposit'];
			$data['booking_tax'] = $summary['tax'];
			$data['booking_total'] = $summary['total'];
			$b_date = $this->_post->toString('date_from');
			$data['date'] = date('Y-m-d', strtotime(str_replace('.', '-', $b_date)));

			$arr = $pjBookingModel->find($this->_post->toInt('id'))->getData();
							
			pjBookingModel::factory()->set('id', $this->_post->toInt('id'))->modify(array_merge($this->_post->raw(), $data));
			
			$pjBookingSubserviceModel = pjBookingSubserviceModel::factory();
			$pjBookingSubserviceModel->where('booking_id', $this->_post->toString('id'))->eraseAll();
			if ($this->_post->toArray('subservice_id') && $this->_post->toArray('subservice_id') != '')
			{
				$pjBookingSubserviceModel->reset()->setBatchFields(array('subservice_id', 'booking_id', 'qty'));
				foreach ($this->_post->toArray('subservice_id') as $subservice_id)
				{
					$pjBookingSubserviceModel->addBatchRow(array($subservice_id, $this->_post->toInt('id'), 1));
				}
				$pjBookingSubserviceModel->insertBatch();
			}
			
			pjUtil::redirect(PJ_INSTALL_URL . "index.php?controller=pjAdminBookings&action=pjActionIndex&err=ABK01");
		} 
		
		if (self::isGet())
		{
			$this->set('arr', $arr)
				->set('country_arr', pjBaseCountryModel::factory()
				->select('t1.*, t2.content AS `name`')
				->join('pjMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->orderBy('`name` ASC')
				->findAll()->getData());
			
			$bi_arr = pjBookingServiceModel::factory()
				->select('t1.*, t2.content AS `title`')
				->join('pjMultiLang', sprintf("t2.model='pjService' AND t2.foreign_id=t1.service_id AND t2.field='name' AND t2.locale='%u'", $arr['locale_id']), 'left outer')
				->where('t1.booking_id', $arr['id'])
				->findAll()
				->getData();
			$this->set('bi_arr', $bi_arr);
			$service_ids = array();
			foreach ($bi_arr as $val) {
				$service_ids[] = $val['service_id'];
			}
			
			if(pjObject::getPlugin('pjPayments') !== NULL)
			{
				$this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions(NULL));
				$this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
			}
			else
			{
				$this->set('payment_titles', __('payment_methods', true));
			}
			
			if ($service_ids) {
				$this->set('subservice_arr', pjSubserviceModel::factory()
						->select('t1.*, t2.content AS `name`')
						->join('pjMultiLang', "t2.model='pjSubservice' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->where('t1.status', 'T')
						->where('t1.id IN (SELECT `subservice_id` FROM `'.pjServiceSubserviceModel::factory()->getTable().'` WHERE `service_id` IN ('.implode(',', $service_ids).'))')
						->orderBy('t2.content ASC')
						->findAll()
						->getData()
				);
			}
			$this->set('bss_arr', pjBookingSubserviceModel::factory()->where('t1.booking_id', $arr['id'])->findAll()->getDataPair(null, 'subservice_id'));
			
			$this->set('additional_service_arr', pjAdditionalServiceModel::factory()
					->select('t1.*, t2.content AS `name`')
					->join('pjMultiLang', "t2.model='pjAdditionalService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.status', 'T')
					->orderBy('t2.content ASC')
					->findAll()
					->getData()
			);
			
			$this->appendCss('css/select2.min.css', PJ_THIRD_PARTY_PATH . 'select2/');
			$this->appendJs('js/select2.full.min.js', PJ_THIRD_PARTY_PATH . 'select2/');			
			$this->appendCss('datepicker.css', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');
			$this->appendJs('bootstrap-datepicker.js', PJ_THIRD_PARTY_PATH . 'bootstrap_datepicker/');			
			$this->appendJs('tinymce.min.js', PJ_THIRD_PARTY_PATH . 'tinymce/');			
			$this->appendJs('sortable.js', PJ_THIRD_PARTY_PATH . 'sortable/');
			$this->appendCss('sortable.css', PJ_THIRD_PARTY_PATH . 'sortable/');
			$this
				->appendJs('jquery.validate.min.js', PJ_THIRD_PARTY_PATH . 'validate/')
				->appendJs('jquery.datagrid.js', PJ_FRAMEWORK_LIBS_PATH . 'pj/js/')
				->appendJs('pjAdminBookings.js')
			;
		}
	}
	
	protected function pjActionCheckSlotBooked()
	{
		$id = $this->_post->toInt('id');
		$date = $this->_post->toString('date_from');
		$date = date('Y-m-d', strtotime(str_replace('.', '-', $date)));
		$bookedSlotId = $this->_post->toString('booked_slot_id');
	
		if (!empty($bookedSlotId) && !empty($date)) {
			$isBooked = pjBookingModel::factory()
				->where('date', $date)
				->where('booked_slot_id', $bookedSlotId)
				->where('id !=', $id)
				->findAll()
				->getData();
	
			if (!empty($isBooked)) {
				return $isBooked;
			}
		}
	}

	public function pjActionViewBookingService()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if (self::isGet() && $this->_get->check('id') && $this->_get->toInt('id') > 0)
		{
			$arr = pjBookingServiceModel::factory()
				->select('t2.*, t1.*, t3.content AS `service_name`, t4.content AS `country_name`')
				->join('pjBooking', 't2.id=t1.booking_id', 'inner')
				->join('pjMultiLang', "t3.model='pjService' AND t3.foreign_id=t1.service_id AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
				->join('pjMultiLang', "t4.model='pjBaseCountry' AND t4.foreign_id=t2.c_country_id AND t4.field='name' AND t4.locale='".$this->getLocaleId()."'", 'left outer')
				->find($this->_get->toInt('id'))
				->getData();
			
			$this->set('arr', $arr);
		}
	}
	
	public function pjActionItemAdd()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$pjBookingServiceModel = pjBookingServiceModel::factory();
		
		if (self::isPost() && $this->_post->check('item_add'))
		{
			if ($this->_post->check('service_id') && $this->_post->toInt('service_id') > 0)
			{
				$date = pjDateTime::formatDate($this->_post->toString('date'), $this->option_arr['o_date_format']);
			
				$service_arr = pjServiceModel::factory()->find($this->_post->toInt('service_id'))->getData();
				/*if ($this->_post->toInt('booking_id') > 0) {
					$pjBookingServiceModel->where('booking_id', $this->_post->toInt('booking_id'))->eraseAll();
				} elseif ($this->_post->toString('tmp_hash') != '') {
					$pjBookingServiceModel->where('tmp_hash', $this->_post->toString('tmp_hash'))->eraseAll();
				}*/
				$data = array(
					'tmp_hash' => @$this->_post->toString('tmp_hash'),
					'booking_id' => @$this->_post->toInt('booking_id'),
					'service_id' => $this->_post->toInt('service_id'),
					'employee_id' => $this->_post->toInt('employee_id'),
					'date' => $date,
					'start' => date("H:i:s", $this->_post->toString('start_ts')),
					'start_ts' => $this->_post->toString('start_ts'),
					'total' => @$service_arr['total'],
					'price' => @$service_arr['price']
				);
				if ($this->_post->check('booking_item_id') && $this->_post->toInt('booking_item_id')) {
					unset($data['tmp_hash']);
					unset($data['booking_id']);
					$bs_id = $this->_post->toInt('booking_item_id');
					$pjBookingServiceModel->reset()->set('id', $bs_id)->modify($data);
				} else {
					$bs_arr = $pjBookingServiceModel->where('t1.tmp_hash', @$this->_post->toString('tmp_hash'))->orderBy('t1.order DESC')->limit(1)->findAll()->getDataIndex(0);
					$order = $bs_arr ? ($bs_arr['order'] + 1) : 1;
					$data['order'] = $order;
					$bs_id = $pjBookingServiceModel->reset()->setAttributes($data)->insert()->getInsertId();
				}
				if ($bs_id !== FALSE && (int) $bs_id > 0)
				{
					/* Re-order booking services */
					if ($this->_post->toInt('booking_id') > 0) {
						$bs_arr = $pjBookingServiceModel->reset()->where('t1.booking_id', @$this->_post->toInt('booking_id'))->orderBy('t1.order ASC')->findAll()->getData();
					} else {
						$bs_arr = $pjBookingServiceModel->reset()->where('t1.tmp_hash', @$this->_post->toString('tmp_hash'))->orderBy('t1.order ASC')->findAll()->getData();
					}
					foreach ($bs_arr as $k => $v) {
						$pjBookingServiceModel->reset()->set('id', $v['id'])->modify(array('order' => ($k+1)));
					}
					self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'Service has been added.'));
				}
				self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Service has not been added.'));
			}
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Service couldn\'t be empty.'));
		}
		
		if (self::isGet()) 
		{
			$service_arr = pjServiceModel::factory()
				->select(sprintf("t1.*, t2.content AS `name`,
				(SELECT GROUP_CONCAT(m.content SEPARATOR ', ')
					FROM `%1\$s` AS `sc`
					LEFT JOIN `%2\$s` AS `m` ON m.model='pjCategory' AND m.foreign_id=sc.category_id AND m.field='name' AND m.locale='%3\$u'
					WHERE sc.service_id = t1.id) AS `categories`
				", pjServiceCategoryModel::factory()->getTable(), pjMultiLangModel::factory()->getTable(), $this->getLocaleId()))				
				->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.is_active', 1)
				->orderBy('t1.order ASC')
				->findAll()->getData();
			
			$this->set('service_arr', $service_arr);
			
			if ($this->_get->check('booking_item_id') && $this->_get->toInt('booking_item_id')) {
				$this->set('bs_arr', pjBookingServiceModel::factory()->select('t1.*, t2.content AS employee_name')
					->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.employee_id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'")
					->find($this->_get->toInt('booking_item_id'))->getData());
			}
			if ($this->_get->check('id') && $this->_get->toInt('id') > 0) {
				$bs_arr = pjBookingServiceModel::factory()->where('t1.booking_id', $this->_get->toInt('id'))->orderBy('t1.order DESC')->limit(1)->findAll()->getDataIndex(0);
				if ($bs_arr) {
					$this->set('date', $bs_arr['date']);
				}
			}
		}
	}
	
	public function pjActionItemDelete()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if ($this->_post->check('id') && $this->_post->toInt('id') > 0)
		{
			$pjBookingServiceModel = pjBookingServiceModel::factory();
			$arr = $pjBookingServiceModel->find($this->_post->toInt('id'))->getData();
			if (empty($arr))
			{
				self::jsonResponse(array('status' => 'ERR', 'code' => 103, 'text' => 'Item not found.'));
			}
			if (1 == $pjBookingServiceModel->set('id', $this->_post->toInt('id'))->erase()->getAffectedRows())
			{
				pjBookingEmployeeModel::factory()->where('booking_service_id', $arr['id'])->eraseAll();
				/* Re-order booking services */
				$bs_arr = $pjBookingServiceModel->reset()->where('t1.booking_id', $arr['booking_id'])->orderBy('t1.order ASC')->findAll()->getData();
				foreach ($bs_arr as $k => $v) {
					$pjBookingServiceModel->reset()->set('id', $v['id'])->modify(array('order' => ($k+1)));
				}
				self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'Item has been deleted.'));
			}
			self::jsonResponse(array('status' => 'ERR', 'code' => 102, 'text' => 'Item has not been deleted.'));
		}
		self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => 'Missing parameters.'));
	}
	
	public function pjActionItemGet()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$pjBookingServiceModel = pjBookingServiceModel::factory()
			->select("t1.*, t2.content AS `service`, t3.content AS `employee`")
			->join('pjMultiLang', "t2.model='pjService' AND t2.foreign_id=t1.service_id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'")
			->join('pjMultiLang', "t3.model='pjEmployee' AND t3.foreign_id=t1.employee_id AND t3.field='name' AND t3.locale='".$this->getLocaleId()."'");
		
		if ($this->_get->check('booking_id') && $this->_get->toInt('booking_id') > 0)
		{
			$pjBookingServiceModel
				->join('pjBooking', 't4.id=t1.booking_id', 'inner')
				->where('t1.booking_id', $this->_get->toInt('booking_id'));
				
			$this->set('employee_arr', pjEmployeeModel::factory()
				->select('t1.*, t2.content AS `name`')
				->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.is_active', 'T')
				->where('t1.role_id', 3)
				->where('t1.category', 'apprentice')
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()
				->getData()
			);
			
			$be_arr = pjBookingEmployeeModel::factory()->select('t1.*, t2.content AS employee_name')
				->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.employee_id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.booking_id', $this->_get->toInt('booking_id'))->findAll()->getDataPair('booking_service_id', null);
			$this->set('be_arr', $be_arr);
		} elseif ($this->_get->check('tmp_hash') && $this->_get->toString('tmp_hash') != '') {
			$pjBookingServiceModel->where('t1.tmp_hash', $this->_get->toString('tmp_hash'));
		} else {
			$pjBookingServiceModel->where('t1.id', -999);
		}
		$bi_arr = $pjBookingServiceModel->orderBy('t1.order ASC')->findAll()->getData();
		
		$this->set('bi_arr', $bi_arr);
	}

	public function pjActionItemEmail()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if ($this->_post->check('send_email') && $this->_post->check('to') && $this->_post->toArray('to') != '' && $this->_post->toString('from') != '' &&
			$this->_post->toString('subject') != '' && $this->_post->toString('message') != '' && $this->_post->toString('id') != '')
		{
			$Email = self::getMailer($this->option_arr);
			
			$r = false;
			if ($this->_post->toString('message') != '')
			{
				$message = pjUtil::textToHtml($this->_post->toString('message'));
				$tos = $this->_post->toArray('to');
				$tmp_arr = array();
				foreach ($tos as $recipient)
				{
					if (!in_array($recipient, $tmp_arr)) {
						$r = $Email
							->setTo($recipient)
							->setSubject($this->_post->toString('subject'))
							->send($message);
						$tmp_arr[] = $recipient;
					}
				}
			}
				
			if ($r)
			{
				pjBookingServiceModel::factory()->set('id', $this->_post->toInt('id'))->modify(array('reminder_email' => 1));
				self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'Email has been sent.'));
			}
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Email failed to send.'));
		}
		
		if (self::isGet() && $this->_get->check('id') && $this->_get->toInt('id') > 0)
		{
			$booking_arr = pjBookingServiceModel::factory()
				->select('t2.*, t1.*, t3.length, t3.before, t4.content AS `service_name`,
					t6.email AS `employee_email`, t7.content AS `country_name`, t8.content AS `o_reminder_subject`, t9.content AS `o_reminder_body`')
				->join('pjBooking', 't2.id=t1.booking_id', 'inner')
				->join('pjService', 't3.id=t1.service_id', 'inner')
				->join('pjMultiLang', "t4.model='pjService' AND t4.foreign_id=t1.service_id AND t4.field='name' AND t4.locale=t2.locale_id", 'left outer')
				->join('pjCalendar', 't5.id=t2.calendar_id', 'left outer')
				->join('pjEmployee', 't6.id=t1.employee_id', 'left outer')
				->join('pjMultiLang', "t7.model='pjBaseCountry' AND t7.foreign_id=t2.c_country_id AND t7.locale=t2.locale_id AND t7.field='name'", 'left outer')
				->join('pjMultiLang', "t8.model='pjCalendar' AND t8.foreign_id=t2.calendar_id AND t8.locale=t2.locale_id AND t8.field='o_reminder_subject'", 'left outer')
				->join('pjMultiLang', "t9.model='pjCalendar' AND t9.foreign_id=t2.calendar_id AND t9.locale=t2.locale_id AND t9.field='o_reminder_body'", 'left outer')
				->find($this->_get->toInt('id'))
				->getData();
			$apprentice_arr = pjBookingEmployeeModel::factory()->select('t1.*, t2.email')
				->join('pjEmployee', 't2.id=t1.employee_id', 'inner')
				->where('t1.booking_service_id', $booking_arr['id'])
				->findAll()->getDataPair(null, 'email');
			
			$pjBookingServiceModel = pjBookingServiceModel::factory()->reset();
			if ($this->isApprentice()) {
				$pjBookingServiceModel->where('t1.id IN (SELECT `booking_service_id` FROM `'.pjBookingEmployeeModel::factory()->getTable().'` WHERE `employee_id`='.$this->getUserId().')');
			} elseif ($this->isEmployee()) {
				$pjBookingServiceModel->where('t1.employee_id', $this->getUserId());
			}
			$booking_arr['bs_arr'] = $pjBookingServiceModel
				->select('t1.*, t3.before, t3.length, t4.content AS `service_name`, t5.content AS `employee_name`,
					t6.phone AS `employee_phone`, t6.email AS `employee_email`, t6.is_subscribed, t6.is_subscribed_sms')
				->join('pjBooking', 't2.id=t1.booking_id', 'inner')
				->join('pjService', 't3.id=t1.service_id', 'inner')
				->join('pjMultiLang', "t4.model='pjService' AND t4.foreign_id=t1.service_id AND t4.field='name' AND t4.locale=t2.locale_id", 'left outer')
				->join('pjMultiLang', "t5.model='pjEmployee' AND t5.foreign_id=t1.employee_id AND t5.field='name' AND t5.locale=t2.locale_id", 'left outer')
				->join('pjEmployee', 't6.id=t1.employee_id', 'left outer')
				->where('t1.booking_id', $booking_arr['booking_id'])
				->orderBy('t1.order ASC')
				->findAll()
				->getData();
			
			
			$tokens = pjAppController::getTokens($booking_arr, $this->option_arr, 'multi');
			$tokens['replace'][21] = str_replace("\n\n","<br>",$tokens['replace'][21]);
			
			$subject_client = str_replace($tokens['search'], $tokens['replace'], $booking_arr['o_reminder_subject']);
			$message_client = str_replace($tokens['search'], $tokens['replace'], $booking_arr['o_reminder_body']);
			
			$this->set('arr', array(
				'id' => $this->_get->toInt('id'),
				//'to' => $booking_arr['c_email'],
				'client_email' => pjSanitize::clean($booking_arr['c_email']),
				'employee_email' => pjSanitize::clean($booking_arr['employee_email']),
				'apprentice_arr' => pjSanitize::clean($apprentice_arr),
				'from' => !empty($booking_arr['admin_email']) ? $booking_arr['admin_email'] : $booking_arr['c_email'],
				'message' => $message_client,
				'subject' => $subject_client
			));
		} else {
			exit;
		}
	}
	
	public function pjActionItemSms()
	{
		$this->setAjax(true);
	
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		if ($this->_post->check('send_sms') && $this->_post->check('to') && $this->_post->toString('to') != '' && $this->_post->toString('message') != '' && $this->_post->toString('id') != '')
		{
			$params = array(
				'text' => $this->_post->toString('message'),
				'type' => 'unicode',
				'key' => md5($this->option_arr['private_key'] . PJ_SALT)
			);
			$tmp_arr = array();
			foreach ($this->_post->toArray('to') as $recipient)
			{
				if (!in_array($recipient, $tmp_arr)) {
					$params['number'] = $recipient;
					$result = $this->requestAction(array('controller' => 'pjBaseSms', 'action' => 'pjActionSend', 'params' => $params), array('return'));
					$tmp_arr[] = $recipient;
				}
			}

			if ((int) $result === 1)
			{
				pjBookingServiceModel::factory()->set('id', $this->_post->toInt('id'))->modify(array('reminder_sms' => 1));
				self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'SMS has been sent.'));
			}
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'SMS failed to send.'));
		}
		
		if (self::isGet() && $this->_get->check('id') && $this->_get->toInt('id') > 0)
		{
			$booking_arr = pjBookingServiceModel::factory()
				->select('t2.*, t1.*, t3.before, t3.length, t4.content AS `service_name`,
					t6.phone AS `employee_phone`, t7.content AS `country_name`, t8.content AS `o_reminder_sms_message`')
				->join('pjBooking', 't2.id=t1.booking_id', 'inner')
				->join('pjService', 't3.id=t1.service_id', 'inner')
				->join('pjMultiLang', "t4.model='pjService' AND t4.foreign_id=t1.service_id AND t4.field='name' AND t4.locale=t2.locale_id", 'left outer')
				->join('pjCalendar', 't5.id=t2.calendar_id', 'left outer')
				->join('pjEmployee', 't6.id=t1.employee_id', 'left outer')
				->join('pjMultiLang', "t7.model='pjBaseCountry' AND t7.foreign_id=t2.c_country_id AND t7.locale=t2.locale_id AND t7.field='name'", 'left outer')
				->join('pjMultiLang', "t8.model='pjCalendar' AND t8.foreign_id=t2.calendar_id AND t8.locale=t2.locale_id AND t8.field='o_reminder_sms_message'", 'left outer')
				->find($this->_get->toInt('id'))
				->getData();
			$apprentice_arr = pjBookingEmployeeModel::factory()->select('t1.*, t2.phone')
				->join('pjEmployee', 't2.id=t1.employee_id', 'inner')
				->where('t1.booking_service_id', $booking_arr['id'])
				->findAll()->getDataPair(null, 'phone');
			$tokens = pjAppController::getTokens($booking_arr, $this->option_arr);
			
			$message_client = str_replace($tokens['search'], $tokens['replace'], $booking_arr['o_reminder_sms_message']);
			
			$this->set('arr', array(
				'id' => $this->_get->toInt('id'),
				'client_phone' => $booking_arr['c_phone'],
				'employee_phone' => $booking_arr['employee_phone'],
				'apprentice_arr' => pjSanitize::clean($apprentice_arr),
				'message' => $message_client
			));
		} else {
			exit;
		}
	}
	
	public function pjActionExport()
	{
	    $this->checkLogin();
	    
	    if (!pjAuth::factory()->hasAccess())
	    {
	        $this->sendForbidden();
	        return;
	    }
	    
	    if(self::isPost() && $this->_post->check('bookings_export'))
	    {
	        if($this->_post->toString('type') == 'file')
	        {
	            $this->setLayout('pjActionEmpty');
	            $post = $this->_post->raw();
	            $post['type'] = $post['period'] == 'next' ? '1' : '2';
	            $post['period'] = $post['period'] == 'next' ? $post['coming_period'] : $post['made_period'];
	            $arr = pjExport::doExportData($post, 'download', $this->getLocaleId(), $this->option_arr);
	            exit;
	        }else{
	            $pjPasswordModel = pjPasswordModel::factory();
	            $password = md5($this->_post->toString('password').PJ_SALT);
	            $arr = $pjPasswordModel
	            ->where("t1.password", $password)
	            ->limit(1)
	            ->findAll()
	            ->getData();
	            if (count($arr) != 1)
	            {
	                $pjPasswordModel->setAttributes(array('password' => $password))->insert();
	            }
	            $this->set('password', $password);
	        }
	    }
	    
	    $this->appendCss('awesome-bootstrap-checkbox.css', PJ_THIRD_PARTY_PATH . 'awesome_bootstrap_checkbox/');
	    $this->appendJs('jquery.validate.min.js', PJ_THIRD_PARTY_PATH . 'validate/');
	    $this->appendJs('pjAdminBookings.js');
	}
	
	public function pjActionGetSubservices()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		
		$pjBookingServiceModel = pjBookingServiceModel::factory();		
		if ($this->_get->check('booking_id') && $this->_get->toInt('booking_id') > 0)
		{
			$pjBookingServiceModel
				->join('pjBooking', 't2.id=t1.booking_id', 'inner')
				->where('t1.booking_id', $this->_get->toInt('booking_id'));
			$this->set('bss_arr', pjBookingSubserviceModel::factory()->where('t1.booking_id', $this->_get->toInt('booking_id'))->findAll()->getDataPair(null, 'subservice_id'));
		} elseif ($this->_get->check('tmp_hash') && $this->_get->toString('tmp_hash') != '') {
			$pjBookingServiceModel->where('t1.tmp_hash', $this->_get->toString('tmp_hash'));
		} else {
			$pjBookingServiceModel->where('t1.id', -999);
		}
		$bi_arr = $pjBookingServiceModel->findAll()->getDataPair(null, 'service_id');
		if ($bi_arr) {
			$this->set('subservice_arr', pjSubserviceModel::factory()
					->select('t1.*, t2.content AS `name`')
					->join('pjMultiLang', "t2.model='pjSubservice' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->where('t1.status', 'T')
					->where('t1.id IN (SELECT `subservice_id` FROM `'.pjServiceSubserviceModel::factory()->getTable().'` WHERE `service_id` IN ('.implode(',', $bi_arr).'))')
					->orderBy('t2.content ASC')
					->findAll()
					->getData()
			);
		}
	}
	
	public function pjActionSetAllowDoubleBooking() {
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
		if ($this->_post->check('id') && $this->_post->check('allow_double_booking')) {
			pjBookingServiceModel::factory()->set('id', $this->_post->toInt('id'))->modify(array('allow_double_booking' => $this->_post->toString('allow_double_booking')));
			self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => 'Data has been updated.'));
		} else {
			self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => 'Missing parameters.'));
		}
	}
	
	public function pjActionReorderBookingServices() {
		$this->setAjax(true);
		if ($this->isXHR()) {
			$pjBookingServiceModel = pjBookingServiceModel::factory();
			$arr = explode("|", $this->_post->toString('params'));
			if ($arr) {
				$order = 1;
				for ($i = 0; $i < count($arr); $i++) {
					if ((int)$arr[$i] > 0) {
						$pjBookingServiceModel->reset()->set('id', $arr[$i])->modify(array('order' => $order));
						$order++;
					}
				}
			}
			pjAppController::jsonResponse(array('status' => 'OK'));
		}
	}
	
	public function pjActionItemAddApprentices()
	{
		$this->setAjax(true);
		
		if (!$this->isXHR())
		{
			self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => 'Missing headers.'));
		}
				
		if (self::isPost() && $this->_post->check('item_add'))
		{
			$pjBookingEmployeeModel = pjBookingEmployeeModel::factory();
			if ($this->_post->check('employee_id') && $this->_post->toInt('employee_id') > 0)
			{
				$pjBookingEmployeeModel->where('booking_service_id', $this->_post->toInt('booking_service_id'))->eraseAll();
				$pjBookingEmployeeModel->reset()->setAttributes(array(
					'booking_id' => $this->_post->toInt('booking_id'),
					'employee_id' => $this->_post->toInt('employee_id'),
					'booking_service_id' => $this->_post->toInt('booking_service_id')
				))->insert();
			} else {
				$pjBookingEmployeeModel->where('booking_service_id', $this->_post->toInt('booking_service_id'))->limit(1)->eraseAll();
			}
			self::jsonResponse(array('status' => 'OK'));
		}
		
		if (self::isGet()) 
		{
			$pjEmployeeModel = pjEmployeeModel::factory();
			$pjBookingServiceModel = pjBookingServiceModel::factory();
			
			$be_arr = $pjBookingServiceModel->select('t1.*, t2.employee_id AS apprentices_id')
				->join('pjBookingEmployee', "t2.booking_service_id=t1.id", 'left outer')
				->find($this->_get->toInt('id'))->getData();
			$this->set('be_arr', $be_arr);
			
			$bs_arr = $pjBookingServiceModel->reset()->select('t1.*, t3.employee_id AS apprentices_id')
				    ->join('pjBooking', sprintf("t1.booking_id=t2.id AND (t2.booking_status='confirmed' OR (t2.booking_status='pending' AND UNIX_TIMESTAMP(t2.created) >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %u MINUTE)) ) )", $this->option_arr['o_pending_time']), 'inner')
				    ->join('pjBookingEmployee', "t3.booking_service_id=t1.id", 'inner')
					->where('t1.date', $be_arr['date'])
					->where('t1.id <>', $be_arr['id'])
					->findAll()
					->getData();
			$exclude_apprentices_ids = array();
			foreach ($bs_arr as $item)
			{
				if (
					($be_arr['start_ts'] >= $item['start_ts'] && $be_arr['start_ts'] < $item['start_ts'] + $item['total'] * 60) || 
					($item['start_ts'] >= $be_arr['start_ts'] && $item['start_ts'] < $be_arr['start_ts'] + $be_arr['total'] * 60)
				)
				{
					$exclude_apprentices_ids[] = $item['apprentices_id'];
				}
			}
			if ($exclude_apprentices_ids) {
				$pjEmployeeModel->whereNotIn('t1.id', $exclude_apprentices_ids);
			}
			$this->set('employee_arr', $pjEmployeeModel
				->select('t1.*, t2.content AS `name`')
				->join('pjMultiLang', "t2.model='pjEmployee' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				->where('t1.is_active', 'T')
				->where('t1.role_id', 3)
				->where('t1.category', 'apprentice')
				->orderBy('t1.order ASC, t2.content ASC')
				->findAll()
				->getData()
			);
			
		}
	}
	
}
?>