Done !
| Server IP : 46.105.57.169 / Your IP : 216.73.216.67 Web Server : Apache System : Linux webm002.cluster120.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64 User : verseaumee ( 152031) PHP Version : 8.5.7 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/verseaumee/ptitsanes/libraries/solidres/roomtype/ |
Upload File : |
<?php
/**
------------------------------------------------------------------------
SOLIDRES - Accommodation booking extension for Joomla
------------------------------------------------------------------------
* @author Solidres Team <contact@solidres.com>
* @website https://www.solidres.com
* @copyright Copyright (C) 2013 - 2019 Solidres. All Rights Reserved.
* @license GNU General Public License version 3, or later
------------------------------------------------------------------------
*/
defined('_JEXEC') or die;
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/models', 'SolidresModel');
/**
* RoomType handler class
*
* @package Solidres
* @subpackage RoomType
*/
class SRRoomType
{
protected $_dbo = null;
protected static $loadedAvailableRooms = array();
public function __construct()
{
$this->_dbo = JFactory::getDbo();
}
/**
* Get list of Room is reserved and belong to a RoomType.
*
* @param int $roomTypeId
* @param int $reservationId
*
* @return array An array of room object
*/
public function getListReservedRoom($roomTypeId, $reservationId)
{
$query = $this->_dbo->getQuery(true);
$query->select('r1.id, r1.label, r2.adults_number, r2.children_number');
$query->from($this->_dbo->quoteName('#__sr_rooms') . ' r1');
$query->join('INNER', $this->_dbo->quoteName('#__sr_reservation_room_xref') . ' r2 ON r1.id = r2.room_id');
$query->where('r1.room_type_id = ' . $this->_dbo->quote($roomTypeId) . ' AND r2.reservation_id = ' . $this->_dbo->quote($reservationId));
$this->_dbo->setQuery($query);
$results = $this->_dbo->loadObjectList();
return $results;
}
/**
* Get list rooms belong to a RoomType
*
* @param int $roomtypeId
*
* @return array object
*/
public function getListRooms($roomtypeId)
{
$query = $this->_dbo->getQuery(true);
$query->clear();
$query->select('id, label, room_type_id');
$query->from($this->_dbo->quoteName('#__sr_rooms'));
$query->where('room_type_id = ' . $this->_dbo->quote($roomtypeId));
$this->_dbo->setQuery($query);
$result = $this->_dbo->loadObjectList();
if (empty($result))
{
return false;
}
return $result;
}
/**
* Method to get a list of available rooms of a RoomType based on check in and check out date
*
* @param int $roomtypeId
* @param int $checkin
* @param int $checkout
* @param int $bookingType 0 is booking per night and 1 is booking per day
* @param int $excludeId
* @param int $confirmationStatuses
*
* @return mixed An array of room object if successfully
* otherwise return false
*/
public function getListAvailableRoom($roomtypeId = 0, $checkin, $checkout, $bookingType = 0, $excludeId = 0, $confirmationStatuses = 5)
{
$srReservation = SRFactory::get('solidres.reservation.reservation');
$availableRooms = array();
$storageId = md5(implode(':', func_get_args()));
if (!isset(self::$loadedAvailableRooms[$storageId]))
{
$query = $this->_dbo->getQuery(true);
$query->select('id, label')->from($this->_dbo->quoteName('#__sr_rooms'));
if ($roomtypeId > 0)
{
$query->where('room_type_id = ' . $this->_dbo->quote($roomtypeId));
}
if (SRPlugin::isEnabled('limitbooking'))
{
$checkinMySQLFormat = "STR_TO_DATE(" . $this->_dbo->quote($checkin) . ", '%Y-%m-%d')";
$checkoutMySQLFormat = "STR_TO_DATE(" . $this->_dbo->quote($checkout) . ", '%Y-%m-%d')";
if (0 == $bookingType) // Booking per night
{
$query->where('id NOT IN (SELECT room_id FROM ' . $this->_dbo->quoteName('#__sr_limit_booking_details') . '
WHERE limit_booking_id IN (SELECT id FROM ' . $this->_dbo->quoteName('#__sr_limit_bookings') . '
WHERE
(
(' . $checkinMySQLFormat . ' <= start_date AND ' . $checkoutMySQLFormat . ' > start_date )
OR
(' . $checkinMySQLFormat . ' >= start_date AND ' . $checkoutMySQLFormat . ' <= end_date )
OR
(start_date != end_date AND ' . $checkinMySQLFormat . ' <= end_date AND ' . $checkoutMySQLFormat . ' >= end_date )
OR
(start_date = end_date AND ' . $checkinMySQLFormat . ' <= end_date AND ' . $checkoutMySQLFormat . ' > end_date )
)
AND state = 1
))');
}
else // Booking per day
{
$query->where('id NOT IN (SELECT room_id FROM ' . $this->_dbo->quoteName('#__sr_limit_booking_details') . '
WHERE limit_booking_id IN (SELECT id FROM ' . $this->_dbo->quoteName('#__sr_limit_bookings') . '
WHERE
(
(' . $checkinMySQLFormat . ' <= start_date AND ' . $checkoutMySQLFormat . ' >= start_date )
OR
(' . $checkinMySQLFormat . ' >= start_date AND ' . $checkoutMySQLFormat . ' <= end_date )
OR
(' . $checkinMySQLFormat . ' <= end_date AND ' . $checkoutMySQLFormat . ' >= end_date )
)
AND state = 1
))');
}
}
$this->_dbo->setQuery($query);
$rooms = $this->_dbo->loadObjectList();
if (empty($rooms))
{
return false;
}
foreach ($rooms as $room)
{
// If this room is available, add it to the returned list
if ($srReservation->isRoomAvailable($room->id, $checkin, $checkout, $bookingType, $excludeId, $confirmationStatuses))
{
$availableRooms[] = $room;
}
}
self::$loadedAvailableRooms[$storageId] = $availableRooms;
}
return self::$loadedAvailableRooms[$storageId];
}
/**
* Check a room to determine whether it can be deleted or not, if yes then delete it
*
* When delete a room, we will need to make sure that all related
* Reservation of that room must be removed first
*
* @param int $roomId
*
* @return boolean True if a room is safe to be deleted
* False otherwise
*/
public function canDeleteRoom($roomId = 0)
{
$query = $this->_dbo->getQuery(true);
$query->select('COUNT(*)')->from($this->_dbo->quoteName('#__sr_reservation_room_xref'))->where('room_id = ' . $this->_dbo->quote($roomId));
$this->_dbo->setQuery($query);
$result = (int) $this->_dbo->loadResult();
if ($result > 0)
{
return false;
}
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/models', 'SolidresModel');
$roomModel = JModelLegacy::getInstance('Room', 'SolidresModel', array('ignore_request' => true));
$result = $roomModel->delete($roomId);
if (!$result)
{
return false;
}
return true;
}
/**
* @param int $roomtypeId
* @param int $couponId
*
* @return bool|mixed
*/
public function storeCoupon($roomtypeId = 0, $couponId = 0)
{
if ($roomtypeId <= 0 && $couponId <= 0)
{
return false;
}
$query = $this->_dbo->getQuery(true);
$query->insert($this->_dbo->quoteName('#__sr_room_type_coupon_xref'))
->columns(array($this->_dbo->quoteName('room_type_id'), $this->_dbo->quoteName('coupon_id')))
->values((int) $roomtypeId . ',' . (int) $couponId);
$this->_dbo->setQuery($query);
return $this->_dbo->execute();
}
/**
* @param int $roomtypeId
* @param int $extraId
*
* @return bool|mixed
*/
public function storeExtra($roomtypeId = 0, $extraId = 0)
{
if ($roomtypeId <= 0 && $extraId <= 0)
{
return false;
}
$query = $this->_dbo->getQuery(true);
$query->insert($this->_dbo->quoteName('#__sr_room_type_extra_xref'))
->columns(array($this->_dbo->quoteName('room_type_id'), $this->_dbo->quoteName('extra_id')))
->values((int) $roomtypeId . ',' . (int) $extraId);
$this->_dbo->setQuery($query);
return $this->_dbo->execute();
}
/**
* Method to store Room information
*
* TODO move this function to corresponding model/table
*
* @param int $roomTypeId
* @param string $roomLabel
* @param int $roomId
*
* @return boolean
*/
public function storeRoom($roomTypeId = 0, $roomLabel = '', $roomId = null)
{
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_solidres/models', 'SolidresModel');
$roomModel = JModelLegacy::getInstance('Room', 'SolidresModel', array('ignore_request' => true));
$data = array('id' => $roomId, 'label' => $roomLabel, 'room_type_id' => $roomTypeId);
$result = $roomModel->save($data);
return $result;
}
/**
* Get list coupon id belong to $roomtypeId
*
* @param int $roomtypeId
*
* @return array
*/
public function getCoupon($roomtypeId)
{
$query = $this->_dbo->getQuery(true);
$query->select('coupon_id')->from($this->_dbo->quoteName('#__sr_room_type_coupon_xref'));
$query->where('room_type_id = ' . $this->_dbo->quote($roomtypeId));
$this->_dbo->setQuery($query);
return $this->_dbo->loadColumn();
}
/**
* Get list extra id belong to $roomtypeId
*
* @param int $roomtypeId
*
* @return array
*/
public function getExtra($roomtypeId)
{
$query = $this->_dbo->getQuery(true);
$query->select('extra_id')->from($this->_dbo->quoteName('#__sr_room_type_extra_xref'));
$query->where('room_type_id = ' . $this->_dbo->quote($roomtypeId));
$this->_dbo->setQuery($query);
return $this->_dbo->loadColumn();
}
/**
* Get price of a room type from a list of room type's tariff that matches the conditions:
* Customer group
* Checkin && Checkout date
* Adult number
* Child number & ages
* Min & Max number of nights
*
* @param int $roomTypeId
* @param $customerGroupId
* @param $imposedTaxTypes
* @param bool $defaultTariff
* @param bool $dateConstraint @deprecated
* @param string $checkin
* @param string $checkout
* @param SRCurrency $solidresCurrency The currency object
* @param array $coupon An array of coupon information
* @param int $adultNumber Number of adult, default is 0
* @param int $childNumber Number of child, default is 0
* @param array $childAges An array of children age, it is associated with the $childNumber
* @param int $stayLength 0 means ignore this condition. This variable already took booking type into account
* @param int $tariffId Search for specific tariff id
* @param array $discounts
* @param int $isDiscountPreTax
* @param array $config An array which holds extra config values for tariff calculation (since v0.9.0)
*
* @return array An array of SRCurrency for Tax and Without Tax
*/
public function getPrice($roomTypeId, $customerGroupId, $imposedTaxTypes, $defaultTariff = false, $dateConstraint = false, $checkin = '', $checkout = '', SRCurrency $solidresCurrency, $coupon = null, $adultNumber = 0, $childNumber = 0, $childAges = array(), $stayLength = 0, $tariffId = null, $discounts = array(), $isDiscountPreTax, $config = array())
{
if (SRPlugin::isEnabled('discount'))
{
JLoader::register('SRDiscount', JPATH_PLUGINS . '/solidres/discount/libraries/discount/discount.php');
}
JPluginHelper::importPlugin('solidres');
$modelTariff = JModelLegacy::getInstance('Tariff', 'SolidresModel', array('ignore_request' => true));
$funcParameters = func_get_args();
//JFactory::getApplication()->triggerEvent('onSolidresTariffBeforeCompute', array(&$funcParameters));
if (isset($tariffId))
{
if (isset($config['tariffObj']) && $config['tariffObj']->mode == 0)
{
$tariffWithDetails = $config['tariffObj'];
}
else
{
$modelTariff->setState('filter.for_calc', 1);
$tariffWithDetails = $modelTariff->getItem($tariffId);
}
// This is package type, do not need to calculate per day
if (isset($tariffWithDetails) && ($tariffWithDetails->type == 2 || $tariffWithDetails->type == 3))
{
$response = $this->getPricePackage($tariffWithDetails, $roomTypeId, $checkin, $checkout, $imposedTaxTypes, $solidresCurrency, $coupon, $adultNumber, $childAges, $stayLength, $discounts, $isDiscountPreTax, $config);
}
else // This is normal tariffs, need to calculate per day
{
$response = $this->getPriceDaily($tariffWithDetails, $roomTypeId, $checkin, $checkout, $imposedTaxTypes, $solidresCurrency, $coupon, $adultNumber, $childAges, $stayLength, $discounts, $isDiscountPreTax, $config);
}
}
else // No tariff id specified, back to old behavior of 0.6.x and before
{
$response = $this->getPriceLegacy($roomTypeId, $customerGroupId, $imposedTaxTypes, $defaultTariff, $dateConstraint, $checkin, $checkout, $solidresCurrency, $coupon, $adultNumber, $childAges, $stayLength, $discounts, $isDiscountPreTax, $config);
}
JFactory::getApplication()->triggerEvent('onSolidresTariffAfterCompute', array($funcParameters, &$response));
return $response;
}
/**
* Get price for Package tariff type: either Package per room or Package per person.
*
* @param array $tariffWithDetails
* @param int $roomTypeId
* @param string $checkin
* @param string $checkout
* @param array $imposedTaxTypes
* @param object $solidresCurrency
* @param object $coupon
* @param int $adultNumber
* @param array $childAges
* @param int $stayLength
* @param array $discounts
* @param int $isDiscountPreTax
* @param array $config An array which holds extra config values for tariff calculation (since v0.9.0)
*
* @return array
*/
public function getPricePackage($tariffWithDetails, $roomTypeId, $checkin, $checkout, $imposedTaxTypes, $solidresCurrency, $coupon = null, $adultNumber, $childAges, $stayLength = 0, $discounts, $isDiscountPreTax, $config)
{
$isAppliedCoupon = false;
$tariffBreakDown = array();
$totalBookingCost = 0;
$totalBookingCostIncludedTaxedFormatted = null;
$totalBookingCostExcludedTaxedFormatted = null;
$totalBookingCostTaxed = null;
$totalBookingCostTaxInclDiscounted = 0;
$totalBookingCostTaxExclDiscounted = 0;
$totalBookingCostIncludedTaxedDiscountedFormatted = null;
$totalBookingCostExcludedTaxedDiscountedFormatted = null;
$totalDiscount = 0;
$totalDiscountFormatted = null;
$appliedDiscounts = array();
$totalSingleSupplement = 0;
$totalSingleSupplementFormatted = null;
$totalImposedTaxAmount = 0;
$checkinDay = new DateTime($checkin);
$checkoutDay = new DateTime($checkout);
$checkinDayInfo = getdate($checkinDay->format('U'));
$checkoutDay = getdate($checkoutDay->format('U'));
$priceIncludesTax = $config['price_includes_tax'];
$isValid = self::isValid($tariffWithDetails, $checkin, $checkout, $stayLength, $checkinDayInfo);
$isCouponApplicable = false;
$srCoupon = SRFactory::get('solidres.coupon.coupon');
if (isset($coupon) && is_array($coupon))
{
$isCouponApplicable = $srCoupon->isApplicable($coupon['coupon_id'], $roomTypeId);
}
if ($isValid)
{
$cost = 0;
$costAdults = 0;
$costChildren = 0;
$singleSupplementAmount = 0;
if ($tariffWithDetails->type == PACKAGE_PER_ROOM)
{
$cost = $tariffWithDetails->details['per_room'][0]->price;
// Calculate single supplement
if ($config['enable_single_supplement'] && $adultNumber == 1)
{
$singleSupplementAmount = $config['single_supplement_value'];
if ($config['single_supplement_is_percent'])
{
$singleSupplementAmount = $cost * ($config['single_supplement_value'] / 100);
}
$cost += $singleSupplementAmount;
}
}
else if ($tariffWithDetails->type == PACKAGE_PER_PERSON)
{
for ($i = 1; $i <= $adultNumber; $i++)
{
$cost += $tariffWithDetails->details['adult' . $i][0]->price;
$costAdults += $tariffWithDetails->details['adult' . $i][0]->price;
// Calculate single supplement
if ($config['enable_single_supplement'] && $adultNumber == 1 && count($childAges) == 0)
{
$singleSupplementAmount = $config['single_supplement_value'];
if ($config['single_supplement_is_percent'])
{
$singleSupplementAmount = $cost * ($config['single_supplement_value'] / 100);
}
$cost += $singleSupplementAmount;
$costAdults += $singleSupplementAmount;
}
}
if ($config['child_room_cost_calc'] == 1) // calculate per child age range
{
for ($i = 0; $i < count($childAges); $i++)
{
foreach ($tariffWithDetails->details as $guestType => $guesTypeTariff)
{
if (substr($guestType, 0, 5) == 'adult')
{
continue; // skip all adult's tariff
}
if
(
$childAges[$i] >= $tariffWithDetails->details[$guestType][0]->from_age
&&
$childAges[$i] <= $tariffWithDetails->details[$guestType][0]->to_age
)
{
$cost += $tariffWithDetails->details[$guestType][0]->price;
$costChildren += $tariffWithDetails->details[$guestType][0]->price;
}
}
}
}
else // calculate per child quantity
{
for ($i = 0; $i < count($childAges); $i++)
{
$guestType = 'child' . ($i + 1);
if
(
$childAges[$i] >= $tariffWithDetails->details[$guestType][0]->from_age
&&
$childAges[$i] <= $tariffWithDetails->details[$guestType][0]->to_age
)
{
$cost += $tariffWithDetails->details[$guestType][0]->price;
$costChildren += $tariffWithDetails->details[$guestType][0]->price;
}
}
}
}
if ($isCouponApplicable && isset($coupon) && is_array($coupon))
{
if ($coupon['coupon_is_percent'] == 1)
{
$deductionAmount = $cost * ($coupon['coupon_amount'] / 100);
}
else
{
$deductionAmount = $coupon['coupon_amount'];
}
$cost -= $deductionAmount;
$isAppliedCoupon = true;
}
// Calculate the imposed tax amount per day
$totalImposedTaxAmountPerDay = 0;
$totalImposedTaxAmountPerDayAdults = 0;
$totalImposedTaxAmountPerDayChildren = 0;
foreach ($imposedTaxTypes as $taxType)
{
// If tax exemption is enabled, ignored this tax if condition matched
if ($taxType->tax_exempt_from > 0 && $stayLength >= $taxType->tax_exempt_from)
{
continue;
}
if ($priceIncludesTax == 0)
{
$totalImposedTaxAmountPerDay += $cost * $taxType->rate;
$totalImposedTaxAmountPerDayAdults += $costAdults * $taxType->rate;
$totalImposedTaxAmountPerDayChildren += $costChildren * $taxType->rate;
}
else
{
$totalImposedTaxAmountPerDay += $cost - ($cost / (1 + $taxType->rate));
$totalImposedTaxAmountPerDayAdults += $costAdults - ($costAdults / (1 + $taxType->rate));
$totalImposedTaxAmountPerDayChildren += $costChildren - ($costChildren / (1 + $taxType->rate));
$cost -= $totalImposedTaxAmountPerDay;
$costAdults -= $totalImposedTaxAmountPerDayAdults;
$costChildren -= $totalImposedTaxAmountPerDayChildren;
}
}
$totalBookingCost = $cost;
$tariffBreakDownTemp[8]['gross'] = $cost;
$tariffBreakDownTemp[8]['gross_adults'] = $costAdults;
$tariffBreakDownTemp[8]['gross_children'] = $costChildren;
$tariffBreakDownTemp[8]['tax'] = $totalImposedTaxAmountPerDay;
$tariffBreakDownTemp[8]['net'] = $cost + $totalImposedTaxAmountPerDay;
$tariffBreakDownTemp[8]['net_adults'] = $costAdults + $totalImposedTaxAmountPerDayAdults;
$tariffBreakDownTemp[8]['net_children'] = $costChildren + $totalImposedTaxAmountPerDayChildren;
$result = array(
'total_booking_cost' => $totalBookingCost,
'tariff_break_down' => $tariffBreakDownTemp,
'is_applied_coupon' => $isAppliedCoupon,
'single_supplement' => $singleSupplementAmount
);
$totalBookingCost = $result['total_booking_cost'];
$totalSingleSupplement += $result['single_supplement'];
$tempKeyWeekDay = key($result['tariff_break_down']);
$tempSolidresCurrencyCostPerDayGross = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGrossAdults = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGrossChildren = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayTax = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNet = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNetAdults = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNetChildren = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGross->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross']);
$tempSolidresCurrencyCostPerDayGrossAdults->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross_adults']);
$tempSolidresCurrencyCostPerDayGrossChildren->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross_children']);
$tempSolidresCurrencyCostPerDayTax->setValue($result['tariff_break_down'][$tempKeyWeekDay]['tax']);
$tempSolidresCurrencyCostPerDayNet->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net']);
$tempSolidresCurrencyCostPerDayNetAdults->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net_adults']);
$tempSolidresCurrencyCostPerDayNetChildren->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net_children']);
$tariffBreakDown[][$tempKeyWeekDay] = array(
'gross' => $tempSolidresCurrencyCostPerDayGross,
'gross_adults' => $tempSolidresCurrencyCostPerDayGrossAdults,
'gross_children' => $tempSolidresCurrencyCostPerDayGrossChildren,
'tax' => $tempSolidresCurrencyCostPerDayTax,
'net' => $tempSolidresCurrencyCostPerDayNet,
'net_adults' => $tempSolidresCurrencyCostPerDayNetAdults,
'net_children' => $tempSolidresCurrencyCostPerDayNetChildren,
'single_supplement' => $result['single_supplement']
);
$totalImposedTaxAmount += $totalImposedTaxAmountPerDay;
unset($tempSolidresCurrencyCostPerDayGross);
unset($tempSolidresCurrencyCostPerDayGrossAdults);
unset($tempSolidresCurrencyCostPerDayGrossChildren);
unset($tempSolidresCurrencyCostPerDayTax);
unset($tempSolidresCurrencyCostPerDayNet);
unset($tempSolidresCurrencyCostPerDayNetAdults);
unset($tempSolidresCurrencyCostPerDayNetChildren);
unset($tempKeyWeekDay);
if ($totalBookingCost > 0 || $config['allow_free'])
{
$totalBookingCostTaxed = $totalBookingCost + $totalImposedTaxAmount;
// Format the number with correct currency
$totalBookingCostExcludedTaxedFormatted = clone $solidresCurrency;
$totalBookingCostExcludedTaxedFormatted->setValue($totalBookingCost);
// Format the number with correct currency
$totalBookingCostIncludedTaxedFormatted = clone $solidresCurrency;
$totalBookingCostIncludedTaxedFormatted->setValue($totalBookingCostTaxed);
// Calculate discounts, need to take before and after tax into consideration
if (SRPlugin::isEnabled('discount') && count($discounts) > 0)
{
$reservationData = array(
'checkin' => $checkin,
'checkout' => $checkout,
'discount_pre_tax' => $isDiscountPreTax,
'stay_length' => $stayLength,
'scope' => 'roomtype',
'scope_id' => $roomTypeId,
'total_reserved_room' => null,
'total_price_tax_excl' => $totalBookingCost,
'total_price_tax_incl' => $totalBookingCostTaxed,
'booking_type' => $config['booking_type'],
'tariff_break_down' => $tariffBreakDown,
'number_decimal_points' => $config['number_decimal_points']
);
$solidresDiscount = new SRDiscount($discounts, $reservationData);
$solidresDiscount->calculate();
$appliedDiscounts = $solidresDiscount->appliedDiscounts;
$totalDiscount = $solidresDiscount->totalDiscount;
}
$totalBookingCostTaxInclDiscounted = $totalBookingCostTaxed - $totalDiscount;
$totalBookingCostTaxExclDiscounted = $totalBookingCost - $totalDiscount;
$totalBookingCostIncludedTaxedDiscountedFormatted = clone $solidresCurrency;
$totalBookingCostIncludedTaxedDiscountedFormatted->setValue($totalBookingCostTaxInclDiscounted);
$totalBookingCostExcludedTaxedDiscountedFormatted = clone $solidresCurrency;
$totalBookingCostExcludedTaxedDiscountedFormatted->setValue($totalBookingCostTaxExclDiscounted);
$totalDiscountFormatted = clone $solidresCurrency;
$totalDiscountFormatted->setValue($totalDiscount);
// End of discount calculation
$totalSingleSupplementFormatted = clone $solidresCurrency;
$totalSingleSupplementFormatted->setValue($totalSingleSupplement);
}
}
$response = array(
'total_price_formatted' => $totalBookingCostIncludedTaxedFormatted,
'total_price_tax_incl_formatted' => $totalBookingCostIncludedTaxedFormatted,
'total_price_tax_excl_formatted' => $totalBookingCostExcludedTaxedFormatted,
'total_price' => $totalBookingCostTaxed,
'total_price_tax_incl' => $totalBookingCostTaxed,
'total_price_tax_excl' => $totalBookingCost,
'total_price_discounted' => $totalBookingCostTaxInclDiscounted,
'total_price_tax_incl_discounted' => $totalBookingCostTaxInclDiscounted,
'total_price_tax_excl_discounted' => $totalBookingCostTaxExclDiscounted,
'total_price_discounted_formatted' => $totalBookingCostIncludedTaxedDiscountedFormatted,
'total_price_tax_incl_discounted_formatted' => $totalBookingCostIncludedTaxedDiscountedFormatted,
'total_price_tax_excl_discounted_formatted' => $totalBookingCostExcludedTaxedDiscountedFormatted,
'total_discount' => $totalDiscount,
'total_discount_formatted' => $totalDiscountFormatted,
'applied_discounts' => $appliedDiscounts,
'tariff_break_down' => $tariffBreakDown,
'is_applied_coupon' => isset($result['is_applied_coupon']) ? $result['is_applied_coupon'] : null,
'type' => isset($tariffWithDetails->type) ? $tariffWithDetails->type : null,
'id' => isset($tariffWithDetails->id) ? $tariffWithDetails->id : null,
'title' => isset($tariffWithDetails->title) ? $tariffWithDetails->title : null,
'description' => isset($tariffWithDetails->description) ? $tariffWithDetails->description : null,
'd_min' => isset($tariffWithDetails->d_min) ? $tariffWithDetails->d_min : null,
'd_max' => isset($tariffWithDetails->d_min) ? $tariffWithDetails->d_min : null,
'total_single_supplement' => $totalSingleSupplement,
'total_single_supplement_formatted' => $totalSingleSupplementFormatted,
'adjoining_layer' => isset($config['adjoining_layer']) ? $config['adjoining_layer'] : null
);
return $response;
}
/**
* Get price for Rate tariff type: either Rate per room per night or Rate per person per night
*
* @param array $tariffWithDetails
* @param int $roomTypeId
* @param string $checkin
* @param string $checkout
* @param array $imposedTaxTypes
* @param SRCurrency $solidresCurrency
* @param null $coupon
* @param int $adultNumber
* @param array $childAges
* @param int $stayLength
* @param array $discounts
* @param boolean $isDiscountPreTax
* @param array $config An array which holds extra config values for tariff calculation (since v0.9.0)
*
* @return array
*/
public function getPriceDaily($tariffWithDetails, $roomTypeId, $checkin, $checkout, $imposedTaxTypes, SRCurrency $solidresCurrency, $coupon = null, $adultNumber = 0, $childAges = array(), $stayLength = 0, $discounts, $isDiscountPreTax, $config)
{
$srCoupon = SRFactory::get('solidres.coupon.coupon');
$totalBookingCost = 0;
$totalSingleSupplement = 0;
$bookWeekDays = $this->calculateWeekDay($checkin, $checkout);
$totalImposedTaxAmount = 0;
$isCouponApplicable = false;
if (isset($coupon) && is_array($coupon))
{
$isCouponApplicable = $srCoupon->isApplicable($coupon['coupon_id'], $roomTypeId);
}
$stayCount = 1;
$tariffBreakDown = array();
$tmpKeyWeekDay = null;
// Add check for limit check in to field
$checkinDay = new DateTime($checkin);
$checkinDayInfo = getdate($checkinDay->format('U'));
$isValid = self::isValid($tariffWithDetails, $checkin, $checkout, $stayLength, $checkinDayInfo);
if ($isValid && isset($tariffWithDetails))
{
foreach ($bookWeekDays as $bookWeekDay)
{
if ($stayCount <= $stayLength)
{
$result = $this->calculateCostPerDay($tariffWithDetails, $bookWeekDay, $isCouponApplicable ? $coupon : null, $adultNumber, $childAges, $imposedTaxTypes, $config);
$totalBookingCost += $result['total_booking_cost'];
$totalSingleSupplement += $result['single_supplement'];
$tempKeyWeekDay = key($result['tariff_break_down']);
$tempSolidresCurrencyCostPerDayGross = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGrossAdults = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGrossChildren = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayTax = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNet = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNetAdults = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNetChildren = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGross->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross']);
$tempSolidresCurrencyCostPerDayGrossAdults->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross_adults']);
$tempSolidresCurrencyCostPerDayGrossChildren->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross_children']);
$tempSolidresCurrencyCostPerDayTax->setValue($result['tariff_break_down'][$tempKeyWeekDay]['tax']);
$tempSolidresCurrencyCostPerDayNet->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net']);
$tempSolidresCurrencyCostPerDayNetAdults->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net_adults']);
$tempSolidresCurrencyCostPerDayNetChildren->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net_children']);
$tariffBreakDown[][$tempKeyWeekDay] = array(
'gross' => $tempSolidresCurrencyCostPerDayGross,
'gross_adults' => $tempSolidresCurrencyCostPerDayGrossAdults,
'gross_children' => $tempSolidresCurrencyCostPerDayGrossChildren,
'tax' => $tempSolidresCurrencyCostPerDayTax,
'net' => $tempSolidresCurrencyCostPerDayNet,
'net_adults' => $tempSolidresCurrencyCostPerDayNetAdults,
'net_children' => $tempSolidresCurrencyCostPerDayNetChildren,
'single_supplement' => $result['single_supplement']
);
$totalImposedTaxAmount += $result['tariff_break_down'][$tempKeyWeekDay]['tax'];
}
$stayCount++;
}
}
unset($tempSolidresCurrencyCostPerDayGross);
unset($tempSolidresCurrencyCostPerDayTax);
unset($tempSolidresCurrencyCostPerDayNet);
unset($tempKeyWeekDay);
$totalBookingCostIncludedTaxedFormatted = null;
$totalBookingCostExcludedTaxedFormatted = null;
$totalBookingCostTaxed = null;
$totalBookingCostTaxedDiscounted = null; // Total booking cost (tax included) and discounted
$totalBookingCostIncludedTaxedDiscountedFormatted = null;
$totalBookingCostExcludedTaxedDiscountedFormatted = null;
$totalBookingCostTaxInclDiscounted = 0;
$totalBookingCostTaxExclDiscounted = 0;
$totalDiscount = 0;
$totalDiscountFormatted = null;
$appliedDiscounts = null;
$totalSingleSupplementFormatted = null;
if ($totalBookingCost > 0 || $config['allow_free'])
{
$totalBookingCostTaxed = $totalBookingCost + $totalImposedTaxAmount;
// Format the number with correct currency
$totalBookingCostExcludedTaxedFormatted = clone $solidresCurrency;
$totalBookingCostExcludedTaxedFormatted->setValue($totalBookingCost);
// Format the number with correct currency
$totalBookingCostIncludedTaxedFormatted = clone $solidresCurrency;
$totalBookingCostIncludedTaxedFormatted->setValue($totalBookingCostTaxed);
// Calculate discounts, need to take before and after tax into consideration
$appliedDiscounts = array();
$totalDiscount = 0;
if (SRPlugin::isEnabled('discount') && count($discounts) > 0)
{
$reservationData = array(
'checkin' => $checkin,
'checkout' => $checkout,
'discount_pre_tax' => $isDiscountPreTax,
'stay_length' => $stayLength,
'scope' => 'roomtype',
'scope_id' => $roomTypeId,
'total_reserved_room' => null,
'total_price_tax_excl' => $totalBookingCost,
'total_price_tax_incl' => $totalBookingCostTaxed,
'booking_type' => $config['booking_type'],
'tariff_break_down' => $tariffBreakDown,
'number_decimal_points' => $config['number_decimal_points']
);
$solidresDiscount = new SRDiscount($discounts, $reservationData);
$solidresDiscount->calculate();
$appliedDiscounts = $solidresDiscount->appliedDiscounts;
$totalDiscount = $solidresDiscount->totalDiscount;
}
// Recalculate tax amount if option Discount pre tax is enabled
if ($isDiscountPreTax && $totalDiscount > 0)
{
$tmpTotalBookingCost = $totalBookingCost - $totalDiscount;
$totalImposedTaxAmount = 0;
foreach ($imposedTaxTypes as $taxType)
{
// If tax exemption is enabled, ignored this tax if condition matched
if ($taxType->tax_exempt_from > 0 && $config['stay_length'] >= $taxType->tax_exempt_from)
{
continue;
}
if (0 == $config['price_includes_tax'])
{
$totalImposedTaxAmount += $tmpTotalBookingCost * $taxType->rate;
}
else
{
$totalImposedTaxAmount += $tmpTotalBookingCost - ($tmpTotalBookingCost / (1 + $taxType->rate));
}
}
$totalBookingCostTaxed = $tmpTotalBookingCost + $totalImposedTaxAmount;
$totalBookingCostTaxInclDiscounted = $totalBookingCostTaxed;
$totalBookingCostTaxExclDiscounted = $totalBookingCost - $totalDiscount;
}
else
{
$totalBookingCostTaxInclDiscounted = $totalBookingCostTaxed - $totalDiscount;
$totalBookingCostTaxExclDiscounted = $totalBookingCost - $totalDiscount;
}
$totalBookingCostIncludedTaxedDiscountedFormatted = clone $solidresCurrency;
$totalBookingCostIncludedTaxedDiscountedFormatted->setValue($totalBookingCostTaxInclDiscounted);
$totalBookingCostExcludedTaxedDiscountedFormatted = clone $solidresCurrency;
$totalBookingCostExcludedTaxedDiscountedFormatted->setValue($totalBookingCostTaxExclDiscounted);
$totalDiscountFormatted = clone $solidresCurrency;
$totalDiscountFormatted->setValue($totalDiscount);
// End of discount calculation
$totalSingleSupplementFormatted = clone $solidresCurrency;
$totalSingleSupplementFormatted->setValue($totalSingleSupplement);
}
$response = array(
'total_price_formatted' => $totalBookingCostIncludedTaxedFormatted,
'total_price_tax_incl_formatted' => $totalBookingCostIncludedTaxedFormatted,
'total_price_tax_excl_formatted' => $totalBookingCostExcludedTaxedFormatted,
'total_price' => $totalBookingCostTaxed,
'total_price_tax_incl' => $totalBookingCostTaxed,
'total_price_tax_excl' => $totalBookingCost,
'total_price_discounted' => $totalBookingCostTaxInclDiscounted,
'total_price_tax_incl_discounted' => $totalBookingCostTaxInclDiscounted,
'total_price_tax_excl_discounted' => $totalBookingCostTaxExclDiscounted,
'total_price_discounted_formatted' => $totalBookingCostIncludedTaxedDiscountedFormatted,
'total_price_tax_incl_discounted_formatted' => $totalBookingCostIncludedTaxedDiscountedFormatted,
'total_price_tax_excl_discounted_formatted' => $totalBookingCostExcludedTaxedDiscountedFormatted,
'total_discount' => $totalDiscount,
'total_discount_formatted' => $totalDiscountFormatted,
'applied_discounts' => $appliedDiscounts,
'tariff_break_down' => $tariffBreakDown,
'is_applied_coupon' => isset($result['is_applied_coupon']) ? $result['is_applied_coupon'] : false,
'type' => isset($tariffWithDetails->type) ? $tariffWithDetails->type : null,
'id' => isset($tariffWithDetails->id) ? $tariffWithDetails->id : null,
'title' => isset($tariffWithDetails->title) ? $tariffWithDetails->title : null,
'description' => isset($tariffWithDetails->description) ? $tariffWithDetails->description : null,
'd_min' => isset($tariffWithDetails->d_min) ? $tariffWithDetails->d_min : null,
'd_max' => isset($tariffWithDetails->d_min) ? $tariffWithDetails->d_min : null,
'total_single_supplement' => $totalSingleSupplement,
'total_single_supplement_formatted' => $totalSingleSupplementFormatted,
'adjoining_layer' => isset($config['adjoining_layer']) ? $config['adjoining_layer'] : null
);
return $response;
}
/**
* Get price of a room type from a list of room type's tariff that matches the conditions:
* Customer group
* Checkin && Checkout date
* Adult number
* Child number & ages
* Min & Max number of nights
*
* @param int $roomTypeId
* @param $customerGroupId
* @param $imposedTaxTypes
* @param bool $defaultTariff
* @param bool $dateConstraint @deprecated
* @param string $checkin
* @param string $checkout
* @param SRCurrency $solidresCurrency The currency object
* @param array $coupon An array of coupon information
* @param int $adultNumber Number of adult, default is 0
* @param array $childAges An array of children age, it is associated with the $childNumber
* @param int $stayLength 0 means ignore this condition
* @param array $discounts
* @param int $isDiscountPreTax
* @param array $config An array which holds extra config values for tariff calculation (since v0.9.0)
*
* @return array An array of SRCurrency for Tax and Without Tax
*/
public function getPriceLegacy($roomTypeId, $customerGroupId, $imposedTaxTypes, $defaultTariff = false, $dateConstraint = false, $checkin = '', $checkout = '', SRCurrency $solidresCurrency, $coupon = null, $adultNumber = 0, $childAges = array(), $stayLength = 0, $discounts, $isDiscountPreTax, $config)
{
$modelTariffs = JModelLegacy::getInstance('Tariffs', 'SolidresModel', array('ignore_request' => true));
$modelTariff = JModelLegacy::getInstance('Tariff', 'SolidresModel', array('ignore_request' => true));
$srCoupon = SRFactory::get('solidres.coupon.coupon');
$totalBookingCost = 0;
$totalSingleSupplement = 0;
$totalImposedTaxAmount = 0;
$modelTariffs->setState('filter.room_type_id', $roomTypeId);
$modelTariffs->setState('filter.customer_group_id', $customerGroupId);
$modelTariffs->setState('filter.state', 1);
if ($defaultTariff)
{
$modelTariffs->setState('filter.default_tariff', 1);
// If we need to get the default price, set customer group to -1, means we do not care about customer group
$modelTariffs->setState('filter.customer_group_id', -1);
}
$bookWeekDays = $this->calculateWeekDay($checkin, $checkout);
if ($dateConstraint)
{
$modelTariffs->setState('filter.date_constraint', 1);
}
$modelTariffs->setState('filter.partial_match', 1);
$modelTariffs->setState('filter.checkin', $checkin);
$modelTariffs->setState('filter.checkout', $checkout);
$isCouponApplicable = false;
if (isset($coupon) && is_array($coupon))
{
$isCouponApplicable = $srCoupon->isApplicable($coupon['coupon_id'], $roomTypeId);
}
// Special check for limit check in to, check checkin date with the first tariff we found.
$isValid = true;
if ($dateConstraint)
{
// Reset these state because we may override it in other steps
$modelTariffs->setState('filter.date_constraint', 1);
$modelTariffs->setState('filter.default_tariff', null);
$modelTariffs->setState('filter.customer_group_id', $customerGroupId);
$modelTariffs->setState('filter.bookday', JFactory::getDate($bookWeekDays[0])->toSql());
$tariff1 = $modelTariffs->getItems();
if (isset($tariff1[0]))
{
if (!is_null($tariff1[0]->limit_checkin))
{
$theDay1 = new DateTime($bookWeekDays[0]);
$dayInfo1 = getdate($theDay1->format('U'));
$limitCheckInToArray = json_decode($tariff1[0]->limit_checkin);
if (!in_array($dayInfo1['wday'], $limitCheckInToArray))
{
$isValid = false;
}
}
}
}
// End special check
$stayCount = 1;
$tariffBreakDown = array();
$tempTariffId = 0;
$tmpKeyWeekDay = null;
$stayLengthLimitArray = array();
if ($isValid)
{
foreach ($bookWeekDays as $bookWeekDay)
{
if ($stayCount <= $stayLength)
{
// Find Complex Tariff
if ($dateConstraint)
{
// Reset these state because we may override it in other steps
$modelTariffs->setState('filter.date_constraint', 1);
$modelTariffs->setState('filter.default_tariff', null);
$modelTariffs->setState('filter.customer_group_id', $customerGroupId);
$modelTariffs->setState('filter.bookday', JFactory::getDate($bookWeekDay)->toSql());
$tariff = $modelTariffs->getItems();
}
else // Or find Standard Tariff
{
$modelTariffs->setState('filter.date_constraint', null);
$modelTariffs->setState('filter.default_tariff', 1);
$modelTariffs->setState('filter.customer_group_id', -1);
$tariff = $modelTariffs->getItems();
}
$result = array(
'total_booking_cost' => 0,
'tariff_break_down' => array(),
'is_applied_coupon' => false
);
if (!empty($tariff))
{
$stayLengthLimitArray[$tariff[$config['adjoining_layer']]->id] = $tariff[$config['adjoining_layer']]->d_min;
// Then we load the tariff details: price for each week day
// Caching stuff
if ($tempTariffId != $tariff[$config['adjoining_layer']]->id)
{
$modelTariff->setState('filter.for_calc', 1);
$tariffWithDetails = $modelTariff->getItem($tariff[$config['adjoining_layer']]->id);
$tempTariffId = $tariff[$config['adjoining_layer']]->id;
}
$result = $this->calculateCostPerDay($tariffWithDetails, $bookWeekDay, $isCouponApplicable ? $coupon : null, $adultNumber, $childAges, $imposedTaxTypes, $config);
$totalBookingCost += $result['total_booking_cost'];
$totalSingleSupplement += $result['single_supplement'];
$tempKeyWeekDay = key($result['tariff_break_down']);
$tempSolidresCurrencyCostPerDayGross = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGrossAdults = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGrossChildren = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayTax = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNet = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNetAdults = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayNetChildren = clone $solidresCurrency;
$tempSolidresCurrencyCostPerDayGross->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross']);
$tempSolidresCurrencyCostPerDayGrossAdults->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross_adults']);
$tempSolidresCurrencyCostPerDayGrossChildren->setValue($result['tariff_break_down'][$tempKeyWeekDay]['gross_children']);
$tempSolidresCurrencyCostPerDayTax->setValue($result['tariff_break_down'][$tempKeyWeekDay]['tax']);
$tempSolidresCurrencyCostPerDayNet->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net']);
$tempSolidresCurrencyCostPerDayNetAdults->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net_adults']);
$tempSolidresCurrencyCostPerDayNetChildren->setValue($result['tariff_break_down'][$tempKeyWeekDay]['net_children']);
$tariffBreakDown[][$tempKeyWeekDay] = array(
'gross' => $tempSolidresCurrencyCostPerDayGross,
'gross_adults' => $tempSolidresCurrencyCostPerDayGrossAdults,
'gross_children' => $tempSolidresCurrencyCostPerDayGrossChildren,
'tax' => $tempSolidresCurrencyCostPerDayTax,
'net' => $tempSolidresCurrencyCostPerDayNet,
'net_adults' => $tempSolidresCurrencyCostPerDayNetAdults,
'net_children' => $tempSolidresCurrencyCostPerDayNetChildren,
'single_supplement' => $result['single_supplement']
);
$totalImposedTaxAmount += $result['tariff_break_down'][$tempKeyWeekDay]['tax'];
}
}
$stayCount++;
}
}
unset($tempSolidresCurrencyCostPerDayGross);
unset($tempSolidresCurrencyCostPerDayTax);
unset($tempSolidresCurrencyCostPerDayNet);
unset($tempKeyWeekDay);
$totalBookingCostIncludedTaxedFormatted = null;
$totalBookingCostExcludedTaxedFormatted = null;
$totalBookingCostTaxed = null;
$totalBookingCostTaxInclDiscounted = 0;
$totalBookingCostTaxExclDiscounted = 0;
$totalBookingCostIncludedTaxedDiscountedFormatted = null;
$totalBookingCostExcludedTaxedDiscountedFormatted = null;
$totalDiscount = 0;
$totalDiscountFormatted = null;
$appliedDiscounts = null;
$totalSingleSupplementFormatted = null;
$isBookingPermitted = false;
$stayLengthLimitArray = array_values($stayLengthLimitArray);
//sort($stayLengthLimitArray);
switch ($config['adjoining_tariffs_mode'])
{
case 0:
$isBookingPermitted = true;
break;
case 1: // Lowest - Use lowest min stay length of any adjoining tariffs
if ($stayLength >= min($stayLengthLimitArray))
{
$isBookingPermitted = true;
}
break;
case 2: // Highest - Use highest min stay length of any adjoining tariffs
if ($stayLength >= max($stayLengthLimitArray))
{
$isBookingPermitted = true;
}
break;
}
if (($totalBookingCost > 0 || $config['allow_free']) && $isBookingPermitted)
{
$totalBookingCostTaxed = $totalBookingCost + $totalImposedTaxAmount;
// Format the number with correct currency
$totalBookingCostExcludedTaxedFormatted = clone $solidresCurrency;
$totalBookingCostExcludedTaxedFormatted->setValue($totalBookingCost);
// Format the number with correct currency
$totalBookingCostIncludedTaxedFormatted = clone $solidresCurrency;
$totalBookingCostIncludedTaxedFormatted->setValue($totalBookingCostTaxed);
// Calculate discounts, need to take before and after tax into consideration
$appliedDiscounts = array();
$totalDiscount = 0;
if (SRPlugin::isEnabled('discount') && count($discounts) > 0)
{
$reservationData = array(
'checkin' => $checkin,
'checkout' => $checkout,
'discount_pre_tax' => $isDiscountPreTax,
'stay_length' => $stayLength,
'scope' => 'roomtype',
'scope_id' => $roomTypeId,
'total_reserved_room' => null,
'total_price_tax_excl' => $totalBookingCost,
'total_price_tax_incl' => $totalBookingCostTaxed,
'booking_type' => $config['booking_type'],
'tariff_break_down' => $tariffBreakDown,
'number_decimal_points' => $config['number_decimal_points']
);
$solidresDiscount = new SRDiscount($discounts, $reservationData);
$solidresDiscount->calculate();
$appliedDiscounts = $solidresDiscount->appliedDiscounts;
$totalDiscount = $solidresDiscount->totalDiscount;
}
$totalBookingCostTaxInclDiscounted = $totalBookingCostTaxed - $totalDiscount;
$totalBookingCostTaxExclDiscounted = $totalBookingCost - $totalDiscount;
$totalBookingCostIncludedTaxedDiscountedFormatted = clone $solidresCurrency;
$totalBookingCostIncludedTaxedDiscountedFormatted->setValue($totalBookingCostTaxInclDiscounted);
$totalBookingCostExcludedTaxedDiscountedFormatted = clone $solidresCurrency;
$totalBookingCostExcludedTaxedDiscountedFormatted->setValue($totalBookingCostTaxExclDiscounted);
$totalDiscountFormatted = clone $solidresCurrency;
$totalDiscountFormatted->setValue($totalDiscount);
// End of discount calculation
$totalSingleSupplementFormatted = clone $solidresCurrency;
$totalSingleSupplementFormatted->setValue($totalSingleSupplement);
}
$joinedDescription = '';
if (!isset($config['adjoining_tariffs_show_desc']))
{
$config['adjoining_tariffs_show_desc'] = 0;
}
if ($config['adjoining_tariffs_show_desc'])
{
$joinedDescription = implode(' ', array_filter(array($tariff1[$config['adjoining_layer']]->description, $tariff[$config['adjoining_layer']]->description)));
}
$response = array(
'total_price_formatted' => $totalBookingCostIncludedTaxedFormatted,
'total_price_tax_incl_formatted' => $totalBookingCostIncludedTaxedFormatted,
'total_price_tax_excl_formatted' => $totalBookingCostExcludedTaxedFormatted,
'total_price' => $totalBookingCostTaxed,
'total_price_tax_incl' => $totalBookingCostTaxed,
'total_price_tax_excl' => $totalBookingCost,
'total_price_discounted' => $totalBookingCostTaxInclDiscounted,
'total_price_tax_incl_discounted' => $totalBookingCostTaxInclDiscounted,
'total_price_tax_excl_discounted' => $totalBookingCostTaxExclDiscounted,
'total_price_discounted_formatted' => $totalBookingCostIncludedTaxedDiscountedFormatted,
'total_price_tax_incl_discounted_formatted' => $totalBookingCostIncludedTaxedDiscountedFormatted,
'total_price_tax_excl_discounted_formatted' => $totalBookingCostExcludedTaxedDiscountedFormatted,
'total_discount' => $totalDiscount,
'total_discount_formatted' => $totalDiscountFormatted,
'applied_discounts' => $appliedDiscounts,
'tariff_break_down' => $tariffBreakDown,
'is_applied_coupon' => isset($result['is_applied_coupon']) ? $result['is_applied_coupon'] : false,
'type' => isset($tariff[0]->type) ? $tariff[0]->type : null,
'id' => 0 - $config['adjoining_layer'], // special id for joined tariffs case
'title' => null,
'description' => $joinedDescription,
'd_min' => isset($tariffWithDetails->d_min) ? $tariffWithDetails->d_min : null,
'd_max' => isset($tariffWithDetails->d_min) ? $tariffWithDetails->d_min : null,
'total_single_supplement' => $totalSingleSupplement,
'total_single_supplement_formatted' => $totalSingleSupplementFormatted,
'adjoining_layer' => $config['adjoining_layer']
);
return $response;
}
/**
* Get an array of week days in the period between $from and $to
*
* @param string From date
* @param string To date
*
* @return array An array in format array(0 => 'Y-m-d', 1 => 'Y-m-d')
*
* @deprecated 1.0.0 Use SRUtilities instead
*/
private function calculateWeekDay($from, $to)
{
JLoader::register('SRUtilities', SRPATH_LIBRARY . '/utilities/utilities.php');
return SRUtilities::calculateWeekDay($from, $to);
}
/**
* Calculate the number of day from a given range
*
* Note: DateTime is PHP 5.3 only
*
* @param string $from Begin of date range
* @param string $to End of date range
* @param string $format The format indicator
*
* @return string
*
* @deprecated 1.0.0 Use SRUtilities instead
*/
public function calculateDateDiff($from, $to, $format = '%a')
{
JLoader::register('SRUtilities', SRPATH_LIBRARY . '/utilities/utilities.php');
return SRUtilities::calculateDateDiff($from, $to, $format = '%a');
}
/**
* Calculate booking cost per day and apply the coupon if possible
*
* @param array $tariff An array of tariffs for searching
* @param array $bookWeekDay The date that we need to find tariff for it from above $tariff
* @param array $coupon An array of coupon information
* @param int $adultNumber Number of adult, only used for tariff Per person per room
* @param array $childAges Children ages, it is associated with $childNumber
* @param array $imposedTaxTypes All imposed tax types
* @param array $config An array holds a list of tariff config
*
* @return array
*/
private function calculateCostPerDay($tariff, $bookWeekDay, $coupon = null, $adultNumber, $childAges, $imposedTaxTypes, $config)
{
$totalBookingCost = 0;
$tariffBreakDown = array();
$costPerDay = 0;
$costPerDayAdults = 0;
$costPerDayChildren = 0;
$isAppliedCoupon = false;
$deductionAmount = 0;
$singleSupplementAmount = 0;
$priceIncludesTax = $config['price_includes_tax'];
$stayLength = $config['stay_length'];
$numberDecimalPoints = isset($config['number_decimal_points']) ? $config['number_decimal_points'] : 2;
$theDay = new DateTime($bookWeekDay);
$dayInfo = getdate($theDay->format('U'));
if ($tariff->type == PER_ROOM_PER_NIGHT || $tariff->type == PER_ROOM_TYPE_PER_STAY)
{
if ($tariff->mode == 0)
{
for ($i = 0, $count = count($tariff->details['per_room']); $i < $count; $i++)
{
if ($tariff->details['per_room'][$i]->w_day == $dayInfo['wday'])
{
$costPerDay = $tariff->details['per_room'][$i]->price;
// Calculate single supplement
if ($config['enable_single_supplement'] && $adultNumber == 1 && count($childAges) == 0)
{
$singleSupplementAmount = $config['single_supplement_value'];
if ($config['single_supplement_is_percent'])
{
$singleSupplementAmount = $costPerDay * ($config['single_supplement_value'] / 100);
}
$costPerDay += $singleSupplementAmount;
}
break; // we found the tariff we need, get out of here
}
}
}
else
{
$costPerDay = $tariff->details['per_room'][$bookWeekDay]->price;
// Calculate single supplement
if ($config['enable_single_supplement'] && $adultNumber == 1 && count($childAges) == 0)
{
$singleSupplementAmount = $config['single_supplement_value'];
if ($config['single_supplement_is_percent'])
{
$singleSupplementAmount = $costPerDay * ($config['single_supplement_value'] / 100);
}
$costPerDay += $singleSupplementAmount;
}
}
}
else if ($tariff->type == PER_PERSON_PER_NIGHT)
{
// Calculate cost per day for each adult
for ($i = 1; $i <= $adultNumber; $i++)
{
$adultIndex = 'adult' . $i;
if ($tariff->mode == 0 && isset($tariff->details[$adultIndex]))
{
for ($t = 0, $count = count($tariff->details[$adultIndex]); $t < $count; $t++)
{
if ($tariff->details[$adultIndex][$t]->w_day == $dayInfo['wday'])
{
$costPerDay += $tariff->details[$adultIndex][$t]->price;
$costPerDayAdults += $tariff->details[$adultIndex][$t]->price;
// Calculate single supplement
if ($config['enable_single_supplement'] && $adultNumber == 1 && count($childAges) == 0)
{
$singleSupplementAmount = $config['single_supplement_value'];
if ($config['single_supplement_is_percent'])
{
$singleSupplementAmount = $costPerDay * ($config['single_supplement_value'] / 100);
}
$costPerDay += $singleSupplementAmount;
$costPerDayAdults += $singleSupplementAmount;
}
break; // we found the tariff we need, get out of here
}
}
}
else
{
$costPerDay += $tariff->details[$adultIndex][$bookWeekDay]->price;
$costPerDayAdults += $tariff->details[$adultIndex][$bookWeekDay]->price;
// Calculate single supplement
if ($config['enable_single_supplement'] && $adultNumber == 1 && count($childAges) == 0)
{
$singleSupplementAmount = $config['single_supplement_value'];
if ($config['single_supplement_is_percent'])
{
$singleSupplementAmount = $costPerDay * ($config['single_supplement_value'] / 100);
}
$costPerDay += $singleSupplementAmount;
$costPerDayAdults += $singleSupplementAmount;
}
}
}
switch ($config['child_room_cost_calc'])
{
case 0: // Quantity
for ($i = 0; $i < count($childAges); $i++)
{
$guestType = 'child' . ($i + 1);
if ($tariff->mode == 0)
{
for ($t = 0, $count = count($tariff->details[$guestType]); $t < $count; $t++)
{
if ($tariff->details[$guestType][$t]->w_day == $dayInfo['wday'])
{
$costPerDay += $tariff->details[$guestType][$t]->price;
$costPerDayChildren += $tariff->details[$guestType][$t]->price;
break; // found it, get out of here
}
}
}
else
{
if ($tariff->details[$guestType][$bookWeekDay]->price)
{
$costPerDay += $tariff->details[$guestType][$bookWeekDay]->price;
$costPerDayChildren += $tariff->details[$guestType][$bookWeekDay]->price;
}
}
}
break;
case 1: // Age range
for ($i = 0; $i < count($childAges); $i++)
{
foreach ($tariff->details as $guestType => $guesTypeTariff)
{
if (substr($guestType, 0, 5) == 'adult')
{
continue; // skip all adult's tariff
}
if ($tariff->mode == 0)
{
for ($t = 0, $count = count($tariff->details[$guestType]); $t < $count; $t++)
{
if
(
$tariff->details[$guestType][$t]->w_day == $dayInfo['wday']
&&
($childAges[$i] >= $tariff->details[$guestType][$t]->from_age && $childAges[$i] <= $tariff->details[$guestType][$t]->to_age)
)
{
$costPerDay += $tariff->details[$guestType][$t]->price;
$costPerDayChildren += $tariff->details[$guestType][$t]->price;
break; // found it, get out of here
}
}
}
else
{
if
(
isset($tariff->details[$guestType][$bookWeekDay]->price)
&&
($childAges[$i] >= $tariff->details[$guestType][$bookWeekDay]->from_age && $childAges[$i] <= $tariff->details[$guestType][$bookWeekDay]->to_age)
)
{
$costPerDay += $tariff->details[$guestType][$bookWeekDay]->price;
$costPerDayChildren += $tariff->details[$guestType][$bookWeekDay]->price;
}
}
}
}
break;
case 2: // Mixed
// Rearrange things a little bit for easier calculation
$newTariffDetails = null;
$foundAgeRanges = [];
$childAgeGroups = [];
foreach ($tariff->details as $guestType => $guesTypeTariff)
{
if (substr($guestType, 0, 5) == 'adult')
{
continue; // skip all adult's tariff
}
$ageRangeFrom = '';
$ageRangeTo = '';
if (is_array($tariff->details[$guestType]))
{
$k = array_keys($tariff->details[$guestType])[0];
$ageRangeFrom = $tariff->details[$guestType][$k]->from_age;
$ageRangeTo = $tariff->details[$guestType][$k]->to_age;
}
$ageRangeFromTo = $ageRangeFrom . '_' . $ageRangeTo;
if (!in_array($ageRangeFromTo, $foundAgeRanges))
{
$foundAgeRanges[] = $ageRangeFromTo;
}
$newTariffDetails[$ageRangeFromTo][] = $tariff->details[$guestType];
}
// Regrouping child ages
for ($i = 0; $i < count($childAges); $i++)
{
$age = $childAges[$i];
foreach ($foundAgeRanges as $foundAgeRange)
{
$ageRangeArray = explode('_', $foundAgeRange);
if ($age < $ageRangeArray[0] || $age > $ageRangeArray[1])
{
continue;
}
$childAgeGroups[$foundAgeRange][$i] = $age;
}
}
foreach ($childAgeGroups as $childAgeGroup)
{
foreach ($childAgeGroup as $childIndex => $childAge)
{
$childAge = $childAgeGroup[$childIndex];
foreach ($newTariffDetails as $ageRange => $newDetails)
{
$ageRangeArray = explode('_', $ageRange);
if ($childAge < $ageRangeArray[0] || $childAge > $ageRangeArray[1])
{
continue;
}
$guestType = $childIndex; // We only need the index number in this mode
if ($tariff->mode == 0)
{
for ($t = 0, $count = count($newDetails[$guestType]); $t < $count; $t++)
{
if ($newDetails[$guestType][$t]->w_day == $dayInfo['wday'])
{
$costPerDay += $newDetails[$guestType][$t]->price;
$costPerDayChildren += $newDetails[$guestType][$t]->price;
break 2; // found it, get out of here
}
}
}
else
{
if ($newDetails[$guestType][$bookWeekDay]->price)
{
$costPerDay += $newDetails[$guestType][$bookWeekDay]->price;
$costPerDayChildren += $newDetails[$guestType][$bookWeekDay]->price;
}
}
}
}
}
break;
}
}
if (isset($coupon) && is_array($coupon))
{
if ($coupon['coupon_is_percent'] == 1)
{
$deductionAmount = $costPerDay * ($coupon['coupon_amount'] / 100);
}
else
{
$deductionAmount = $coupon['coupon_amount'];
}
$costPerDay -= $deductionAmount;
$isAppliedCoupon = true;
}
// Calculate the imposed tax amount per day
$totalImposedTaxAmountPerDay = 0;
$totalImposedTaxAmountPerDayAdults = 0;
$totalImposedTaxAmountPerDayChildren = 0;
foreach ($imposedTaxTypes as $taxType)
{
// If tax exemption is enabled, ignored this tax if condition matched
if ($taxType->tax_exempt_from > 0 && $stayLength >= $taxType->tax_exempt_from)
{
continue;
}
if ($priceIncludesTax == 0)
{
$totalImposedTaxAmountPerDay += $costPerDay * $taxType->rate;
$totalImposedTaxAmountPerDayAdults += $costPerDayAdults * $taxType->rate;
$totalImposedTaxAmountPerDayChildren += $costPerDayChildren * $taxType->rate;
}
else
{
$totalImposedTaxAmountPerDay += $costPerDay - ($costPerDay / (1 + $taxType->rate));
$totalImposedTaxAmountPerDayAdults += $costPerDayAdults - ($costPerDayAdults / (1 + $taxType->rate));
$totalImposedTaxAmountPerDayChildren += $costPerDayChildren - ($costPerDayChildren / (1 + $taxType->rate));
$costPerDay -= $totalImposedTaxAmountPerDay;
$costPerDayAdults -= $totalImposedTaxAmountPerDayAdults;
$costPerDayChildren -= $totalImposedTaxAmountPerDayChildren;
}
}
$totalBookingCost += $costPerDay;
$tariffBreakDown[$dayInfo['wday']]['gross'] = $costPerDay;
$tariffBreakDown[$dayInfo['wday']]['gross_adults'] = $costPerDayAdults;
$tariffBreakDown[$dayInfo['wday']]['gross_children'] = $costPerDayChildren;
$tariffBreakDown[$dayInfo['wday']]['deduction'] = $deductionAmount;
$tariffBreakDown[$dayInfo['wday']]['tax'] = $totalImposedTaxAmountPerDay;
$tariffBreakDown[$dayInfo['wday']]['net'] = $costPerDay + $totalImposedTaxAmountPerDay;
$tariffBreakDown[$dayInfo['wday']]['net_adults'] = $costPerDayAdults + $totalImposedTaxAmountPerDayAdults;
$tariffBreakDown[$dayInfo['wday']]['net_children'] = $costPerDayChildren + $totalImposedTaxAmountPerDayChildren;
$tariffBreakDown[$dayInfo['wday']]['single_supplement'] = $singleSupplementAmount;
return array(
'total_booking_cost' => $totalBookingCost,
'total_booking_cost_adults' => $costPerDayAdults,
'total_booking_cost_children' => $costPerDayChildren,
'tariff_break_down' => $tariffBreakDown,
'is_applied_coupon' => $isAppliedCoupon,
'single_supplement' => $singleSupplementAmount
);
}
/**
* Check to see if the general checkin/out match this tariff's valid from and valid to
* We also have to check if the checkin match the allowed checkin days (except standard tariff).
* We also have to check if the general nights number match this tariff's min nights and max nights
*
*
* @param $tariffWithDetails
* @param $checkin
* @param $checkout
* @param $stayLength
* @param $checkinDayInfo
*
* @return bool
*
*/
private function isValid($tariffWithDetails, $checkin, $checkout, $stayLength, $checkinDayInfo)
{
$isValid = false;
// We have different conditions for standard tariff and complex tariff
if ($tariffWithDetails->valid_from == '00-00-0000' && $tariffWithDetails->valid_to == '00-00-0000')
{
$isValid = true;
}
else
{
$isValidDayRange = true;
// First case: this tariff has value for d_min and d_max
if ($tariffWithDetails->d_min > 0 && $tariffWithDetails->d_max > 0)
{
$isValidDayRange = $stayLength >= $tariffWithDetails->d_min && $stayLength <= $tariffWithDetails->d_max;
}
elseif (empty($tariffWithDetails->d_min) && $tariffWithDetails->d_max > 0)
{
$isValidDayRange = $stayLength <= $tariffWithDetails->d_max;
}
elseif ($tariffWithDetails->d_min > 0 && empty($tariffWithDetails->d_max))
{
$isValidDayRange = $stayLength >= $tariffWithDetails->d_min;
}
if (
strtotime($tariffWithDetails->valid_from) <= strtotime($checkin) &&
strtotime($tariffWithDetails->valid_to) >= strtotime($checkout) &&
(in_array($checkinDayInfo['wday'], $tariffWithDetails->limit_checkin)) &&
$isValidDayRange
)
{
$isValid = true;
}
}
return $isValid;
}
/**
* Retrieve booking type from room type id
*
* @param $roomTypeId
*
* @return mixed
*
*/
public function getBookingType($roomTypeId)
{
$query = $this->_dbo->getQuery(true);
$query->select('booking_type')->from($this->_dbo->quoteName('#__sr_reservation_assets'));
$query->where('id = (SELECT reservation_asset_id FROM ' . $this->_dbo->quoteName('#__sr_room_types') . ' WHERE id = ' . $this->_dbo->quote($roomTypeId) . ')');
$this->_dbo->setQuery($query);
return $this->_dbo->loadResult();
}
public function getUnavailableDates($roomTypeId, $year, $month)
{
$solidresParams = JComponentHelper::getParams('com_solidres');
if (empty($year) || empty($month) || empty($roomTypeId))
{
return;
}
$datePickerMonthNum = $solidresParams->get('datepicker_month_number', 1);
$confirmationState = $solidresParams->get('confirm_state', 5);
$bookingType = $this->getBookingType($roomTypeId);
$start = strtotime("01-$month-$year");
$end = strtotime("+$datePickerMonthNum month", $start);
$dates = array();
$unavailableDates = array();
for ($i = $start; $i < $end; $i += 86400)
{
$dates[] = date('Y-m-d', $i);
}
foreach ($dates as $date)
{
$checkin = $date;
if ($bookingType == 0)
{
$checkout = date('Y-m-d', strtotime('+1 day', strtotime($checkin)));
}
else
{
$checkout = $checkin;
}
$availableRooms = $this->getListAvailableRoom($roomTypeId, $checkin, $checkout, $bookingType, 0, $confirmationState);
if (!$availableRooms || count($availableRooms) == 0)
{
$unavailableDates[] = $date;
}
}
return $unavailableDates;
}
public function clearInternalCache()
{
self::$loadedAvailableRooms = [];
}
}