/administrator/components/com_virtuemart/classes/ps_booking.php
PHP | 1414 lines | 876 code | 281 blank | 257 comment | 194 complexity | f0002ad286d3694e5c19b8bf84821c36 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
- <?php
- if( ! defined( '_VALID_MOS' ) && ! defined( '_JEXEC' ) )
- die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ;
- require_once( CLASSPATH . "ps_discount.php" );
- require_once( CLASSPATH . "ps_season.php" );
- require_once( CLASSPATH . "ps_stage_payments.php" );
-
- class ps_booking {
-
- var $status = 0;
- var $total = 0;
- var $subtotal = 0;
- var $discount = 0;
- var $extras = 0;
- var $pets = 0;
- var $original = 0;
- var $tax = 0;
- var $tax_rate = 0;
- var $tax_state = 0;
- var $tax_resort = 0;
- var $dateFrom;
- var $dateTo;
- var $discounts = array();
- var $extras_details = array('extras_total'=>0);
- var $nights;
- var $nightPrices = array();
- var $seasons = array();
- var $maxPrice = 0;
- var $minNights = 0;
- var $securityDeposit = 48;
-
- /*** Booking info ***/
- var $booking_id;
- var $dateBooked;
- var $unixdateBooked;
- var $unixdateFrom;
- var $unixdateTo;
- var $people;
- var $arrivalAirport;
- var $departureAirport;
- var $arrivalFlightNo;
- var $departureFlightNo;
- var $hasPets;
- var $cleaning;
-
- /** Property Info **/
- var $property_id;
- var $property_data;
- /** Extra flags **/
- var $owner = 0;
- var $admin = 0;
- var $free = 0;
- var $payment_id = 0;
- var $display_errors = 1;
-
- /** Object holders **/
- var $discountObject;
- var $extrasObjects;
- var $ps_season;
- var $validation = array();
-
- /**
- *
- *
- */
- function __construct() {
-
- $this->status = 0;
-
- //Setup discounts class
- $this->discountObject = new ps_discount($this);
- }
-
-
- function ps_booking(){
- $this->__construct();
- }
-
-
- /**
- * Calculate the base value of the booking
- * and store the booking data in the object
- * then update the session to store the new values
- *
- */
- function process($saveSession = 1, $display_errors = 1){
- global $VM_LANG;
-
- //Always get the property ID
- $this->status = 0;
- $this->property_id = vmget($_REQUEST,'property_id',$this->property_id);
- $this->display_errors = $display_errors;
- $this->validationReset();
-
- //Setup discounts class
- $this->discountObject = new ps_discount($this);
-
- if(!$this->property_id){
-
- //Throw error
- $GLOBALS['vmLogger']->err($VM_LANG->_("VM_BOOKING_PROCESS_ERR"));
- $this->status = 0;
- return false;
- }else{
- //Calculate booking
- if(!$this->getPropertyData()) return false;
- $this->owner = $this->isOwner();
- $this->admin = $this->isAdmin();
- $this->free = $this->isFree();
- $this->dateBooked = date('Y-m-d');
- $this->unixdateBooked = strtotime($this->dateBooked);
- if(!$this->setDates()) return false;
- $this->people = vmget($_REQUEST,'people', $this->people);
- $this->arrivalAirport = vmget($_REQUEST,'arrivalAirport');
- $this->departureAirport = vmget($_REQUEST,'departureAirport');
- $this->extras_details = $this->setExtras(vmget($_REQUEST,'quantity'));
- $this->arrivalFlightNo = vmget($_REQUEST,'arrivalFlightNo');
- $this->departureFlightNo = vmget($_REQUEST,'departureFlightNo');
- $this->hasPets = vmget($_REQUEST,'pets');
- $this->payInFull = (bool)vmget($_REQUEST,'pay_in_full');
-
- //print_r($this);
- //exit;
-
- if(!$this->setPrice()){
- $this->original =
- $this->total =
- $this->subtotal =
- $this->discount =
- $this->tax =
- $this->tax_rate =
- $this->tax_state =
- $this->tax_resort =
- $this->maxPrice =
- $this->discount = 0;
- $this->discounts = array();
- $this->status = 0;
- return false;
- }
- $this->setPaymentMethod();
-
- //Commit the populated variables to the session
- if($saveSession) $this->updateSession();
-
- return $this->status;
- }
- }
-
- /**
- * Updates the session and stores
- * this object in a session var
- *
- */
- function updateSession(){
-
- @session_start();
- //Set the session var ['booking']['object'] equal to $this;
- $_SESSION['booking']['object'] = serialize($this);
- $_SESSION['booking']['cart'] = serialize(vmget($_SESSION,'cart',''));
-
-
- }
-
-
- function restoreSession(){
- @session_start();
- //Check if booking array is set
- if(!isset($_SESSION['booking'])){
- $_SESSION['booking'] = array();
- }
-
- //Restore booking session data
- if(isset($_SESSION['booking']['object'])) {
- $object = unserialize($_SESSION['booking']['object']);
- foreach(get_object_vars($this) as $key => $val ){
- if($key != 'discountObject') $this->$key = $object->$key;
- }
- }
-
- //Reset the status
- //$this->status = 0;
- }
-
- /**
- * Purges the session and resets all of $this vars to default
- *
- */
- function removeSession(){
- unset($_SESSION['booking']['object']);
- $this->reset();
- }
-
- /**
- * Reset to defaults
- *
- */
- function reset(){
- $tmp_bk = new ps_booking();
- foreach(get_class_vars((get_class($this))) as $key => $value){
- unset($this->$key);
- $this->$key = $tmp_bk->$key;
- }
- }
-
-
- /**
- * Core routing for calculating the base value of a booking
- *
- */
- function setPrice() {
- global $perm, $VM_LANG;
-
- //Clear the seasons and nightly prices array first
- $this->seasons = array();
- $this->nightPrices = array();
-
- $this->getNights();
- $this->unixdateFrom = strtotime($this->dateFrom);
- $this->unixdateTo = strtotime($this->dateTo);
- //Validate the date ranges
- if(!$this->validateDates()){
- return false;
- }
-
- if(vmGet($_REQUEST,'security_deposit',0) !== false && $perm->check( "admin,storeadmin")){
- $this->securityDeposit = vmGet($_REQUEST,'security_deposit',0);
- }
-
- //read in cleaning charge from property
- $this->cleaning = $this->getPropertyField('cleaning_fee') ? $this->getPropertyField('cleaning_fee') : (defined('VB_CLEANING_CHARGE') ? VB_CLEANING_CHARGE : 0);
-
- //Loop through each day and get its associated price
- $current_total = $this->total;
- $total = 0;
- $original = 0;
- $discount = 0;
- $discounts = array();
- for($i = 0; $i < $this->nights; $i++){
-
- //Get the current day in yyyy-mm-dd format
- $currentDay = date('Y-m-d', ($this->unixdateFrom) + ($i * 86400));
-
-
- //Get the nightly price to $currentDay
- $nightPrice = $this->getNightlyPrice($currentDay, $i);
- if($nightPrice === false){
- return false;
- }
-
- //Loop through the returned advanced discounts
- $nightly_discount = 0;
- foreach($nightPrice['discounts'] as $k => $d){
-
- if(!isset($discounts[$k])){
- $discounts[$k] = new stdClass;
- $discounts[$k]->id = $d->id;
- $discounts[$k]->name = $d->name;
- $discounts[$k]->value = 0;
- }
- //Store todays advanced discount
- $discounts[$k]->value += $d->value;
- $nightly_discount += $d->value;
- }
- $discount += $nightly_discount;
-
- //Add the returned values to the global counters
- $nightPrice['discount'] = $nightly_discount;
- $nightPrice['total'] = $nightPrice['total'] - $nightly_discount;
- $original += $nightPrice['original'];
- $total += $nightPrice['total'];
- //Store night prices
- $this->nightPrices[$currentDay] = $nightPrice;
- }
- //Run the total discount routines
- $total_discount = 0;
- foreach($this->getTotalDiscounts($total) as $k => $d){
- if(!isset($discounts[$k])){
- $discounts[$k] = new stdClass;
- $discounts[$k]->id = $d->id;
- $discounts[$k]->name = $d->name;
- $discounts[$k]->value = 0;
- }
- //Store todays advanced discount
- $discounts[$k]->value += $d->value;
- $total_discount += $d->value;
- }
- $discount += $total_discount;
- ksort($discounts);
-
- //Create the total price, subtract off discounts and save all
- $this->discount = $discount;
- $this->discounts = $discounts;
- $this->extras = $this->extras_details['extras_total'];
-
-
-
- /*Organic Mod: This is what you need to change to calculate pets VB_PET_RATE * $this->nights*/
- $this->pets = ($this->hasPets && defined('VB_PET_RATE') && VB_PET_RATE) ? ((VB_PET_RATE * $this->nights)*$this->hasPets) : 0;
-
- $this->original = $original;
- $this->subtotal = ($original - $this->discount + $this->pets + $this->cleaning);
-
- //Check if the an admin has overridden the price, if so, set the new subtotal and zero the discounts as they no longer apply
- if(vmGet($_REQUEST,'use_new_price',0) && $perm->check( "admin,storeadmin")){
- //Get the tax rate for this property
- $taxes = $this->getTaxRate($this->property_id);
- //Set the subtotal
- $this->subtotal = vmGet($_REQUEST,'new_total',0) / (1+$taxes->tax_total);
-
- //Zero discounts as they no longer apply
- $this->discount = 0;
- $this->discounts = array();
- }
-
- //Set the tax rates due for this booking
- $this->setTaxRates($this->property_id);
- //Check that total and subtotal and tax are not negative
- if($this->tax < 0) $this->tax = 0;
- if($this->subtotal < 0) $this->subtotal = 0;
- if($this->total < 0) $this->total = 0;
-
- if($this->free){
- $this->tax = 0;
- $this->tax_state = 0;
- $this->tax_resort = 0;
- $this->subtotal = 0;
- $this->total = 0;
- }
-
- //Get the highest price it could have ever been
- $this->setMaxPrice();
-
- $this->status = 1;
- //Check if we are updating an order and wether we are displaying errors, if not, show success msg
- $order_id = vmGet($_REQUEST,'order_id');
- if($this->total != $current_total && $this->display_errors && !$order_id){
- $GLOBALS['vmLogger']->info( $VM_LANG->_('VM_BOOKING_STORED') );
- }
- return true;
- }
-
-
- /**
- * This function provides a quick easy way to get a price of a booking
- * pass the property id to this funciton
- *
- * @param int $id = property_id
- * @return array()
- */
- function getPrice($id = 0, $returnTemplate = 1, $displayErrors = 0){
- global $CURRENCY_DISPLAY, $CURRENCY, $auth, $VM_LANG;
- $VM_LANG->load('booking');
-
- //Always get the property ID
- if($id) $this->property_id = $id;
- else if(vmGet($_REQUEST,'property_id',0)) $this->property_id = vmGet($_REQUEST,'property_id',0);
-
- $dateFrom = vmGet($_REQUEST,'dateFrom',array());
- $dateTo = vmGet($_REQUEST,'dateTo',array());
-
- $GLOBALS['cache_id'] = isset($GLOBALS['cache_id']) ? $GLOBALS['cache_id'] : 'vm_' . @md5( 'bookingGetPrice'. $id. $dateFrom .$dateTo. @$auth["shopper_group_id"]);
- $tpl = vmTemplate::getInstance();
- //Check the arrival and departure dates
- if(!defined('parsedDates')){
- if($this->parseDate($dateFrom) == -1){
- $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_DATE_ERR_ARR_INV') );
- }
- if($this->parseDate($dateTo) == -1){
- $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_DATE_ERR_DEPT_INV') );
- }
- define('parsedDates',1);
- }
-
- //Check if we have supplied a valid arrival and departure date
- if($this->property_id){
- //Check the arrival and departure dates are valid
- if($this->getDate('dateFrom') && $this->getDate('dateTo')){
-
- //Do the processing to retrieve a price
- $this->process(0,$displayErrors);
-
- $values = array('total'=> $this->total,
- 'subtotal'=>$this->subtotal,
- 'original'=>$this->original,
- 'tax'=>$this->tax,
- 'discount'=>$this->discount,
- 'max'=>$this->maxPrice,
- 'total_str'=>$CURRENCY_DISPLAY->getFullValue($this->total),
- 'subtotal_str'=>$CURRENCY_DISPLAY->getFullValue($this->subtotal),
- 'tax_str'=>$CURRENCY_DISPLAY->getFullValue($this->tax),
- 'original_str'=>$CURRENCY_DISPLAY->getFullValue($this->original),
- 'discount_str'=>$CURRENCY_DISPLAY->getFullValue($this->discount),
- 'max_str'=>$CURRENCY_DISPLAY->getFullValue($this->maxPrice),
- );
-
- if(!$returnTemplate){
- return $values;
- }else{
- $tpl->set_vars($values);
- return $tpl->fetch( 'booking/booking.quick_price_total.tpl.php' );
- }
- }else{
-
- //Store the season object in $this season var
- if(is_null($this->ps_season)) $this->ps_season = new ps_season();
- $bounds = $this->ps_season->getSeasonBounds($this->property_id);
- $min = vmGet($bounds,'minimum');
- $max = vmGet($bounds,'maximum');
-
- //If we found a price return
- if($min && $max && ($min->rate && $max->rate)){
- //Get the tax rate for this property
- $taxes = $this->getTaxRate();
- $tax_rate = 1+($taxes ? $taxes->tax_total : 0);
-
- //Calculate inclusive of tax price
- $min->rate_nightly = $min->rate * ($min->per_person_pricing ? $min->min_people : 1);
- $max->rate_nightly = $max->rate * ($max->per_person_pricing ? $max->min_people : 1);
- $min->rate_weekly = $min->rate_nightly * 7;
- $max->rate_weekly = $max->rate_nightly * 7;
- $min->rate_gross = $min->rate * $tax_rate;
- $min->rate_weekly_gross = round($min->rate_weekly * $tax_rate);
- $max->rate_gross = $max->rate * $tax_rate;
- $max->rate_weekly_gross = round($max->rate_weekly * $tax_rate);
- $min->currency = $CURRENCY_DISPLAY->getFullValue($CURRENCY->convert($min->rate_gross));
- $max->currency = $CURRENCY_DISPLAY->getFullValue($CURRENCY->convert($max->rate_gross));
- $min->currency_weekly = $CURRENCY_DISPLAY->getFullValue($CURRENCY->convert($min->rate_weekly_gross), 0);
- $max->currency_weekly = $CURRENCY_DISPLAY->getFullValue($CURRENCY->convert($max->rate_weekly_gross), 0);
- $return = array('min'=>$min,'max'=>$max);
-
- if(!$returnTemplate){
- return $return;
- }else{
- $tpl->set_vars($return);
- return $tpl->fetch( 'booking/booking.quick_price_bounds.tpl.php' );
- }
- }else{
- return false;
- }
- }
- }else{
- $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_NO_PROP_ERR') );
- return false;
- }
- }
-
-
-
- /**
- * Sets the maximum price for the date range, use for showing out of season discounts
- */
-
- function setMaxPrice(){
-
- //Get the highest price it could have ever been
- if(is_null($this->ps_season)) $this->ps_season = new ps_season();
- $bounds = $this->ps_season->getSeasonBounds($this->property_id);
-
- if(isset($bounds['maximum'])){
- $max = $bounds['maximum'];
- $people = $max->min_people > $this->people ? $max->min_people : $this->people;
- $this->maxPrice = $max->rate * ($max->per_person_pricing ? $people : 1) * $this->nights;
- }
- }
-
-
- function getMaxPrice(){
-
- }
-
- /**
- * This function retrieves the tax rate for a particular property
- *
- */
- function getTaxRate(){
-
- $db = new ps_DB();
- $db->query("SELECT t.tax_rate, t.tax_resort, (t.tax_rate + t.tax_resort) AS tax_total FROM #__{vm}_property_tax as p, #__{vm}_tax_rate as t
- WHERE p.tax_rate_id = t.tax_rate_id
- AND p.property_id = $this->property_id");
- $db->next_record();
-
- if($db->num_rows()){
- return $db->get_row();
- }else{
- return false;
- }
- }
-
-
-
- /**
- * This functions sets the tax rates for $this
- *
- */
- function setTaxRates(){
-
- $taxes = $this->getTaxRate($this->property_id);
- if($taxes){
- //Calculate the state and resort tax
- $this->tax_state = $taxes->tax_rate * $this->subtotal;
- $this->tax_resort = $taxes->tax_resort * $this->subtotal;
- $this->tax = $this->tax_state + $this->tax_resort;
- $this->tax_rate = $taxes->tax_total;
- $this->total = (float) $this->subtotal + (float) $this->tax;
- if($this->total > 0) {
- $this->total += (float) $this->securityDeposit;
- }
- }else{
- //No tax to be applied
- $this->total = (float) $this->subtotal;
- if($this->total > 0) {
- $this->total += (float) $this->securityDeposit;
- }
- }
- }
-
-
-
- /**
- * This function retrieves the nightly price for a property if one is set,
- * if not, it retrieves the global nightly price
- *
- * @param unknown_type $date
- * @return unknown
- */
- function getNightlyPrice($date, $day_no){
- global $VM_LANG;
-
- //Get rate specific to this property if any
- $season = $this->getSeason($date, $this->property_id);
- $rate = null;
-
- //Get the default pricing calculation
- $default_pricing = defined('VB_PER_PERSON_PRICING') ? VB_PER_PERSON_PRICING : 1;
-
- //Set the return variable
- $return = array();
-
- //Check if we have a property specific rate
- if($season){
- $seasonid = $season->f('rate_id');
- $rate = $season->f('rate');
-
- }else{
- //Get global rate
- $season = $this->getSeason($date);
- if($season){
- $seasonid = $season->f('rate_id');
- $rate = $season->f('rate');
- }
- }
-
- if($rate !== null){
-
- $min_ppl = $season->f('min_people');
- $season_discount_value = $season->f('discount');
-
- //Check how we are calculating pricing
- $per_person_pricing = $season->f('per_person_pricing') !== null ? $season->f('per_person_pricing') : $default_pricing;
-
- //Check if we are charging per person or per property (0|1)
- if($per_person_pricing){
- //Work out how many people we are charging
- if($this->people < $min_ppl){
- $people = $min_ppl;
- }else{
- $people = $this->people;
- }
- }else{
- $people = 1;
- }
- //return the rate multiplied by the number of guests
- $base_price = $rate * $people;
- $total = $base_price;
-
- //Run the advanced discount routines
- $discounts = $this->getNightlyDiscounts($seasonid, $season, $date, $day_no, $total);
- if($discounts === false){
- return false;
- }
-
- //Validate that the booking conforms to the season settings
- if(!$this->validate_season($season)){
- return false;
- }
-
- //Store season (simple) discount
- if($season_discount_value > 0){
- $season_discount = new stdClass();
- $season_discount->name = 'Season Discount';
- $season_discount->value = ($total * $season_discount_value) / 100; //Calculate the discount
- //Add the season discount first
- $discounts[-999] = $season_discount;
- }
- ksort($discounts);
-
- //Store the totals and calculate the overall total
- $return['total'] = $total;
- $return['original'] = $base_price;
- $return['discounts'] = $discounts;
-
- return $return;
-
- }else{
- //Error, no seasonal pricing available
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_NO_RPICING_ERR') );
- return false;
- }
- }
-
-
-
- /**
- * This function will retrieve the season information for a specific date and property
- *
- * @param unknown_type $date
- * @param unknown_type $property_id
- * @return unknown
- */
- function getSeason($date, $property_id = 0){
-
- //Store the season object in $this season var
- if(is_null($this->ps_season)) $this->ps_season = new ps_season();
-
- //Get the season from ps_booking_seaons
- $season = $this->ps_season->getSeason('', $property_id, $date, '', '', '', 0);
- if($season){
- if(!array_key_exists($season->f('rate_id'), $this->seasons)) $this->seasons[$season->f('rate_id')] = $season;
- }
-
- return $season;
- }
-
-
-
- /**
- * Validates that the information submitted by the user
- * meets the minimum and maximum requirements for the given
- * season.
- *
- * @param unknown_type $season
- * @return unknown
- */
- function validate_season($season){
- global $perm, $VM_LANG;
-
- $min_ppl_force = $season->f('min_people_force');
- $min_ppl = $season->f('min_people');
- $max_ppl = $season->f('max_people');
- $min_stay = $this->minNights && $this->minNights < $season->f('min_stay') ? $this->minNights : $season->f('min_stay');
- $max_stay = $season->f('max_stay');
- $changeover = $season->f('changeover_day');
- $changeforce = $season->f('changeover_force');
- if(vmGet($_REQUEST,'ignore',0) && $perm->check('admin,storeadmin')) $this->validation = array();
-
- //Check if the booking exceeds the min/max values for this season
- if(($this->people == 0) && $this->validateCheck('PEOPLE')){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_MIN_PERSON'));
- return false;
- }
-
- if(($this->people < $min_ppl && $min_ppl != 0 && $min_ppl_force) && $this->validateCheck('MIN_PEOPLE')){
- if($this->display_errors) $GLOBALS['vmLogger']->err( sprintf($VM_LANG->_('VM_BOOKING_MIN_GUESTS'),$min_ppl));
- return false;
- }
-
- if(($this->people > $max_ppl && $max_ppl != 0) && $this->validateCheck('MAX_PEOPLE')){
- if($this->display_errors) $GLOBALS['vmLogger']->err( sprintf($VM_LANG->_('VM_BOOKING_MAX_GUESTS'),$max_ppl));
- return false;
- }
-
- if(($this->nights < $min_stay && $min_stay != 0) && $this->validateCheck('MIN_NIGHTS')){
- if($this->display_errors) $GLOBALS['vmLogger']->err( sprintf($VM_LANG->_('VM_BOOKING_MIN_NIGHTS'),$min_stay));
- return false;
- }
-
- if(($this->nights > $max_stay && $max_stay != 0) && $this->validateCheck('MAX_NIGHTS')){
- if($this->display_errors) $GLOBALS['vmLogger']->err( sprintf($VM_LANG->_('VM_BOOKING_MAX_NIGHTS'),$max_stay));
- return false;
- }
-
- if($changeover && $changeforce && ($changeover != date('N',$this->unixdateFrom)) && $this->validateCheck('CHANGEOVER')){
- $days = array(_DATE_MONDAY, _DATE_TUESDAY, _DATE_WEDNESDAY, _DATE_THURSDAY, _DATE_FRIDAY, _DATE_SATURDAY, _DATE_SUNDAY);
- if($this->display_errors) $GLOBALS['vmLogger']->err( sprintf($VM_LANG->_('VM_BOOKING_CHANGEOVER'),$days[$changeover-1]));
- return false;
- }
-
- if(!$this->property_data->allows_pets && $this->hasPets){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_PETS') );
- return false;
- }
-
- return true;
- }
-
-
- /**
- * Validation checking function, used in validate_season()
- */
- function validateCheck($perm){
-
- $perm = strtoupper($perm);
- if(isset($this->validation[$perm])) return $this->validation[$perm];
- else return false;
-
- }
-
-
- /**
- * Resets the validation data
- */
- function validationReset(){
- $this->validation = array(
- 'PEOPLE'=>1,
- 'MIN_PEOPLE'=>1,
- 'MAX_PEOPLE'=>1,
- 'MIN_NIGHTS'=>1,
- 'MAX_NIGHTS'=>1,
- 'CHANGEOVER'=>1
- );
- }
- /**
- * This function will validate that the entered dates are valid and
- * that there are no booking between the arrival or departure date *
- */
- function validateDates(){
- global $VM_LANG;
- if($this->dateFrom && $this->dateTo){
-
- if($this->unixdateFrom > $this->unixdateTo){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_DATE_ERR1') );
- return false;
- }else if($this->unixdateFrom == $this->unixdateTo){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_DATE_ERR2') );
- return false;
- }
- if(!$this->people){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_DATE_ERR3') );
- return false;
- }
-
- $order_id = vmGet($_REQUEST,'order_id');
- $db = $this->getBookingsBetweenDates($this->dateFrom, $this->dateTo, $this->property_id, $order_id);
- if($db->num_rows() > 0){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_DATE_ERR4') );
- return false;
- }
- }
- return true;
- }
-
-
- function getBookingsBetweenDates($from = '', $to = '', $property_id = '', $order_id =''){
-
- $db = new ps_DB();
-
- $from = $from ? $from : $this->dateFrom;
- $to = $to ? $to : $this->dateTo;
-
- if($from == '' || $to == '') return false;
-
- $yesterday = strtotime('-1 day');
-
- $q = "SELECT property_id FROM #__{vm}_order_booking AS booking
- LEFT JOIN #__{vm}_orders AS `order` on order.order_id = booking.order_id
- WHERE
- (
- '$from' BETWEEN `arrival` and DATE_SUB(`departure`, INTERVAL 1 DAY)
- OR
- DATE_SUB('$to', INTERVAL 1 DAY) BETWEEN `arrival` and DATE_SUB(`departure`, INTERVAL 1 DAY)
- OR
- `arrival` BETWEEN '$from' AND DATE_SUB('$to', INTERVAL 1 DAY)
- OR
- DATE_SUB(`departure`, INTERVAL 1 DAY) BETWEEN '$from' AND DATE_SUB('$to', INTERVAL 1 DAY)
- )"
- .($property_id ? " AND booking.property_id = '$property_id'" : '')
- .($order_id ? " AND order.order_id != '$order_id'" : '')
- ." AND (order.order_status = 'C' OR (order.cdate >= '$yesterday' AND order.order_status = 'P'))";
- $db->query($q);
-
- return $db;
- }
-
-
- function checkNights($from, $to, $nights, $unavailable = array()){
-
- $this->unixdateFrom = strtotime($this->dateFrom);
- $this->unixdateTo = strtotime($this->dateTo);
-
- $dateFrom = 'IF(r.season_id, s.dateFrom, r.dateFrom)';
- $dateTo = 'IF(r.season_id, s.dateTo, r.dateTo)';
- $db = new ps_DB();
- $q = "SELECT r.rate_id, r.property_id FROM #__{vm}_seasons_rates AS r
- LEFT JOIN #__{vm}_seasons AS s ON s.season_id = r.season_id
- WHERE
- (
- $dateFrom BETWEEN '$from' and DATE_SUB('$to', INTERVAL 1 DAY)
- OR
- $dateTo BETWEEN '$from' AND DATE_SUB('$to', INTERVAL 1 DAY)
- OR
- '$from' BETWEEN $dateFrom and $dateTo
- OR
- '$to' BETWEEN $dateFrom and DATE_SUB($dateTo, INTERVAL 1 DAY)
- )"
- .(count($unavailable) > 0 ? ' AND r.property_id NOT IN ('.implode(',',$unavailable).')' : '');
-
- $this->display_errors = 0;
- $this->people = 1;
-
- $arr = array();
- $db->query($q);
- $cur_prop_id = $this->property_id;
- $cur_prop_data = $this->property_data;
- while($db->next_record()){
-
- //Reset the validation rules
- $this->validationReset();
-
- //Reset property
- $this->property_id = $db->f('property_id');
- $this->property_data = null;
-
- //Reeset the discount objects
- $this->discountObject = new ps_discount($this);
-
- $valid = 1;
- for($i = 0; $i < $this->nights; $i++){
-
- //Get the current day in yyyy-mm-dd format
- $date = date('Y-m-d', ($this->unixdateFrom) + ($i * 86400));
- $this->property_id = $db->f('property_id');
- if(!$this->getNightlyPrice($date, $i)){
- $valid = 0;
- break;
- }
- }
- //Validation passed, add property to allowed list
- if($valid){
- $arr[] = $db->f('property_id');
- }
- }
-
- //Reset the property id
- $this->property_id = $cur_prop_id;
- $this->property_data = $cur_prop_data;
-
- return $arr;
- }
-
-
- /**
- * Get number of nights from x date to y date
- *
- */
- function getNights() {
-
- //Count the number of nights
- $checkdate = $this->dateFrom;
- $this->nights = 0;
- while($checkdate < $this->dateTo){
-
- $this->nights++;
-
- //Increment date
- $unixNow = strtotime($checkdate);
- $checkdate = date('Y-m-d',strtotime('+1 day',$unixNow));
- }
- return $this->nights;
- }
-
-
-
- /**
- * This function retrieves the discounts for the relevant
- * seasons and applies them to the price
- *
- */
- function getNightlyDiscounts($season_id, $season, $date, $day_no, $total){
-
- $discounts = $this->discountObject->getNightlyDiscounts($season_id, $season, $date, $day_no, $total, $this->nights, $this->dateFrom, $this->dateTo, $this);
- return $discounts;
- }
-
-
-
- /**
- * This function retrieves the total discount functions
- *
- */
- function getTotalDiscounts($total){
-
- $discounts = $this->discountObject->getTotalDiscounts($total, $this->nights, $this->dateFrom, $this->dateTo, $this);
- return $discounts;
- }
-
-
-
- /**
- * Get all extras that are in products table
- * NOT property specific at this stage - more money needed!
- *
- */
- function getExtras() {
-
- $ps_product = new ps_product();
-
- $db = new ps_DB();
- $db->query('SELECT * FROM #__{vm}_product where product_publish=\'Y\'');
-
- $prods = $db->loadObjectList('product_id');
-
- $quantities = array();
- foreach(vmget($_SESSION, 'cart', array()) as $cart){
-
- $product_id = vmget($cart,'product_id','');
- if($product_id != ''){
- $quantities[$product_id] = vmget($cart,'quantity');
- }
-
- }
- foreach($prods as &$prod){
- $prod->product_quantity = vmget($quantities,$prod->product_id,0);
- $prod->price = $ps_product->get_price($prod->product_id);
- }
- $this->extrasObjects = $prods;
-
- return $prods;
- }
-
-
-
- function setExtras($q){
- global $Itemid, $vmDisplayLogger;
-
- $ps_cart = new ps_cart();
- $extras_total = array('extras_total'=>0);
-
- if(!$q) return $extras_total;
-
- //Get the existing product quantities from the session
- $quantities = array();
- $cart = vmget($_SESSION,'cart',array());
- foreach($cart as $c){
-
- $product_id = vmget($c,'product_id','');
- if($product_id != ''){
- $quantities[$product_id] = vmget($c,'quantity');
- }
-
- }
-
- //Create a new $d array to update quantities if theyve changed
- $quantity = array();
- $prod_ids = array();
- foreach($q as $k => $v){
-
- $qty = vmget($quantities,$k,null);
- if(($qty === null && $v > 0) || ($qty !== null && $v ==0) || ($qty !== null && $v != $qty)){
- $quantity[] = $v;
- $prod_ids[] = $k;
- }
- }
-
- $d = array();
- $d['product_id'] = 1;
- $d['prod_id'] = $prod_ids;
- $d['quantity'] = $quantity;
- $d['category_id'] = '';
- $d['page'] = 'shop.cart';
- $d['func'] = 'cartAdd';
- $d['option'] = 'com_virtuemart';
- $d['Itemid'] = $Itemid;
- $d['set_price'] = array('');
- $d['adjust_price'] = array('');
- $d['master_product'] = array('');
-
- //Add products to cart
- if(count($prod_ids) > 0){
- $ps_cart->add($d);
- }
-
- //Get the extras objects
- $extras = $this->getExtras();
-
- //Save extras
- foreach(vmget($_SESSION, 'cart', array()) as $cart){
-
- $product_id = vmget($cart,'product_id','');
- $product_quantity = vmget($cart,'quantity','');
- if($product_id){
- $extra = $extras[$product_id];
- $total = $extra->price['product_price'] * $product_quantity;
- $extras_total['extras_total'] += $total;
- $extras_total[$product_id] = $extra->price;
- }
- }
- return $extras_total;
- }
-
-
- /**
- * Loads the booking data from an existing booking and populates $this;
- *
- * @param unknown_type $id
- */
- function loadBookingData($id){
- $db = new ps_DB();
-
- $db->query("SELECT * FROM #__{vm}_orders AS o
- LEFT JOIN #__{vm}_order_booking AS b ON b.order_id = o.order_id
- LEFT JOIN #__{vm}_order_history AS h ON b.order_id = h.order_id
- WHERE o.order_id=$id
- ORDER BY h.date_added DESC
- LIMIT 0, 1");
- $db->next_record();
- if(!$db->f('order_id')) return false;
-
- if(!$db->f('booking_serialized') || !$this->__unserialize($db->f('booking_serialized'))){
- //Set all the booking variables
- $this->booking_id = $db->f('order_id');
- $this->dateFrom = $db->f('arrival');
- $this->dateTo = $db->f('departure');
- $this->dateBooked = date('Y-m-d',$db->f('cdate'));
- $this->unixdateFrom = strtotime($this->dateFrom);
- $this->unixdateTo = strtotime($this->dateTo);
- $this->unixdateBooked = strtotime($this->dateBooked);
- $this->total = $db->f('total');
- $this->subtotal = $db->f('subtotal');
- $this->original = $db->f('original');
- $this->tax = $db->f('tax_total');
- $this->discount = $db->f('discounts');
- $this->adv_discount = unserialize($db->f('discount_details'));
- $this->getNights();
- }else{
- //Restore serialized booking
- $ps_booking = $this->__unserialize($db->f('booking_serialized'));
- foreach(get_class_vars(get_class($ps_booking)) as $key => $value){
- $this->$key = $ps_booking->$key;
- }
- $this->dateFrom = $db->f('arrival');
- $this->dateTo = $db->f('departure');
- $this->dateBooked = date('Y-m-d',$db->f('cdate'));
- $this->unixdateFrom = strtotime($this->dateFrom);
- $this->unixdateTo = strtotime($this->dateTo);
- $this->unixdateBooked = strtotime($this->dateBooked);
- }
- $this->booking_id = $id;
- }
-
-
- /**
- * Get the available properties between two dates
- *
- */
- function getAvailableProperties($from = '', $to = ''){
- if(!$from) $from = $this->getDate('dateFrom');
- if(!$to) $to = $this->getDate('dateTo');
- if(!$from && !$to) return false;
-
- $this->getNights();
-
- $db = $this->getBookingsBetweenDates($from, $to);
- $unavailable = array();
- if(is_object($db) && $db->num_rows()){
- while($db->next_record()){
- $unavailable[] = $db->f('property_id');
- }
- }
- $db = new ps_DB();
- $db->query("SELECT id FROM #__hp_properties ".(count($unavailable) ? "WHERE id NOT IN (".implode(',',$unavailable).")" : ''));
- $available = array();
- if(is_object($db) && $db->num_rows()){
- while($db->next_record()){
- $available[] = $db->f('id');
- }
- }
-
- $min_nights = $this->checkNights($from, $to, $this->nights, $unavailable);
- $properties = array_intersect($available, $min_nights);
- return $properties;
- }
-
-
- /**
- * Unserialize
- *
- * @param unknown_type $sObject
- * @return unknown
- */
- function __unserialize($sObject) {
- $__ret =preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $sObject );
- return unserialize($__ret);
- }
-
-
- /**
- * This function retrieves the current stage payment
- * upon the rules defined in global config
- */
-
- function getStagePayment($order_total = '', $payment_method_id = 0){
- $order_total = $order_total ? $order_total : $this->total;
-
- //INclude payments functions
- require_once(CLASSPATH.'ps_payments.php');
- $ps_payments = new ps_payments();
- $stage_payments = $ps_payments->getStagePayments($order_total, null, null, $this, $payment_method_id);
- return $stage_payments;
- }
-
-
-
- /**
- * Function to retrieve VM error messages
- *
- * @return unknown
- */
- function getMessages($html = 1, $priority = null){
-
- if($html){
- ob_start();
- $GLOBALS['vmDisplayLogger']->printLog($priority);
- $return = ob_get_contents();
- ob_end_clean();
- return $return;
- }else{
- $log = $GLOBALS['vmDisplayLogger'];
- $i = 0;
- $output = '';
- foreach( $log->_messages as $message ) {
- if( ( $priority === null || $priority <= $message['priority'] )
- && $message['priority'] !== PEAR_LOG_DEBUG
- || ( $message['priority'] === PEAR_LOG_DEBUG && DEBUG == '1')) {
-
- $output .= ucfirst($log->priorityToString($message['priority'])) . ': '
- . htmlspecialchars($message['message'])
- . "\n";
- }
- $i++;
- }
- return $output;
- }
- }
-
-
- /**
- * Set dates function, this sets the arrival and departure dates
- *
- * @return unknown
- */
- function setDates(){
- global $VM_LANG;
-
- if(!$this->getDate('dateFrom')){
- $GLOBALS['vmLogger']->err($VM_LANG->_("VM_BOOKING_DATE_ERR_ARR_EMPTY"));
- $this->status = 0;
- return false;
- }
- if(!$this->getDate('dateTo')){
- $GLOBALS['vmLogger']->err($VM_LANG->_("VM_BOOKING_DATE_ERR_DEPT_EMPTY"));
- $this->status = 0;
- return false;
- }
- return true;
- }
-
- /**
- * This function retrieves the date from the request array
- *
- * @param unknown_type $reqName
- */
-
- function getDate($reqName){
-
- if(isset($_REQUEST[$reqName])){
- $dateFromReq = $this->parseDate(vmget($_REQUEST,$reqName));
-
- //Check if empty values were passed
- if($dateFromReq === 0){
- $this->$reqName = null;
- }else if($dateFromReq !== -1){
- $this->$reqName = $dateFromReq;
- }
- }
- return isset($this->$reqName) ? $this->$reqName : false;
- }
-
- /**
- * Parses a date array from the $_REQUEST array
- * into a mysql date stamp
- *
- */
- function parseDate($arr){
- if(is_array($arr)){
- $d = vmGet($arr,'d',false);
- $m = vmGet($arr,'m',false);
- $y = vmGet($arr,'y',false);
-
- //Check if values were passed
- if(!$d || !$m || !$y){
- return 0;
- }
- //Check if date valriables are present and that they're valid
- if(!isset($arr['d']) || !isset($arr['m']) || !isset($arr['y']) || !checkdate($m, $d, $y)){
- return -1;
- }
-
- //Return a full mysql date
- return date('Y-m-d', mktime(0,0,0, $m, $d, $y));
- }else{
- if($arr){
- return $arr;
- }else{
- return 0;
- }
- }
- }
-
-
- /**
- * Check if the person booking the property is the owner
- *
- */
- function isOwner() {
- global $my;
-
- $db = new ps_DB();
-
- if($my->id){
- $owner = $this->getOwner();
- return $owner->f('user') == $my->id;
- }else{
- return 0;
- }
- }
-
-
-
- function getOwner($id = 0){
- global $my;
-
- if(!$id) $id = $this->property_id;
-
- $db = new ps_DB();
- //Check for owner booking
- $q = "SELECT a.* from #__hp_properties as p
- LEFT JOIN #__hp_agents as a ON p.agent = a.id
- WHERE p.id = $id";
-
- $db->query($q);
- return $db;
- }
-
-
- /**
- * Check if the person booking the property is an admin
- *
- */
- function isAdmin() {
- global $my;
- //return in_array($my->usertype, array(23,24,25));
- return in_array($my->usertype, array('Super Administrator','Administrator','Manager'));
- }
-
-
- /**
- * Check if the an admin chose to make the booking free
- *
- */
- function isFree() {
- global $my;
-
- $makeFree = vmget($_REQUEST,'make_free',0);
-
- if(($this->admin && $makeFree == 1) || ($this->owner && $makeFree == 1)){
- return 1;
- }else if($makeFree == -1){
- return 0;
- }else{
- return 0;
- }
- }
-
-
- /**
- * Get the property data relating to this booking
- *
- */
- function getPropertyData() {
- global $VM_LANG;
- $db = new ps_DB();
-
- # Load property data
- $q = "SELECT p.*, t.thumb, t.ordering FROM #__hp_properties as p
- LEFT JOIN #__hp_photos as t ON p.id = t.property
- WHERE p.id = $this->property_id
- ORDER BY t.ordering
- Limit 0, 1";
-
- $db->query($q);
-
- if(!$db->next_record()){
- if($this->display_errors) $GLOBALS['vmLogger']->err( $VM_LANG->_('VM_BOOKING_PROP_ERR') );
- $this->property_data = null;
- return false;
- }else{
- $this->property_data = $db->get_row();
- $this->property_data->allows_pets = $this->getPropertyField('pets');
- }
- return $this->property_data;
- }
-
-
- function getPropertyField($field){
- $db = new ps_DB();
-
- $db->query("SELECT v.value FROM #__hp_properties2 AS v
- LEFT JOIN #__hp_prop_ef AS ef ON ef.id = v.field
- WHERE ef.name = '$field' AND v.property = $this->property_id");
- $db->next_record();
- return strtolower($db->f('value')) == 'yes' ? 1 : (strtolower($db->f('value')) == 'no' ? 0 : $db->f('value'));
- }
-
-
- /**
- * Returns special offer data for a particular property
- *
- */
- function getPropertySpecial($id){
-
- if($id){
- //Store the season object in $this season var
- if(is_null($this->ps_season)) $this->ps_season = new ps_season();
- $this->property_id = $id;
-
- return $this->ps_season->getSeasonDiscount($id);
- }else{
- return false;
- }
-
- }
-
-
- /**
- * Retrieve and set the payment method if there is
- * one relating to the property
- *
- */
- function setPaymentMethod(){
-
- $db = new ps_DB();
- //Check for owner booking
- $q = "SELECT merchant_id from #__hp_payments WHERE property_id = '$this->property_id' AND enable = 1";
- $db->query($q);
-
- if($db->num_rows() > 0){
- $this->payment_id = $db->f('merchant_id');
- $_SESSION['booking']['payment'] = $this->payment_id;
- }else{
- $this->payment_id = '';
- $_SESSION['booking']['payment'] = $this->payment_id;
- }
- }
-
-
- /**
- * Retrieve booking value minus agent commission
- *
- */
- function getBookingMinusCommission($value) {
-
- if (isset($value) && defined('VB_AGENT_COMMISSION_TYPE') && defined('VB_AGENT_COMMISSION')) {
- if (VB_AGENT_COMMISSION_TYPE=='pc') { //commission is a percentage
- $value = ($value - (($value/100)*intval(VB_AGENT_COMMISSION)));
- } else { //commission is a fixed fee
- $value = ($value - intval(VB_AGENT_COMMISSION));
- }
- } else {
- $value = intval(0);
- }
- return $value > 0 ? $value : 0;
- }
- }
- ?>