<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjAppController extends pjController
{
	public $models = array();

	public $defaultLocale = 'admin_locale_id';
	
	public $defaultCalendarId = 'admin_calendar_id';
	
	public $defaultFields = 'fields';
	
	public $defaultFieldsIndex = 'fields_index';
	
	protected function loadSetFields($force=FALSE, $locale_id=NULL, $fields=NULL)
	{
		if (is_null($locale_id))
		{
			$locale_id = $this->getLocaleId();
		}
	
		if (is_null($fields))
		{
			$fields = $this->defaultFields;
		}
	
		$registry = pjRegistry::getInstance();
		if ($force
				|| !isset($_SESSION[$this->defaultFieldsIndex])
				|| (isset($this->option_arr) && $_SESSION[$this->defaultFieldsIndex] != $this->option_arr['o_fields_index'])
				|| !isset($_SESSION[$fields])
				|| empty($_SESSION[$fields]))
		{
			pjAppController::setFields($locale_id);
	
			# Update session
			if ($registry->is('fields'))
			{
				$_SESSION[$fields] = $registry->get('fields');
			}
			$_SESSION[$this->defaultFieldsIndex] = $this->option_arr['o_fields_index'];
		}
	
		if (isset($_SESSION[$fields]) && !empty($_SESSION[$fields]))
		{
			# Load fields from session
			$registry->set('fields', $_SESSION[$fields]);
		}
	
		return TRUE;
	}
	
	public static function setTimezone($timezone="UTC")
    {
    	if (in_array(version_compare(phpversion(), '5.1.0'), array(0,1)))
		{
			date_default_timezone_set($timezone);
		} else {
			$safe_mode = ini_get('safe_mode');
			if ($safe_mode)
			{
				putenv("TZ=".$timezone);
			}
		}
    }

	public static function setMySQLServerTime($offset="-0:00")
    {
		pjAppModel::factory()->prepare("SET SESSION time_zone = :offset;")->exec(compact('offset'));
    }
    
	public function setTime()
	{
		if (isset($this->option_arr['o_timezone']))
		{
			$offset = $this->option_arr['o_timezone'] / 3600;
			if ($offset > 0)
			{
				$offset = "-".$offset;
			} elseif ($offset < 0) {
				$offset = "+".abs($offset);
			} elseif ($offset === 0) {
				$offset = "+0";
			}
	
			pjAppController::setTimezone('Etc/GMT' . $offset);
			if (strpos($offset, '-') !== false)
			{
				$offset = str_replace('-', '+', $offset);
			} elseif (strpos($offset, '+') !== false) {
				$offset = str_replace('+', '-', $offset);
			}
			pjAppController::setMySQLServerTime($offset . ":00");
		}
	}
	public function afterFilter()
	{
		if ($_GET['controller'] != 'pjInstaller')
		{
			$this->set('menu_locale_arr', pjLocaleModel::factory()->select('t1.*, t2.file, t2.title')
					->join('pjLocaleLanguage', 't2.iso=t1.language_iso', 'left outer')
					->where('t2.file IS NOT NULL')
					->orderBy('t1.sort ASC')
					->findAll()
					->getDataPair('id')
			);
		}
		if ($_GET['controller'] == 'pjInstaller' && $_GET['action'] == 'pjActionSecureUpdate')
		{
			pjOptionModel::factory()->where("(`key` LIKE 'o_update_%')")->limit(1)->modifyAll(array('foreign_id' => $this->getForeignId()));
		}
	}
	
    public function beforeFilter()
    {
    	if (!in_array($_GET['controller'], array('pjFront', 'pjInstaller')))
    	{
    		$pjCalendarModel = pjCalendarModel::factory();
    		if ($this->isOwner())
    		{
    			$pjCalendarModel->where('t1.user_id', $this->getUserId());
    		}
	    	$calendars = $pjCalendarModel
				->select('t1.*, t2.content AS `name`')
				->join('pjMultiLang', "t2.model='pjCalendar' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left')
				->orderBy('t1.id ASC')
				->findAll()->getDataPair('id');
			$this->set('calendars', $calendars);
			
			if ($this->getForeignId() === false && count($calendars) > 0)
			{
				$keys = array_keys($calendars);
				$this->setForeignId($keys[0]);
				
			}
    	}
		
    	$this->appendJs('jquery.min.js', PJ_THIRD_PARTY_PATH . 'jquery/');
    	$dm = new pjDependencyManager(PJ_INSTALL_PATH, PJ_THIRD_PARTY_PATH);
    	$dm->load(PJ_CONFIG_PATH . 'dependencies.php')->resolve();
    	$this->appendJs('jquery-migrate.min.js', $dm->getPath('jquery_migrate'), FALSE, FALSE);
    	$this->appendJs('pjAdminCore.js');
    	$this->appendCss('reset.css');
    		
    	$this->appendJs('js/jquery-ui.custom.min.js', PJ_THIRD_PARTY_PATH . 'jquery_ui/');
    	$this->appendCss('css/smoothness/jquery-ui.min.css', PJ_THIRD_PARTY_PATH . 'jquery_ui/');
    		
    	$this->appendCss('pj-all.css', PJ_FRAMEWORK_LIBS_PATH . 'pj/css/');
    	$this->appendCss('admin.css');
				
    	if ($_GET['controller'] != 'pjInstaller')
		{
			$this->models['Option'] = pjOptionModel::factory();
			$this->option_arr = $this->models['Option']->getPairs($this->getForeignId());
			$this->set('option_arr', $this->option_arr);
			$this->setTime();
			if (!isset($_SESSION[$this->defaultLocale]))
			{
				$locale_arr = pjLocaleModel::factory()->where('is_default', 1)->limit(1)->findAll()->getData();
				if (count($locale_arr) === 1)
				{
					$_SESSION[$this->defaultLocale] = $locale_arr[0]['id'];
				}
			}
			$this->loadSetFields();
		}
		
		if ($_GET['controller'] == 'pjInvoice')
		{
			$foreign_arr = array();
			foreach ($calendars as $calendar)
			{
				$foreign_arr[] = array(
					'id' => $calendar['id'],
					'title' => $calendar['name']
				);
			}
			$this->set('foreign_arr', $foreign_arr);
		}
    }
    
    public function getForeignId()
	{
		if (isset($_SESSION[$this->defaultCalendarId]))
		{
			return $_SESSION[$this->defaultCalendarId];
		}
		return false;
	}
	
    public static function getTokens($booking_arr, $option_arr, $locale_id)
    {
    	$na = __('lblNA', true, false);
    	$c_name = !empty($booking_arr['c_name']) ? pjSanitize::clean(@$booking_arr['c_name']) : $na;
    	$c_email = !empty($booking_arr['c_email']) ? pjSanitize::clean(@$booking_arr['c_email']) : $na;
    	$c_phone = !empty($booking_arr['c_phone']) ? pjSanitize::clean(@$booking_arr['c_phone']) : $na;
    	$c_adults = $booking_arr['c_adults'] != '' ? @$booking_arr['c_adults'] : $na;
    	$c_children = $booking_arr['c_children'] != '' ? @$booking_arr['c_children'] : $na;
    	$c_notes = !empty($booking_arr['c_notes']) ? pjSanitize::clean(@$booking_arr['c_notes']) : $na;
    	$c_address = !empty($booking_arr['c_address']) ? pjSanitize::clean(@$booking_arr['c_address']) : $na;
    	$c_city = !empty($booking_arr['c_city']) ? pjSanitize::clean(@$booking_arr['c_city']) : $na;
    	$country = !empty($booking_arr['country']) ? pjSanitize::clean(@$booking_arr['country']) : $na;
    	$c_state = !empty($booking_arr['c_state']) ? pjSanitize::clean(@$booking_arr['c_state']) : $na;
    	$c_zip = !empty($booking_arr['c_zip']) ? pjSanitize::clean(@$booking_arr['c_zip']) : $na;
    	$cc_type = !empty($booking_arr['cc_type']) ? @$booking_arr['cc_type'] : $na;
    	$cc_num = !empty($booking_arr['cc_num']) ? @$booking_arr['cc_num'] : $na;
    	$cc_exp_month = @$booking_arr['payment_method'] == 'creditcard' ? (!empty($booking_arr['cc_exp_month']) ? @$booking_arr['cc_exp_month'] : $na) : $na;
    	$cc_exp_year = @$booking_arr['payment_method'] == 'creditcard' ? (!empty($booking_arr['cc_exp_year']) ? @$booking_arr['cc_exp_year'] : $na) : $na;
    	$cc_code = !empty($booking_arr['cc_code']) ? @$booking_arr['cc_code'] : $na;
    	$payment_method = !empty($booking_arr['payment_method']) ? @$booking_arr['payment_method'] : $na;
    	
    	$security = NULL;
    	$tax = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['tax'], $option_arr), $option_arr['o_currency']);
    	$tourist_tax = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['tourist_tax'], $option_arr), $option_arr['o_currency']);
    	$amount = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['amount'], $option_arr), $option_arr['o_currency']);
    	$total =  $booking_arr['amount'] + $booking_arr['extra_price'] - $booking_arr['discount_amount'] - $booking_arr['promo_amount'] + $booking_arr['tax'] + $booking_arr['tourist_tax'];
    	if($option_arr['o_to_be_paid'] == 'when_booking')
    	{
    		$total = $total + (float) $booking_arr['security'];
    		$security = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['security'], $option_arr), $option_arr['o_currency']);
    	}
    	$total_price =  pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat($total, $option_arr), $option_arr['o_currency']);
    	$extra_price = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['extra_price'], $option_arr), $option_arr['o_currency']);
    	$discount_amount = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['discount_amount'], $option_arr), $option_arr['o_currency']);
    	$promo_amount = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['promo_amount'], $option_arr), $option_arr['o_currency']);
    	$deposit = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$booking_arr['deposit'], $option_arr), $option_arr['o_currency']);
    	
    	$cancelURL = sprintf("%sindex.php?controller=pjFront&action=pjActionCancel&cid=%u&id=%u&hash=%s", PJ_INSTALL_URL, @$booking_arr['calendar_id'], @$booking_arr['id'], sha1(@$booking_arr['id'] . PJ_SALT));
    	$cancelURL = '<a href="'.$cancelURL.'">'.$cancelURL.'</a>';
    	
    	$firstInvoiceURL = '';
    	if(isset($booking_arr['uuid']) && !empty($booking_arr['uuid']))
    	{
    		$invoice_arr = pjInvoiceModel::factory()->where('t1.order_id', $booking_arr['uuid'])->limit(1)->orderBy("t1.id ASC")->findAll()->getData();
    		if(count($invoice_arr))
    		{
    			$firstInvoiceURL = sprintf("%sindex.php?controller=pjInvoice&action=pjActionView&id=%u&uuid=%s", PJ_INSTALL_URL, $invoice_arr[0]['id'], @$booking_arr['uuid']);
    			$firstInvoiceURL = '<a href="'.$firstInvoiceURL.'">'.$firstInvoiceURL.'</a>';
    		}    		
    	}
		$calendar_name = '';
		if(isset($booking_arr['calendar_id']) && (int) $booking_arr['calendar_id'] > 0)
		{
			$calendar = pjCalendarModel::factory()
			->select("t1.*, t2.content as name")
			->join('pjMultiLang', "t2.foreign_id = t1.id AND t2.model = 'pjCalendar' AND t2.locale = '".$locale_id."' AND t2.field = 'name'", 'left')
			->find($booking_arr['calendar_id'])->getData();
			$calendar_name = $calendar['name'];
		}
		
		$extra_arr = pjExtraModel::factory()
			->select('t1.*, t2.content AS name, t3.qty')
			->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$locale_id."'", 'left outer')
			->join('pjReservationExtra', 't1.id=t3.extra_id', 'left outer')
			->where('t1.status', 'T')
			->where("(t1.id IN (SELECT TCE.extra_id FROM `".pjCalendarExtraModel::factory()->getTable()."` AS `TCE` WHERE `TCE`.calendar_id='".$booking_arr['calendar_id']."') )")
			->where("(t3.reservation_id='".$booking_arr['id']."')")
			->orderBy('`name` ASC')
			->findAll()->getData();
		$extras = '';
		$temp_extra = array();
		$price_types = $option_arr['o_price_based_on'] == 'days' ? __('day_price_types', true) : __('price_types', true);
		foreach($extra_arr as $extra)
		{
			$temp_extra[] = $extra['qty'] . ' x ' . pjSanitize::html($extra['name']) . ' (' . pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat($extra['price'], $option_arr), $option_arr['o_currency']) . ' ' . $price_types[$extra['price_type']] . ')';
		}
		$extras = join("<br/>", $temp_extra);
		
    	$search = array(
    		'{Name}', '{Email}', '{Phone}', '{Adults}', '{Children}',
    		'{Notes}', '{Address}', '{City}', '{Country}', '{State}',
    		'{Zip}', '{CCType}', '{CCNum}', '{CCExpMonth}', '{CCExpYear}',
    		'{CCSec}', '{PaymentMethod}', '{StartDate}', '{EndDate}', '{Deposit}',
    		'{Security}', '{Tax}', '{TouristTax}', '{Price}', '{TotalPrice}', '{ExtraPrice}', '{Discount}', '{Promo}', '{PromoCode}','{CalendarID}', '{ReservationID}',
    		'{ReservationUUID}', '{CancelURL}', '{FirstInvoice}', '{CalendarName}', '{Extras}');
		$replace = array(
			$c_name, $c_email, $c_phone, $c_adults, $c_children,
			$c_notes, $c_address, $c_city, $country, $c_state,
			$c_zip, $cc_type, $cc_num, $cc_exp_month, $cc_exp_year,
			$cc_code, $payment_method, date(@$option_arr['o_date_format'], strtotime(@$booking_arr['date_from'])), date(@$option_arr['o_date_format'], strtotime(@$booking_arr['date_to'])), @$deposit,
			$security, $tax, $tourist_tax, $amount, @$total_price, @$extra_price, @$discount_amount, @$promo_amount, @$booking_arr['promo_code'], @$booking_arr['calendar_id'], @$booking_arr['id'],
			@$booking_arr['uuid'], $cancelURL, $firstInvoiceURL, $calendar_name, $extras
		);
		return compact('search', 'replace');
    }
    
	public function setForeignId($calendar_id)
	{
		$_SESSION[$this->defaultCalendarId] = (int) $calendar_id;
		return $this;
	}
	
    public static function setFields($locale)
    {
    	if(isset($_SESSION['lang_show_id']) && (int) $_SESSION['lang_show_id'] == 1)
		{
			$fields = pjMultiLangModel::factory()
				->select('CONCAT(t1.content, CONCAT(":", t2.id, ":")) AS content, t2.key')
				->join('pjField', "t2.id=t1.foreign_id", 'inner')
				->where('t1.locale', $locale)
				->where('t1.model', 'pjField')
				->where('t1.field', 'title')
				->findAll()
				->getDataPair('key', 'content');
		}else{
			$fields = pjMultiLangModel::factory()
				->select('t1.content, t2.key')
				->join('pjField', "t2.id=t1.foreign_id", 'inner')
				->where('t1.locale', $locale)
				->where('t1.model', 'pjField')
				->where('t1.field', 'title')
				->findAll()
				->getDataPair('key', 'content');
		}
		$registry = pjRegistry::getInstance();
		$tmp = array();
		if ($registry->is('fields'))
		{
			$tmp = $registry->get('fields');
		}
		$arrays = array();
		foreach ($fields as $k => $v)
		{
			if (strpos($k, '_ARRAY_') !== false)
			{
				list($prefix, $suffix) = explode("_ARRAY_", $k);
				if (!isset($arrays[$prefix]))
				{
					$arrays[$prefix] = array();
				}
				$arrays[$prefix][$suffix] = $v;
			}
		}
		require PJ_CONFIG_PATH . 'settings.inc.php';
		$fields = array_merge($tmp, $fields, $settings, $arrays);
		$registry->set('fields', $fields);
    }

    public static function jsonDecode($str)
	{
		$Services_JSON = new pjServices_JSON();
		return $Services_JSON->decode($str);
	}
	
	public static function jsonEncode($arr)
	{
		$Services_JSON = new pjServices_JSON();
		return $Services_JSON->encode($arr);
	}
	
	public static function jsonResponse($arr)
	{
		header("Content-Type: application/json; charset=utf-8");
		echo pjAppController::jsonEncode($arr);
		exit;
	}

	public function isEditor()
	{
		return $this->getRoleId() == 2;
	}

	public function isOwner()
	{
		return $this->getRoleId() == 3;
	}
	
	public function isPriceReady()
	{
		return $this->isAdmin() || $this->isEditor() || $this->isOwner();
	}
	
	public function isPeriodReady()
	{
		return $this->isAdmin() || $this->isEditor() || $this->isOwner();
	}
	
	public function isInvoiceReady()
	{
		return $this->isAdmin() || $this->isEditor() || $this->isOwner();
	}
	
	public function isCountryReady()
	{
		return $this->isAdmin();
	}
	
	public function isOneAdminReady()
	{
		return $this->isAdmin();
	}

	public function getLocaleId()
	{
		return isset($_SESSION[$this->defaultLocale]) && (int) $_SESSION[$this->defaultLocale] > 0 ? (int) $_SESSION[$this->defaultLocale] : false;
	}
	public function setLocaleId($locale_id)
	{
		$_SESSION[$this->defaultLocale] = (int) $locale_id;
	}
	public function pjActionCheckInstall()
	{
		$this->setLayout('pjActionEmpty');
		
		$result = array('status' => 'OK', 'code' => 200, 'text' => 'Operation succeeded', 'info' => array());
		$folders = array('app/web/upload');
		foreach ($folders as $dir)
		{
			if (!is_writable($dir))
			{
				$result['status'] = 'ERR';
				$result['code'] = 101;
				$result['text'] = 'Permission requirement';
				$result['info'][] = sprintf('Folder \'<span class="bold">%1$s</span>\' is not writable. You need to set write permissions (chmod 777) to directory located at \'<span class="bold">%1$s</span>\'', $dir);
			}
		}
		
		return $result;
	}
	
	public function pjActionAfterInstall()
	{
		$this->setLayout('pjActionEmpty');
		
		$id = pjCalendarModel::factory()->set('user_id', 1)->insert()->getInsertId();
		if ($id !== false && (int) $id > 0)
		{
			pjMultiLangModel::factory()->saveMultiLang(array(
				1 => array('name' => 'Calendar 1')
			), $id, 'pjCalendar');
			
			$pjOptionModel = pjOptionModel::factory();
			$pjOptionModel->init($id);
			$pjOptionModel->initConfirmation($id, null);

			$data = $data = $pjOptionModel->reset()->getAllPairs($id);
			pjUtil::pjActionGenerateImages($id, $data);
		}
		
		return array('status' => 'OK', 'code' => 200, 'text' => 'Operation succeeded');
	}
	
	public function notify($notification_id, $locale_id, $user_id=NULL, $params=array(), $option_arr)
	{
		$map = array(
			3 => array('o_email_new_reservation_subject', 'o_email_new_reservation', 'o_sms_new_reservation'),
			4 => array('o_email_new_reservation_subject', 'o_email_new_reservation', 'o_sms_new_reservation'),
			5 => array('o_email_reservation_cancelled_subject', 'o_email_reservation_cancelled', 'o_sms_reservation_cancelled'),
			6 => array('o_email_reservation_cancelled_subject', 'o_email_reservation_cancelled', 'o_sms_reservation_cancelled')
		);
		
		$pjUserNotificationModel = pjUserNotificationModel::factory()
			->select('t1.type, t2.email, t2.phone')
			->join('pjUser', "t2.id=t1.user_id", 'inner')
			->where('t1.notification_id', $notification_id);

		if (!is_null($user_id))
		{
			$pjUserNotificationModel->where('t1.user_id', $user_id);
		}
		$recipients = $pjUserNotificationModel->findAll()->getData();
		
		$pjEmail = new pjEmail();
		$smsPlugin = (pjObject::getPlugin('pjSms') !== NULL);
		
		$from_email = pjAppController::getFromEmail($option_arr);
		
		$calendar_name = '';
		if(isset($params['calendar_id']) && (int) $params['calendar_id'] > 0)
		{
			$calendar = pjCalendarModel::factory()
				->select("t1.*, t2.content as name")
				->join('pjMultiLang', "t2.foreign_id = t1.id AND t2.model = 'pjCalendar' AND t2.locale = '".$locale_id."' AND t2.field = 'name'", 'left')
				->find($params['calendar_id'])->getData();
			$calendar_name = $calendar['name'];
		}
		
		$extra_arr = pjExtraModel::factory()
			->select('t1.*, t2.content AS name, t3.qty')
			->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$locale_id."'", 'left outer')
			->join('pjReservationExtra', 't1.id=t3.extra_id', 'left outer')
			->where('t1.status', 'T')
			->where("(t1.id IN (SELECT TCE.extra_id FROM `".pjCalendarExtraModel::factory()->getTable()."` AS `TCE` WHERE `TCE`.calendar_id='".$params['calendar_id']."') )")
			->where("(t3.reservation_id='".$params['id']."')")
			->orderBy('`name` ASC')
			->findAll()->getData();
		$extras = '';
		$temp_extra = array();
		$price_types = $option_arr['o_price_based_on'] == 'days' ? __('day_price_types', true) : __('price_types', true);
		foreach($extra_arr as $extra)
		{
			$temp_extra[] = $extra['qty'] . ' x ' . pjSanitize::html($extra['name']) . ' (' . pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat($extra['price'], $option_arr), $option_arr['o_currency']) . ' ' . $price_types[$extra['price_type']] . ')';
		}
		$extras = join("<br/>", $temp_extra);
		
		
		$security = NULL;
		$tax = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['tax'], $option_arr), $option_arr['o_currency']);
		$tourist_tax = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['tourist_tax'], $option_arr), $option_arr['o_currency']);
		$amount = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['amount'], $option_arr), $option_arr['o_currency']);
		$total =  $params['amount'] + $params['extra_price'] - $params['discount_amount'] - $params['promo_amount'] + $params['tax'] + $params['tourist_tax'];
		if($option_arr['o_to_be_paid'] == 'when_booking')
		{
			$total = $total + (float) $params['security'];
			$security = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['security'], $option_arr), $option_arr['o_currency']);
		}
		$total_price =  pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat($total, $option_arr), $option_arr['o_currency']);
		$extra_price = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['extra_price'], $option_arr), $option_arr['o_currency']);
		$discount_amount = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['discount_amount'], $option_arr), $option_arr['o_currency']);
		$promo_amount = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['promo_amount'], $option_arr), $option_arr['o_currency']);
		$deposit = pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat(@$params['deposit'], $option_arr), $option_arr['o_currency']);
		
		foreach ($recipients as $recipient)
		{
			switch ($recipient['type'])
			{
				case 'email':
					if (empty($recipient['email']))
					{
						continue;
					}
					if ($option_arr['o_send_email'] == 'smtp')
					{
						$pjEmail
							
							->setTransport('smtp')
							->setSmtpHost($option_arr['o_smtp_host'])
							->setSmtpPort($option_arr['o_smtp_port'])
							->setSmtpUser($option_arr['o_smtp_user'])
							->setSmtpPass($option_arr['o_smtp_pass'])
							->setSender($option_arr['o_smtp_user'])
						;
					}
					
					$body = $option_arr[@$map[$notification_id][1]];
					switch ($notification_id)
					{
						default:
							$body = str_replace(
								array(
									'{Name}','{Email}','{Phone}','{Adults}','{Children}',
									'{Notes}','{Address}','{City}','{Country}','{State}',
									'{Zip}','{CCType}','{CCNum}','{CCExpMonth}','{CCExpYear}',
									'{CCSec}','{PaymentMethod}','{StartDate}','{EndDate}','{Deposit}',
									'{Security}', '{Tax}', '{TouristTax}', '{Price}', '{TotalPrice}', '{ExtraPrice}', '{Discount}', '{Promo}', '{PromoCode}', '{CalendarID}','{ReservationID}',
									'{ReservationUUID}', '{CancelURL}', '{CalendarName}', '{Extras}'
								),
								array(
									pjSanitize::clean(@$params['c_name']), @$params['c_email'], pjSanitize::clean(@$params['c_phone']), @$params['c_adults'], @$params['c_children'],
									pjSanitize::clean(@$params['c_notes']), pjSanitize::clean(@$params['c_address']), pjSanitize::clean(@$params['c_city']), @$params['country'], pjSanitize::clean(@$params['c_state']),
									pjSanitize::clean(@$params['c_zip']), @$params['cc_type'], @$params['cc_num'], @$params['cc_exp_month'], @$params['cc_exp_year'],
									@$params['cc_code'], @$params['payment_method'], pjUtil::formatDate(@$params['date_from'], 'Y-m-d', $option_arr['o_date_format']), pjUtil::formatDate(@$params['date_to'], 'Y-m-d', $option_arr['o_date_format']), @$deposit,
									$security, $tax, $tourist_tax, $amount, @$total_price, @$extra_price, @$discount_amount, @$promo_amount, @$params['promo_code'],@$params['calendar_id'], @$params['id'],
									@$params['uuid'], sprintf('<a href="%1$sindex.php?controller=pjFront&action=pjActionCancel&cid=%2$u&id=%3$u&hash=%4$s">%1$sindex.php?controller=pjFront&action=pjActionCancel&cid=%2$u&id=%3$u&hash=%4$s</a>', PJ_INSTALL_URL, @$params['calendar_id'], @$params['id'], sha1(@$params['id'] . PJ_SALT)), $calendar_name, $extras
								),
								$body);
							break;
					}
					
					$pjEmail
						->setFrom($from_email)
						->setTo($recipient['email'])
						->setSubject($option_arr[@$map[$notification_id][0]])
						->setContentType('text/html')
						->send($body);
					break;
				case 'sms':
					if (empty($recipient['phone']) || !$smsPlugin)
					{
						continue;
					}
					$this->requestAction(array(
						'controller' => 'pjSms',
						'action' => 'pjActionSend',
						'params' => array(
							'number' => $recipient['phone'],
							'text' => $option_arr[@$map[$notification_id][2]],
							'type' => 'unicode',
							'key' => md5($option_arr['private_key'] . PJ_SALT)
						)
					), array('return'));
					break;
			}
		}
	}
	
	protected function pjActionGenerateInvoice($reservation_id)
	{
		if (!isset($reservation_id) || (int) $reservation_id <= 0)
		{
			return array('status' => 'ERR', 'code' => 400, 'text' => 'ID is not set ot invalid.');
		}
		$arr = pjReservationModel::factory()->find($reservation_id)->getData();
		$cnt_extras = pjReservationExtraModel::factory()->where('reservation_id', $reservation_id)->findCount()->getData();
		if (empty($arr))
		{
			return array('status' => 'ERR', 'code' => 404, 'text' => 'Reservation not found.');
		}
		$map = array(
			'Confirmed' => 'paid',
			'Pending' => 'not_paid',
			'Cancelled' => 'cancelled'
		);
		
		$deposit = $this->option_arr['o_deposit_type'] == 'percent' ? ($arr['amount'] * $this->option_arr['o_deposit']) / 100 : $this->option_arr['o_deposit'];
		
		$security = 0;
		
		$has_balance = 1;
		$total = 0;
		$amount_due = 0;
		$subtotal = $arr['amount'] + $arr['extra_price'];
		$discount = $arr['promo_amount'] + $arr['discount_amount'];
		$tax = (($subtotal - $discount) * $this->option_arr['o_tax']) / 100;
	
		if (isset($this->option_arr['o_security']) && (float) $this->option_arr['o_security'] > 0)
		{
			$security = (float) $this->option_arr['o_security'];
		}
		
		if (isset($this->option_arr['o_require_all_within']) && (int) $this->option_arr['o_require_all_within'] > 0 && strtotime(date("Y-m-d")) + (int) $this->option_arr['o_require_all_within'] * 86400 >= strtotime($arr['date_from']))
		{
			$has_balance = 0;
		}
		
		if($this->option_arr['o_to_be_paid'] == 'when_booking')
		{
			$total = ($subtotal - $discount) + $tax + $arr['tourist_tax'] + $security;
			$amount_due = $total - $arr['deposit'];
		}else{
			$total = ($subtotal - $discount) + $tax + $arr['tourist_tax'];
			$amount_due = $total - $arr['deposit'];
		}
		
		$items = array();
		$items[] = array(
							'name' => $this->option_arr['o_price_based_on'] == 'days' ? __('lblDaysPrice', true) : __('lblNightsPrice', true),
							'description' => sprintf("%s - %s; adults: %u; children: %u",
								pjUtil::formatDate($arr['date_from'], 'Y-m-d', $this->option_arr['o_date_format']),
								pjUtil::formatDate($arr['date_to'], 'Y-m-d', $this->option_arr['o_date_format']),
								$arr['c_adults'], $arr['c_children']),
							'qty' => 1,
							'unit_price' => $arr['amount'],
							'amount' => $arr['amount']
						);
		
		if($cnt_extras > 0)
		{
			$extra_arr = pjExtraModel::factory()
				->select('t1.*, t2.content AS name')
				->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->pjActionGetLocale()."'", 'left outer')
				->where('t1.status', 'T')
				->where("(t1.id IN (SELECT TCE.extra_id FROM `".pjReservationExtraModel::factory()->getTable()."` AS `TCE` WHERE `TCE`.reservation_id='".$reservation_id."') )")
				->orderBy('`name` ASC')
				->findAll()->getData();
			$extra_desc = array();
			$price_types = $this->option_arr['o_price_based_on'] == 'days' ? __('day_price_types', true) : __('price_types', true);
			foreach($extra_arr as $v)
			{
				$extra_desc[] = pjSanitize::html($v['name']) . ' (' . pjUtil::formatCurrencySign(pjUtil::converToCurrencyFormat($v['price'], $this->option_arr), $this->option_arr['o_currency']) . ' ' . $price_types[$v['price_type']] . ')'; 
			}
			$items[] = array(
								'name' => __('lblReservationExtraPrice', true),
								'description' => !empty($extra_desc) ? join("\r\n", $extra_desc) : NULL,
								'qty' => $cnt_extras,
								'unit_price' => $arr['extra_price'],
								'amount' => $arr['extra_price']
						);
		}
		$items[] = array(
				'name' => $this->option_arr['o_price_based_on'] == 'days' ? __('lblTouristTaxPerDay', true) : __('lblTouristTaxPerNight', true),
				'description' => NULL,
				'qty' => 1,
				'unit_price' => $arr['tourist_tax'],
				'amount' => $arr['tourist_tax']
		);
		if($this->option_arr['o_to_be_paid'] == 'when_booking')
		{
			$items[] = array(
					'name' => __('lblSecurityDeposit', true),
					'description' => NULL,
					'qty' => 1,
					'unit_price' => $security,
					'amount' => $security
			);
		}
		$response = $this->requestAction(
			array(
	    		'controller' => 'pjInvoice',
	    		'action' => 'pjActionCreate',
	    		'params' => array(
    				'key' => md5($this->option_arr['private_key'] . PJ_SALT),
					
					'uuid' => pjInvoiceModel::factory()->getInvoiceID(),
					'order_id' => $arr['uuid'],
					'foreign_id' => $arr['calendar_id'],
					'issue_date' => ':CURDATE()',
					'due_date' => ':CURDATE()',
					'created' => ':NOW()',
	    			'payment_method' => $arr['payment_method'],
					'status' => @$map[$arr['status']],
					'subtotal' => $subtotal,
    				'discount' => $discount,
					'tax' => $tax,
					'total' => $total,
					'paid_deposit' => $arr['deposit'],
					'amount_due' => $amount_due,
					'currency' => $this->option_arr['o_currency'],
					'notes' => $arr['c_notes'],
					'b_billing_address' => $arr['c_address'],
					'b_name' => $arr['c_name'],
					'b_address' => $arr['c_address'],
					'b_street_address' => $arr['c_address'],
	    			'b_country' => $arr['c_country'],
					'b_city' => $arr['c_city'],
					'b_state' => $arr['c_state'],
					'b_zip' => $arr['c_zip'],
					'b_phone' => $arr['c_phone'],
					'b_email' => $arr['c_email'],
					'items' => $items
					)
    		),
    		array('return')
		);
		if($amount_due > 0 && $has_balance == 1)
		{
			$second_items = array();
			
			$second_items[] = array(
					'name' => __('lblBalancePayment', true),
					'description' => __('lblReservationID', true) . ': ' . $arr['uuid'],
					'qty' => 1,
					'unit_price' => $amount_due,
					'amount' => $amount_due
			);
			$response = $this->requestAction(
				array(
						'controller' => 'pjInvoice',
						'action' => 'pjActionCreate',
						'params' => array(
						'key' => md5($this->option_arr['private_key'] . PJ_SALT),
							
						'uuid' => pjInvoiceModel::factory()->getInvoiceID(),
						'order_id' => $arr['uuid'],
						'foreign_id' => $arr['calendar_id'],
						'issue_date' => ':CURDATE()',
						'due_date' => ':CURDATE()',
						'created' => ':NOW()',
						'payment_method' => $arr['payment_method'],
						'status' => 'not_paid',
						'subtotal' => $amount_due,
						'discount' => 0,
						'tax' => 0,
						'total' => $amount_due,
						'paid_deposit' => $amount_due,
						'amount_due' => 0,
						'currency' => $this->option_arr['o_currency'],
						'notes' => $arr['c_notes'],
						'b_billing_address' => $arr['c_address'],
						'b_name' => $arr['c_name'],
						'b_address' => $arr['c_address'],
						'b_street_address' => $arr['c_address'],
						'b_country' => $arr['c_country'],
						'b_city' => $arr['c_city'],
						'b_state' => $arr['c_state'],
						'b_zip' => $arr['c_zip'],
						'b_phone' => $arr['c_phone'],
						'b_email' => $arr['c_email'],
						'items' => $second_items
					)
				),
				array('return')
			);
		}
		return $response;
	}

	protected function pjActionCheckDt($date_from, $date_to, $calendar_id=NULL, $id=NULL, $backend=false)
	{
		$calendar_id = !empty($calendar_id) ? (int) $calendar_id : $this->getForeignId();
		
		if ($backend && $calendar_id != $this->getForeignId())
		{
			$option_arr = pjOptionModel::factory()->getPairs($calendar_id);
		} else {
			$option_arr = $this->option_arr;
		}
		
		if ($option_arr['o_price_based_on'] == 'nights' && $date_from == $date_to && $option_arr['o_booking_behavior'] == 1)
		{
			return array('status' => 'ERR', 'code' => 100, 'text' => '');
		}
		
		$pjReservationModel = pjReservationModel::factory();
		$pjLimitModel = pjLimitModel::factory();
		
		$info = $pjReservationModel
			->prepare(sprintf("SELECT `date_from`, `date_to` 
				FROM `%1\$s`
				WHERE `calendar_id` = :calendar_id
				%2\$s
				AND `status` != :status
				AND ((`date_from` BETWEEN :date_from AND :date_to)
				OR ( `date_to` BETWEEN :date_from AND :date_to)
				OR ( `date_from` <= :date_from AND `date_to` >= :date_to))",
				$pjReservationModel->getTable(), (!empty($id) ? " AND `id` != :id" : NULL),
				($option_arr['o_price_based_on'] == 'nights' ? '<' : '<='),
				($option_arr['o_price_based_on'] == 'nights' ? '>' : '>=')
			))
			->exec(array(
				'calendar_id' => $calendar_id,
				'status' => 'Cancelled',
				'date_from' => $date_from,
				'date_to' => $date_to,
				'id' => $id
			))
			->getData();

		$limit_info = $pjLimitModel
			->prepare(sprintf("SELECT `date_from`, `date_to`,`blocked_days`
				FROM `%1\$s`
				WHERE `calendar_id` = :calendar_id
				%2\$s
				AND `blocked` = :blocked
				AND ((`date_from` BETWEEN :date_from AND :date_to)
				OR ( `date_to` BETWEEN :date_from AND :date_to)
				OR ( `date_from` <= :date_from AND `date_to` >= :date_to))",
					$pjLimitModel->getTable(), NULL,
					($option_arr['o_price_based_on'] == 'nights' ? '<' : '<='),
					($option_arr['o_price_based_on'] == 'nights' ? '>' : '>=')
			))
			->exec(array(
					'calendar_id' => $calendar_id,
					'blocked' => 'T',
					'date_from' => $date_from,
					'date_to' => $date_to,
			))
			->getData();
		
		foreach ($limit_info as $limit)
		{
			$limit_date_from = $limit['date_from'];
			$limit_date_to = ($option_arr['o_price_based_on'] == 'nights' && $limit['date_from'] == $limit['date_to']) ? date('Y-m-d', strtotime($limit['date_to']) + 86400) : $limit['date_to'];
			
			if($limit['blocked_days'] != "" && $limit['blocked_days'] != "1|2|3|4|5|6|0")
			{
				$blocked_days = explode("|", $limit['blocked_days']);
			
				$dt_from = strtotime($date_from);
				$dt_to = strtotime($date_to);
				for($i = $dt_from; $i <= $dt_to; $i = strtotime('+1 day', $i))
				{
					$week_day = date('w', $i);
						
					if(in_array($week_day, $blocked_days) && ($i >= strtotime($limit['date_from']) && $i <= strtotime($limit['date_to'])) )
					{
						$limit_date_from = date('Y-m-d', $i);
						$limit_date_to = date('Y-m-d', $i);
						if ($option_arr['o_price_based_on'] == 'nights')
						{
							$temp_ts = $i+ 86400;
							$week_day_to = date('w', $temp_ts);
							while(in_array($week_day_to, $blocked_days))
							{
								$temp_ts = $temp_ts + 86400;
								$week_day_to = date('w', $temp_ts);
							}
							$limit_date_to = date('Y-m-d', $temp_ts);
							$i = $temp_ts;
						}
						$temp = array();
						$temp['price_based_on'] = $option_arr['o_price_based_on'];
						$temp['date_from'] = $limit_date_from;
						$temp['date_to'] = $limit_date_to;
						$temp['status'] = 'Confirmed';
						$temp['from_limit'] = 1;
						$info[] = $temp;
					}
				}
			}else{
				$temp = array();
				$temp['price_based_on'] = $option_arr['o_price_based_on'];
				$temp['date_from'] = $limit_date_from;
				$temp['date_to'] = $limit_date_to;
				$temp['status'] = 'Confirmed';
				$temp['from_limit'] = 1;
				$info[] = $temp;
			}
		}
			
		$morning = array();
		$afternoon = array();
		$av_arr = array();
		$booked_arr = array();
		$nights_mode = false;
		if ($option_arr['o_price_based_on'] == 'nights')
		{ 
			$nights_mode = true;
		}
		if(isset($info) && count($info)  >0)
		{
			foreach ($info as $res)
			{
				$dt_from = strtotime($res['date_from']);
				$dt_to = strtotime($res['date_to']);
				for($i = $dt_from; $i <= $dt_to; $i = strtotime('+1 day', $i))
				{
					if(!empty($res['price_based_on']) && in_array($res['price_based_on'], array('nights', 'days')))
					{
						if($res['price_based_on'] == 'nights')
						{
							$nights_mode = true;
						}
					}
					if ($i == $dt_from && $nights_mode){
						$afternoon[$i] += 1;
					}elseif ($i == $dt_to && $nights_mode) {
						$morning[$i] += 1;
					}else {
						$booked_arr[$i] += 1;
					}
				}
			}
		}
		$s_from = strtotime($date_from);
		$s_to = strtotime($date_to);	
  		for($z = $s_from; $z <= $s_to; $z = strtotime('+1 day', $z))
		{
			if(isset($booked_arr[$z]) || isset($morning[$z]) || isset($afternoon[$z])) 
			{
				$booked_value = isset($booked_arr[$z]) ? $booked_arr[$z] : 0;
				$monring_value = isset($morning[$z]) ? $morning[$z] : 0;
				$afternoon_value = isset($afternoon[$z]) ? $afternoon[$z] : 0;
				
				$booked_value += min($monring_value,$afternoon_value);
				$morning[$z] -= min($monring_value, $afternoon_value);
				$afternoon[$z] -= min($monring_value, $afternoon_value);
				
				$av_arr[$z] = $booked_value;
				if($morning[$z] >= $afternoon[$z])
				{
					if($z > $s_from && $z <= $s_to)
					{
						$av_arr[$z] = $booked_value + ($morning[$z] );
					}
				}else{
					if($z >= $s_from && $z < $s_to)
					{
						$av_arr[$z] = $booked_value + ($afternoon[$z]);
					}
				}
			}else{
				$av_arr[$z] = 0;
			}
		}
		$cnt = max($av_arr);
		
		if(empty($id))
		{
			if ($cnt < (int) $option_arr['o_bookings_per_day'])
			{
				$result = array('status' => 'OK', 'code' => 200, 'text' => '');
			} else {
				$result = array('status' => 'ERR', 'code' => 100, 'text' => '');
			}
		}else{
			if ($cnt < (int) $option_arr['o_bookings_per_day'])
			{
				$result = array('status' => 'OK', 'code' => 200, 'text' => '');
			} else {
				$result = array('status' => 'ERR', 'code' => 100, 'text' => '');
			}
		}
		return $result;
	}
	
	protected function pjActionCalcPrices($calendar_id, $start_dt, $end_dt, $adults, $children, $extras, $extras_qty, $promo_code, $option_arr, $locale_id)
	{
		$tourist_tax = 0;
		$amount = 0;
		$extra_price = 0;
		$sub_total = 0;
		$tax = 0;
		$total = 0;
		$deposit = 0;
		$net = 0;
		$security = 0;
		$promo_valid = 0;
		$promo_amount = 0;
		$promo_type = '';
		$promo_percentage = 0;
		$discount_valid = 0;
		$discount_check = 0;
		$discount_amount = 0;
		$discount_type = '';
		$discount_percentage = 0;
		$discount_name = '';
		$temp_discount_amount;
		
		$nights = ceil(($end_dt - $start_dt) / 86400);
		$early_nights = ceil(($start_dt - time()) / 86400);
		if ($option_arr['o_price_based_on'] == 'days')
		{
			$nights += 1;
			$early_nights += 1;
		}
		
		$price_arr = array();
		if (pjObject::getPlugin('pjPrice') !== NULL && $option_arr['o_price_plugin'] == 'price')
		{
			$price_arr = pjPriceModel::factory()->getPrice(
					$calendar_id,
					date("Y-m-d", $start_dt),
					date("Y-m-d", $end_dt),
					$this->option_arr,
					@$adults,
					(int) $option_arr['o_bf_children'] !== 1 ? @$children : 0
			);
		
		} elseif (pjObject::getPlugin('pjPeriod') !== NULL && $option_arr['o_price_plugin'] == 'period') {
			$price_arr = pjPeriodModel::factory()->getPrice(
					$calendar_id,
					date("Y-m-d", $start_dt),
					date("Y-m-d", $end_dt),
					$this->option_arr,
					@$adults,
					(int) $option_arr['o_bf_children'] !== 1 ? @$children : 0
			);
		}
		$people = @$adults + ((int) $option_arr['o_bf_children'] !== 1 ? @$children : 0);
		$tourist_taxt_per_nights = 0;
		if((float)$option_arr['o_tourist_tax'] > 0)
		{
			$tourist_taxt_per_nights = (float)$option_arr['o_tourist_tax'] * $nights;
		}
		if(isset($option_arr['o_max_tax']) && (float)$option_arr['o_max_tax'] > 0 && $tourist_taxt_per_nights > (float)$option_arr['o_max_tax'])
		{
			$tourist_taxt_per_nights = (float)$option_arr['o_max_tax'];
		}
		$tourist_tax = $people * $tourist_taxt_per_nights;
		
		$net = $price_arr['net'];
		$amount = $price_arr['amount'];
		$tax = $price_arr['tax'];
		
		if(isset($extras) && !empty($extras))
		{
			$extra_arr = pjExtraModel::factory()->whereIn('t1.id', array_keys($extras))->findAll()->getData();
			foreach($extra_arr as $k => $v)
			{
				$qty = $extras_qty[$v['id']];
				switch ($v['price_type']) {
					case 'person':
				 		$extra_price += $v['price'] * $qty * $people;
					break;
					
					case 'night':
						$extra_price += $v['price'] * $qty * $nights;
					break;
					
					case 'person_night':
						$extra_price += $v['price'] * $qty * $people * $nights;
					break;
					case 'count':
						$extra_price += $v['price'] * $qty;
					break;
					case 'count_night':
						$extra_price += $v['price'] * $qty * $nights;
					break;
					case 'one_time':
						$extra_price += $v['price'] * $qty;
					break;
				}
			}
		}
		
		$sub_total = $amount + $extra_price;
		
		if($promo_code != '')
		{
			$voucher_arr = pjVoucherModel::factory()
				->where('code', pjObject::escapeString($promo_code))
				->where("t1.id IN (SELECT TCV.voucher_id FROM `".pjCalendarVoucherModel::factory()->getTable()."` AS `TCV` WHERE `TCV`.calendar_id='".$calendar_id."') ")
				->findAll()
				->getData();
			if(!empty($voucher_arr))
			{
				$voucher_arr = $voucher_arr[0];
				switch ($voucher_arr['condition']) {
					case 'period':
						$date_from_ts = strtotime($voucher_arr['date_from']);
						$date_to_ts = strtotime($voucher_arr['date_to']);
						if( ($start_dt >= $date_from_ts && $start_dt <= $date_to_ts) || ($end_dt >= $date_from_ts && $end_dt <= $date_to_ts) || ($date_from_ts >= $start_dt && $date_from_ts <= $end_dt ) || ($date_to_ts >= $start_dt && $date_to_ts <= $end_dt ))
						{
							$promo_valid = 1;
						}
						break;
		
					case 'made':
						$date_from_ts = strtotime($voucher_arr['date_from']);
						$date_to_ts = strtotime($voucher_arr['date_to']);
						if((time() >= $date_from_ts && time() <= $date_to_ts))
						{
							$promo_valid = 1;
						}
						break;
							
					case 'both':
						$date_from_ts = strtotime($voucher_arr['date_from']);
						$date_to_ts = strtotime($voucher_arr['date_to']);
						if( (($start_dt >= $date_from_ts && $start_dt <= $date_to_ts) || ($end_dt >= $date_from_ts && $end_dt <= $date_to_ts) || ($date_from_ts >= $start_dt && $date_from_ts <= $end_dt ) || ($date_to_ts >= $start_dt && $date_to_ts <= $end_dt )) && (time() >= $date_from_ts && time() <= $date_to_ts))
						{
							$promo_valid = 1;
						};
						break;
				}
				if($promo_valid == 1)
				{
					$cnt_reservations = pjReservationModel::factory()->where('status', 'confirmed')->where('promo_code', pjObject::escapeString($promo_code))->findCount()->getData();
					if($cnt_reservations >= (int) $voucher_arr['used_count'])
					{
						$promo_valid = 0;
					}else{
						$promo_amount = (float) $voucher_arr['discount'];
						$promo_type = $voucher_arr['type'];
						if($voucher_arr['type'] == 'percent')
						{
							$promo_percentage = (float) $voucher_arr['discount'];
							if($voucher_arr['apply_on'] == 'both')
							{
								$promo_amount = ($amount + $extra_price) * (float) $voucher_arr['discount'] / 100;
							}else if($voucher_arr['apply_on'] == 'room'){
								$promo_amount = ($amount) * (float) $voucher_arr['discount'] / 100;
							}else if($voucher_arr['apply_on'] == 'extra'){
								$promo_amount = ($extra_price) * (float) $voucher_arr['discount'] / 100;
							}
						}
					}
				}
			}
		}
		
		
		$discount_arr = pjDiscountModel::factory()
			->select('t1.*, t2.content as name')
			->join('pjMultiLang', "t2.foreign_id = t1.id AND t2.model = 'pjDiscount' AND t2.locale = '".$locale_id."' AND t2.field = 'name'", 'left')
			->where("(t1.id IN (SELECT TCV.discount_id FROM `".pjCalendarDiscountModel::factory()->getTable()."` AS `TCV` WHERE `TCV`.calendar_id='".$calendar_id."'))")
			->findAll()
			->getData();
		
		foreach($discount_arr as $k => $v)
		{
			$condition = false;
			switch ($v['condition']) {
				case 'period':
					$date_from_ts = strtotime($v['date_from']);
					$date_to_ts = strtotime($v['date_to']);
					if( ($start_dt >= $date_from_ts && $start_dt <= $date_to_ts) || ($end_dt >= $date_from_ts && $end_dt <= $date_to_ts) || ($date_from_ts >= $start_dt && $date_from_ts <= $end_dt ) || ($date_to_ts >= $start_dt && $date_to_ts <= $end_dt ))
					{
						$condition = true;
					}
					break;
			
				case 'made':
					$date_from_ts = strtotime($v['date_from']);
					$date_to_ts = strtotime($v['date_to']);
					if((time() >= $date_from_ts && time() <= $date_to_ts))
					{
						$condition = true;
					}
					break;
						
				case 'both':
					$date_from_ts = strtotime($v['date_from']);
					$date_to_ts = strtotime($v['date_to']);
					if( (($start_dt >= $date_from_ts && $start_dt <= $date_to_ts) || ($end_dt >= $date_from_ts && $end_dt <= $date_to_ts) || ($date_from_ts >= $start_dt && $date_from_ts <= $end_dt ) || ($date_to_ts >= $start_dt && $date_to_ts <= $end_dt )) && (time() >= $date_from_ts && time() <= $date_to_ts))
					{
						$condition = true;
					};
					break;
			}
			if($condition == true)
			{
				switch ($v['options']) {
					case 'early':
						if($early_nights >= (int) $v['early_days'])
						{
							$discount_check = 1;
						}
						break;
				
					case 'persons':
						if($people >= (int) $v['min_persons'] && $people <= (int) $v['max_persons'])
						{
							$discount_check = 1;
						}
						break;
							
					case 'family':
						if((int) $option_arr['o_bf_children'] !== 1 && (int) @$children > 0)
						{
							$discount_check = 1;
						}
						break;
					case 'duration':
						if($nights >= (int) $v['min_duration'] && $nights <= (int) $v['max_duration'])
						{
							$discount_check = 1;
						}	
						break;
				}
				if($discount_check == 1)
				{
					$temp_discount_amount = (float) $v['discount'];
					if($v['type'] == 'percent')
					{
						$temp_discount_amount = ($amount + $extra_price) * (float) $v['discount'] / 100;
					}
					if($temp_discount_amount >= $discount_amount)
					{
						$discount_amount = $temp_discount_amount;
						$discount_name = pjSanitize::html($v['name']);
						$discount_type = $v['type'];
						if($v['type'] == 'percent')
						{
							$discount_percentage = (float) $v['discount'];
						}
					}
					$discount_valid = 1;
					$discount_check = 0;
				}
			}
		}

		if (isset($option_arr['o_tax']) && (float) $option_arr['o_tax'] > 0)
		{
			$tax = (($sub_total - $promo_amount - $discount_amount) * (float) $option_arr['o_tax']) / 100;
		}
		
		if (isset($option_arr['o_security']) && (float) $option_arr['o_security'] > 0)
		{
			$security = (float) $option_arr['o_security'];
		}
		
		if (isset($option_arr['o_require_all_within']) && (int) $option_arr['o_require_all_within'] > 0 &&
				strtotime(date("Y-m-d")) + (int) $option_arr['o_require_all_within'] * 86400 >= $start_dt)
		{
			
			$deposit = $sub_total - $promo_amount - $discount_amount + $tax + $tourist_tax + $security;
				
		} elseif (isset($option_arr['o_deposit']) && (float) $option_arr['o_deposit'] > 0) {
				
			switch ($option_arr['o_deposit_type'])
			{
				case 'percent':
					$deposit = (($sub_total - $promo_amount - $discount_amount + $tax + $tourist_tax) * (float) $option_arr['o_deposit']) / 100 + $security;
					break;
				case 'amount':
					$deposit = (float) $option_arr['o_deposit'] + $security;
					break;
			}
		}
		$total = $sub_total - $promo_amount - $discount_amount + $tax + $tourist_tax;
		if($option_arr['o_to_be_paid'] == 'when_booking')
		{
			$total = $total + $security;
		}
		if($option_arr['o_to_be_paid'] == 'on_arrival')
		{
			$deposit = $deposit - $security;
		}
		$unformat_deposit = $deposit;
		$unformat_total = $total;
		
		$result = compact('nights', 'amount', 'extra_price', 'deposit', 'sub_total', 'tax', 'tourist_tax', 'total', 'security', 'net', 'extras', 'promo_valid', 'promo_code', 'promo_amount', 'promo_type', 'promo_percentage', 'discount_valid', 'discount_amount', 'discount_type', 'discount_percentage', 'discount_name', 'unformat_deposit', 'unformat_total');
		
		return $result;
	}
	static public function getFromEmail($option_arr)
	{
		$email = $option_arr['o_email_address'];
		if($email == '')
		{
			$arr = pjUserModel::factory()
				->findAll()
				->orderBy("t1.id ASC")
				->limit(1)
				->getData();
			$email = !empty($arr) ? $arr[0]['email'] : null;
		}
		return $email;
	}
	static public function getOwnerEmail($calendar_id)
	{
		$arr = pjCalendarModel::factory()->select("t1.*, t2.email")->join("pjUser", "t1.user_id=t2.id", 'left')->find($calendar_id)->getData();
		if(!empty($arr))
		{
			if(!empty($arr['email']))
			{
				return $arr['email'];
			}else{
				return null;
			}
		}else{
			return null;
		}
	}
}
?>