+* @copyright 2010-2023 Webkul IN
+* @license https://store.webkul.com/license.html
+*}
+
+{if isset($orderOverBookings) && $orderOverBookings}
+
+
+ {l s='Overbookings found in this order !!'}
+
+
+
+
+
+
- {l s='You can resolve room overbooking with \'Resolve\' column only when the overbooked room is now free for booked duration.'}
+
- {l s='You can also reallocate an overbooked room with an available room to resolve room\'s overbooking.'}
+
+
+
+{/if}
\ No newline at end of file
diff --git a/admin/themes/default/template/controllers/orders/_product_line.tpl b/admin/themes/default/template/controllers/orders/_product_line.tpl
index ce198686e..4685230f5 100644
--- a/admin/themes/default/template/controllers/orders/_product_line.tpl
+++ b/admin/themes/default/template/controllers/orders/_product_line.tpl
@@ -30,7 +30,10 @@
{/if}
- {$data.room_num}
+ {$data.room_num}
+ {if $data.is_back_order}
+ {l s='overbooked'}
+ {/if}
|
diff --git a/admin/themes/default/template/controllers/orders/_resolvable_overbookings.tpl b/admin/themes/default/template/controllers/orders/_resolvable_overbookings.tpl
new file mode 100644
index 000000000..b2f5cba79
--- /dev/null
+++ b/admin/themes/default/template/controllers/orders/_resolvable_overbookings.tpl
@@ -0,0 +1,77 @@
+{*
+* 2010-2023 Webkul.
+*
+* NOTICE OF LICENSE
+*
+* All right is reserved,
+* Please go through this link for complete license : https://store.webkul.com/license.html
+*
+* DISCLAIMER
+*
+* Do not edit or add to this file if you wish to upgrade this module to newer
+* versions in the future. If you wish to customize this module for your
+* needs please refer to https://store.webkul.com/customisation-guidelines/ for more information.
+*
+* @author Webkul IN
+* @copyright 2010-2023 Webkul IN
+* @license https://store.webkul.com/license.html
+*}
+
+{if isset($resolvableOverBookings) && $resolvableOverBookings}
+
+
+ {l s='Resolvable Overbookings'}
+
+
+ {if isset($smarty.get.resolvable_overbooked_orders) && $smarty.get.resolvable_overbooked_orders}
+
+ {/if}
+
+ {l s='Some overbookings are now available to be resolved. You can directly resolve overbookings from below list as per your choice.'}
+ {if !isset($smarty.get.resolvable_overbooked_orders) || !$smarty.get.resolvable_overbooked_orders}
+
+ {l s='You can also filter orders which overbookings are now available to be resolved.'} {l s='Filter orders with resolvable overbookings'}
+ {/if}
+
+
+
+
+
+{/if}
diff --git a/admin/themes/default/template/controllers/orders/helpers/view/view.tpl b/admin/themes/default/template/controllers/orders/helpers/view/view.tpl
index 480b84455..7dd73d353 100644
--- a/admin/themes/default/template/controllers/orders/helpers/view/view.tpl
+++ b/admin/themes/default/template/controllers/orders/helpers/view/view.tpl
@@ -105,6 +105,10 @@
+
+ {* Overbookings information of the order *}
+ {include file='controllers/orders/_overbookings.tpl'}
+
diff --git a/classes/PaymentModule.php b/classes/PaymentModule.php
index 0e30ce63b..7add9d744 100644
--- a/classes/PaymentModule.php
+++ b/classes/PaymentModule.php
@@ -760,15 +760,16 @@ abstract class PaymentModuleCore extends Module
// update order in htl tables
$objRoomType = new HotelRoomType();
-
$objAdvancedPayment = new HotelAdvancedPayment();
-
+ $objCartBookingData = new HotelCartBookingData();
+ $objBookingDetail = new HotelBookingDetail();
$vatAddress = new Address((int)$order->id_address_tax);
$idLang = (int)$this->context->cart->id_lang;
$normalProducts = array();
+ // variable to check max overbookings are created in the room in any date of the booking duration
+ $maxOverbookingCount = 0;
foreach ($order->product_list as $product) {
- $objCartBookingData = new HotelCartBookingData();
$idProduct = $product['id_product'];
$cartBookingData = $objCartBookingData->getOnlyCartBookingData($this->context->cart->id, $this->context->cart->id_guest, $idProduct);
if ($cartBookingData) {
@@ -776,8 +777,67 @@ abstract class PaymentModuleCore extends Module
$objCartBookingData = new HotelCartBookingData($bookingInfo['id']);
$objCartBookingData->id_order = $order->id;
$objCartBookingData->id_customer = $this->context->customer->id;
+
+ // check if still room available for this booking or not
+ $isRoomOverBooked = 1;
+
+ // get all the available rooms right now
+ $bookingParams = array(
+ 'date_from' => $objCartBookingData->date_from,
+ 'date_to' => $objCartBookingData->date_to,
+ 'hotel_id' => $objCartBookingData->id_hotel,
+ 'id_room_type' => $idProduct,
+ 'only_search_data' => 1
+ );
+
+ if ($searchRoomsInfo = $objBookingDetail->getBookingData($bookingParams)) {
+ if (isset($searchRoomsInfo['rm_data'][$idProduct]['data']['available'])
+ && $searchRoomsInfo['rm_data'][$idProduct]['data']['available']
+ ) {
+ $availableRoomsInfo = $searchRoomsInfo['rm_data'][$idProduct]['data']['available'];
+ if ($roomIdsAvailable = array_column($availableRoomsInfo, 'id_room')) {
+ // If room is still there in the available rooms list then it is not in back order
+ if (in_array($objCartBookingData->id_room, $roomIdsAvailable)) {
+ $isRoomOverBooked = 0;
+ } else {
+ $isRoomOverBooked = 1;
+ foreach ($roomIdsAvailable as $idRoom) {
+ if ($idRoom != $objCartBookingData->id_room) {
+ $objCartBookingData->id_room = $idRoom;
+ $isRoomOverBooked = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // if room is not available right now the set it to back order
+ if ($isRoomOverBooked) {
+ $objCartBookingData->is_back_order = 1;
+
+ // max overbookings in a room datewise breakup. So that we can know no. of overbookings in every date
+ if ($roomOverBookings = $objBookingDetail->getOverbookedRooms(
+ 0,
+ $objCartBookingData->id_hotel,
+ $objCartBookingData->date_from,
+ $objCartBookingData->date_to,
+ 0,
+ 1
+ )) {
+ // check in the bokking duration what is the max overbookings in ay date in the date range
+ // replace $maxOverbookingCount with $maxOverbookingsInDate if it is greater
+ if ($maxOverbookingCount < $roomOverBookings) {
+ $maxOverbookingCount = $roomOverBookings;
+ }
+ }
+ } else {
+ $objCartBookingData->is_back_order = 0;
+ }
$objCartBookingData->save();
+ // Lets set data to the hotel booking detail table
$objBookingDetail = new HotelBookingDetail();
$id_order_detail = $objBookingDetail->getPsOrderDetailIdByIdProduct($idProduct, $order->id);
$objBookingDetail->id_product = $idProduct;
@@ -789,12 +849,9 @@ abstract class PaymentModuleCore extends Module
$objBookingDetail->id_customer = $this->context->customer->id;
$objBookingDetail->booking_type = $objCartBookingData->booking_type;
$objBookingDetail->id_status = 1;
+ $objBookingDetail->is_back_order = $objCartBookingData->is_back_order;
$objBookingDetail->comment = $objCartBookingData->comment;
- // For Back Order(Because of cart lock)
- if ($objCartBookingData->is_back_order) {
- $objBookingDetail->is_back_order = 1;
- }
$total_price = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice(
$idProduct,
$objCartBookingData->date_from,
@@ -998,10 +1055,39 @@ abstract class PaymentModuleCore extends Module
$new_history->addWithemail(true, $extra_vars);
// Switch to back order if needed
- if (Configuration::get('PS_STOCK_MANAGEMENT') && ($order_detail->getStockState() || $order_detail->product_quantity_in_stock <= 0)) {
+ $objHotelBookingDetail = new HotelBookingDetail();
+ if ($objHotelBookingDetail->getOverbookedRooms($order->id)) {
+ $cancelOrder = 0;
+ // Take overbooking action as per order->overbooking Preferences else set order for cancellation
+ if (Configuration::get('PS_OVERBOOKING_ORDER_ACTION') == Order::OVERBOOKING_ORDER_CANCEL_ACTION) {
+ $cancelOrder = 1;
+ } else {
+ // check conditions for maximun overbookings allowed for the hotel else set order for cancellation
+ $maxAllowedOverbookings = Configuration::get('PS_MAX_OVERBOOKING_PER_HOTEL_PER_DAY');
+ // >= condition applied because equal case means already overbooked rooms limit exceeded before this booking
+ if ($maxAllowedOverbookings && ($maxOverbookingCount >= $maxAllowedOverbookings)) {
+ $cancelOrder = 1;
+ }
+ }
+
+ // set order status after all conditions checks
+ if ($cancelOrder) {
+ $id_order_state = Configuration::get('PS_OS_CANCELED');
+ } else {
+ if ($order->valid) {
+ if ($order->is_advance_payment && $order->advance_paid_amount < $order->total_paid_tax_incl) {
+ $id_order_state = Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID');
+ } else {
+ $id_order_state = Configuration::get('PS_OS_OVERBOOKING_PAID');
+ }
+ } else {
+ $id_order_state = Configuration::get('PS_OS_OVERBOOKING_UNPAID');
+ }
+ }
+
$history = new OrderHistory();
$history->id_order = (int)$order->id;
- $history->changeIdOrderState(Configuration::get($order->valid ? 'PS_OS_OUTOFSTOCK_PAID' : 'PS_OS_OUTOFSTOCK_UNPAID'), $order, true);
+ $history->changeIdOrderState($id_order_state, $order, true);
$history->addWithemail();
}
@@ -1147,8 +1233,21 @@ abstract class PaymentModuleCore extends Module
PrestaShopLogger::addLog('PaymentModule::validateOrder - Mail is about to be sent', 1, null, 'Cart', (int)$id_cart, true);
}
- // Send order confirmation mails to the reciepients according to the order mail configuration
+ $orderStatusObj = new OrderState((int)$id_order_state, (int)$this->context->language->id);
+ $data['{order_status}'] = $orderStatusObj->name;
+ $data['{order_status_color}'] = $orderStatusObj->color;
+ // Send order confirmation/overbooking mails to the reciepients according to the order mail configuration
+ $overBookingStates = OrderState::getOverBookingStates();
+ $isOverBookingStatus = in_array($id_order_state, $overBookingStates);
if (Configuration::get('PS_ORDER_CONF_MAIL_TO_CUSTOMER')){
+ // If order currenct state is overbooking, the send overbooking email or send order confirmation email
+ if ($isOverBookingStatus) {
+ $subject = Mail::l('Order Not Confirmed', (int)$order->id_lang);
+ $template = 'overbooking';
+ } else {
+ $subject = Mail::l('Order confirmation', (int)$order->id_lang);
+ $template = 'order_conf';
+ }
if (Validate::isEmail($this->context->customer->email)) {
// send customer information
$data['{firstname}'] = $this->context->customer->firstname;
@@ -1156,8 +1255,8 @@ abstract class PaymentModuleCore extends Module
$data['{email}'] = $this->context->customer->email;
Mail::Send(
(int)$order->id_lang,
- 'order_conf',
- Mail::l('Order confirmation', (int)$order->id_lang),
+ $template,
+ $subject,
$data,
$this->context->customer->email,
$this->context->customer->firstname.' '.$this->context->customer->lastname,
@@ -1178,8 +1277,8 @@ abstract class PaymentModuleCore extends Module
$data['{email}'] = $objOrderCustomerGuestDetail->email;
Mail::Send(
(int)$order->id_lang,
- 'order_conf',
- Mail::l('Order confirmation', (int)$order->id_lang),
+ $template,
+ $subject,
$data,
$objOrderCustomerGuestDetail->email,
$objOrderCustomerGuestDetail->firstname.' '.$objOrderCustomerGuestDetail->lastname,
@@ -1193,8 +1292,17 @@ abstract class PaymentModuleCore extends Module
}
}
if (Configuration::get('PS_ORDER_CONF_MAIL_TO_SUPERADMIN')){
- // send superadmin information
+ // get superadmin employees
if ($superAdminEmployees = Employee::getEmployeesByProfile(_PS_ADMIN_PROFILE_, true)) {
+ // If order currenct state is overbooking, the send overbooking email or send order confirmation email
+ if ($isOverBookingStatus) {
+ $subject = Mail::l('Order Not Confirmed', (int)$order->id_lang);
+ $template = 'overbooking_admin';
+ } else {
+ $subject = Mail::l('Order confirmation', (int)$order->id_lang);
+ $template = 'order_conf_admin';
+ }
+
foreach ($superAdminEmployees as $superAdminEmployee) {
if (Validate::isEmail($superAdminEmployee['email'])) {
$data['{customer_name}'] = $this->context->customer->firstname.' '.$this->context->customer->lastname;
@@ -1204,8 +1312,8 @@ abstract class PaymentModuleCore extends Module
$data['{email}'] = $superAdminEmployee['email'];
Mail::Send(
(int)$order->id_lang,
- 'order_conf_admin',
- Mail::l('Order confirmation', (int)$order->id_lang),
+ $template,
+ $subject,
$data,
$superAdminEmployee['email'],
$superAdminEmployee['firstname'].' '.$superAdminEmployee['lastname'],
@@ -1222,6 +1330,14 @@ abstract class PaymentModuleCore extends Module
&& Validate::isLoadedObject($objHotel = new HotelBranchInformation($idHotel))
) {
if (Configuration::get('PS_ORDER_CONF_MAIL_TO_HOTEL_MANAGER')){
+ // If order currenct state is overbooking, the send overbooking email or send order confirmation email
+ if ($isOverBookingStatus) {
+ $subject = Mail::l('Order Not Confirmed', (int)$order->id_lang);
+ $template = 'overbooking_admin';
+ } else {
+ $subject = Mail::l('Order confirmation', (int)$order->id_lang);
+ $template = 'order_conf_admin';
+ }
// send hotel information
$data['{firstname}'] = '';
$data['{lastname}'] = '';
@@ -1231,8 +1347,8 @@ abstract class PaymentModuleCore extends Module
if (Validate::isEmail($objHotel->email)) {
Mail::Send(
(int)$order->id_lang,
- 'order_conf_admin',
- Mail::l('Order confirmation', (int)$order->id_lang),
+ $template,
+ $subject,
$data,
$objHotel->email,
null,
@@ -1247,6 +1363,16 @@ abstract class PaymentModuleCore extends Module
if ($htlAccesses = $objHotel->getHotelAccess($idHotel)) {
$data['{customer_name}'] = $this->context->customer->firstname.' '.$this->context->customer->lastname;
$data['{customer_email}'] = $this->context->customer->email;
+
+ // If order currenct state is overbooking, the send overbooking email or send order confirmation email
+ if ($isOverBookingStatus) {
+ $subject = Mail::l('Order Not Confirmed', (int)$order->id_lang);
+ $template = 'overbooking_admin';
+ } else {
+ $subject = Mail::l('Order confirmation', (int)$order->id_lang);
+ $template = 'order_conf_admin';
+ }
+
foreach ($htlAccesses as $access) {
if ($access['access'] && $access['id_profile'] != _PS_ADMIN_PROFILE_) {
if ($htlEmployees = Employee::getEmployeesByProfile($access['id_profile'])) {
@@ -1258,8 +1384,8 @@ abstract class PaymentModuleCore extends Module
$data['{email}'] = $empl['email'];
Mail::Send(
(int)$order->id_lang,
- 'order_conf_admin',
- Mail::l('Order confirmation', (int)$order->id_lang),
+ $template,
+ $subject,
$data,
$empl['email'],
$empl['firstname'].' '.$empl['lastname'],
@@ -1277,7 +1403,6 @@ abstract class PaymentModuleCore extends Module
}
}
}
-
// updates stock in shops
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
$product_list = $order->getProducts();
diff --git a/classes/order/Order.php b/classes/order/Order.php
index bf9a33801..a4e7a5e6b 100644
--- a/classes/order/Order.php
+++ b/classes/order/Order.php
@@ -34,6 +34,10 @@ class OrderCore extends ObjectModel
const ORDER_PAYMENT_TYPE_FULL = 1;
const ORDER_PAYMENT_TYPE_ADVANCE = 2;
+ // actions when overbooking will be created
+ const OVERBOOKING_ORDER_CANCEL_ACTION = 1;
+ const OVERBOOKING_ORDER_NO_ACTION = 2;
+
//Consts for: In the order list in which currency prices should be displayed
const ORDER_LIST_PRICE_DISPLAY_IN_PAYMENT_CURRENCY = 1;
const ORDER_LIST_PRICE_DISPLAY_IN_DEFAULT_CURRENCY = 2;
diff --git a/classes/order/OrderState.php b/classes/order/OrderState.php
index 22e3d8db4..cd14adbf3 100644
--- a/classes/order/OrderState.php
+++ b/classes/order/OrderState.php
@@ -155,4 +155,13 @@ class OrderStateCore extends ObjectModel
{
return !($this->unremovable);
}
+
+ public static function getOverBookingStates()
+ {
+ return array(
+ Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID'),
+ Configuration::get('PS_OS_OVERBOOKING_PAID'),
+ Configuration::get('PS_OS_OVERBOOKING_UNPAID'),
+ );
+ }
}
diff --git a/controllers/admin/AdminOrderPreferencesController.php b/controllers/admin/AdminOrderPreferencesController.php
index 52c131480..5f8622503 100644
--- a/controllers/admin/AdminOrderPreferencesController.php
+++ b/controllers/admin/AdminOrderPreferencesController.php
@@ -58,6 +58,18 @@ class AdminOrderPreferencesControllerCore extends AdminController
)
);
+ // actions when overbooking will be created
+ $overbookingAction = array(
+ array(
+ 'value' => Order::OVERBOOKING_ORDER_CANCEL_ACTION,
+ 'name' => $this->l('Cancel the booking')
+ ),
+ array(
+ 'value' => Order::OVERBOOKING_ORDER_NO_ACTION,
+ 'name' => $this->l('Take the overbooking')
+ )
+ );
+
// Options to display currency in order list
$displayCurrencyOptions = array(
array(
@@ -195,33 +207,83 @@ class AdminOrderPreferencesControllerCore extends AdminController
'submit' => array('title' => $this->l('Save'))
),
'email' => array(
- 'title' => $this->l('Email'),
+ 'title' => $this->l('Order Confirmation / Overbooking Email'),
'icon' => 'icon-cogs',
'fields' => array(
'PS_ORDER_CONF_MAIL_TO_CUSTOMER' => array(
- 'title' => $this->l('Order confirmation mail to customer'),
- 'hint' => $this->l('Enable, if you want to send order confirmation email to the customer.'),
+ 'title' => $this->l('Send email to customer'),
+ 'hint' => $this->l('Enable, if you want to send order confirmation or overbooking or overbooking email to the customer.'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool'
),
'PS_ORDER_CONF_MAIL_TO_SUPERADMIN' => array(
- 'title' => $this->l('Order confirmation mail to super admin'),
- 'hint' => $this->l('Enable, if you want to send order confirmation email to the super admin.'),
+ 'title' => $this->l('Send email to super admin'),
+ 'hint' => $this->l('Enable, if you want to send order confirmation or overbooking email to the super admin.'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool'
),
'PS_ORDER_CONF_MAIL_TO_HOTEL_MANAGER' => array(
- 'title' => $this->l('Order confirmation mail to hotelier'),
- 'hint' => $this->l('Enable, if you want to send order confirmation email to the hotelier. Mail will be sent to the email saved while creating the hotel.'),
+ 'title' => $this->l('Send email to hotelier'),
+ 'hint' => $this->l('Enable, if you want to send order confirmation or overbooking email to the hotelier. Mail will be sent to the email saved while creating the hotel.'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool'
),
'PS_ORDER_CONF_MAIL_TO_EMPLOYEE' => array(
- 'title' => $this->l('Order confirmation mail to employees'),
- 'hint' => $this->l('Enable, if you want to send order confirmation email to employees having permission to manage the hotel.'),
+ 'title' => $this->l('Send email to employees'),
+ 'hint' => $this->l('Enable, if you want to send order confirmation or overbooking email to employees having permission to manage the hotel.'),
+ 'validation' => 'isBool',
+ 'cast' => 'intval',
+ 'type' => 'bool'
+ ),
+ ),
+ 'submit' => array('title' => $this->l('Save'))
+ ),
+ 'overbooking' => array(
+ 'title' => $this->l('Overbooking'),
+ 'icon' => 'icon-cogs',
+ 'fields' => array(
+ 'PS_OVERBOOKING_ORDER_ACTION' => array(
+ 'title' => $this->l('Overbooking order action'),
+ 'hint' => $this->l('Please choose the action to take when overbooking is created in any order.'),
+ 'validation' => 'isInt',
+ 'type' => 'select',
+ 'cast' => 'intval',
+ 'validation' => 'isInt',
+ 'list' => $overbookingAction,
+ 'identifier' => 'value',
+ 'js' => "changeOverbookingOrderAction()"
+ ),
+ 'PS_MAX_OVERBOOKING_PER_HOTEL_PER_DAY' => array(
+ 'title' => $this->l('Maximun hotel overbookings per date'),
+ 'hint' => $this->l('Enter the maximum number of the overbookings on any date can be created for a hotel.(Set 0 for no limit)'),
+ 'desc' => $this->l('When maximun number of the overbookings on any date in the booking duration is reached, then the new overbooking order will be cancelled.(Set 0 for no limit)'),
+ 'validation' => 'isInt',
+ 'type' => 'text',
+ 'class' => 'fixed-width-xxl',
+ 'validation' => 'isInt',
+ 'id' => 'PS_MAX_OVERBOOKING_PER_HOTEL_PER_DAY',
+ ),
+ 'OVERBOOKING_ORDER_CANCEL_ACTION' => array(
+ 'title' => $this->l('Overbooking order cancel action value'),
+ 'type' => 'hidden',
+ 'value' => Order::OVERBOOKING_ORDER_CANCEL_ACTION,
+ 'auto_value' => false,
+ ),
+ 'OVERBOOKING_ORDER_NO_ACTION' => array(
+ 'title' => $this->l('Overbooking order no action value'),
+ 'validation' => 'isInt',
+ 'cast' => 'intval',
+ 'type' => 'hidden',
+ 'value' => Order::OVERBOOKING_ORDER_NO_ACTION,
+ 'auto_value' => false
+ ),
+ 'PS_OVERBOOKING_AUTO_RESOLVE' => array(
+ 'title' => $this->l('Resolve overbooking automatically'),
+ 'hint' => $this->l('Enable, if you want to resolve overbooking automatically when rooms are available to be replaced with overbooked rooms.'),
+ 'desc' => $this->l('If enabled, the overbookings in the order will be resolved automatically when rooms are available to be replaced with all overbooked rooms in the order.'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool'
diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php
index b58c17844..52769f958 100644
--- a/controllers/admin/AdminOrdersController.php
+++ b/controllers/admin/AdminOrdersController.php
@@ -96,6 +96,22 @@ class AdminOrdersControllerCore extends AdminController
$this->_group = ' GROUP BY hbd.`id_order`';
+ // if request for resolvable overbooked orders filter comes the set condition for this
+ if (Tools::getIsset('resolvable_overbooked_orders') && Tools::getValue('resolvable_overbooked_orders')) {
+ $objHotelBookingDetail = new HotelBookingDetail();
+ $resolvableOrders = array();
+ // Overbookings information of the order
+ if ($orderOverBookings = $objHotelBookingDetail->getOverbookedRooms()) {
+ foreach ($orderOverBookings as $overBookedRoom) {
+ if (!in_array($overBookedRoom['id_order'], $resolvableOrders)) {
+ $resolvableOrders[$overBookedRoom['id_order']] = $overBookedRoom['id_order'];
+ }
+ }
+ }
+ $this->_where = ' AND a.`id_order` IN ('.implode(',', $resolvableOrders).')';
+ }
+
+
$statuses = OrderState::getOrderStates((int)$this->context->language->id);
foreach ($statuses as $status) {
$this->statuses_array[$status['id_order_state']] = $status['name'];
@@ -326,6 +342,8 @@ class AdminOrdersControllerCore extends AdminController
parent::__construct();
+ // overbooking success status
+ $this->_conf[51] = $this->l('Overbooking is successfully resolved');
$this->_conf[52] = $this->l('Room in the booking is successfully reallocated');
$this->_conf[53] = $this->l('Room in the booking is successfully swapped');
}
@@ -610,6 +628,13 @@ class AdminOrdersControllerCore extends AdminController
public function renderList()
{
+ // Show all resolvable overbookings if available
+ $objHotelBookingDetail = new HotelBookingDetail();
+ if ($resolvableOverBookings = $objHotelBookingDetail->getOverbookedRooms(0, 0, '', '', 0, 0, 2)) {
+ $this->context->smarty->assign('resolvableOverBookings', $resolvableOverBookings);
+ $this->content .= $this->context->smarty->fetch('controllers/orders/_resolvable_overbookings.tpl');
+ }
+
if (Tools::isSubmit('submitBulkupdateOrderStatus'.$this->table)) {
if (Tools::getIsset('cancel')) {
Tools::redirectAdmin(self::$currentIndex.'&token='.$this->token);
@@ -1701,7 +1726,20 @@ class AdminOrdersControllerCore extends AdminController
} else {
$this->errors[] = Tools::displayError('You do not have permission to edit this.');
}
+ } elseif(Tools::getIsset('resolve_overbooking') && Tools::getValue('resolve_overbooking')) {
+ $objHotelBookingDetail = new HotelBookingDetail();
+ // resolve an overbooking manually
+ if ($objHotelBookingDetail->resolveOverbookings(Tools::getValue('resolve_overbooking'))) {
+ if (Tools::getValue('id_order')) {
+ Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=51&token='.$this->token);
+ } else {
+ Tools::redirectAdmin(self::$currentIndex.'&conf=51&token='.$this->token);
+ }
+ } else {
+ $this->errors = Tools::displayError('An error occurred while resolving overbooking.');
+ }
}
+
parent::postProcess();
}
@@ -2111,8 +2149,12 @@ class AdminOrdersControllerCore extends AdminController
// applicable refund policies
$applicableRefundPolicies = HotelOrderRefundRules::getApplicableRefundRules($order->id);
+ // Overbookings information of the order
+ $orderOverBookings = $objHotelBookingDetail->getOverbookedRooms($order->id, 0, '', '', 0, 0, 1);
+
$this->tpl_view_vars = array(
// refund info
+ 'orderOverBookings' => $orderOverBookings,
'refund_allowed' => (int) $order->isReturnable(),
'applicable_refund_policies' => $applicableRefundPolicies,
'returns' => OrderReturn::getOrdersReturn($order->id_customer, $order->id),
diff --git a/controllers/front/HistoryController.php b/controllers/front/HistoryController.php
index e3a8210e4..8e41935c8 100644
--- a/controllers/front/HistoryController.php
+++ b/controllers/front/HistoryController.php
@@ -66,6 +66,7 @@ class HistoryControllerCore extends FrontController
}
$this->context->smarty->assign(array(
'orders' => $orders,
+ 'overbooking_order_states' => OrderState::getOverBookingStates(),
'invoiceAllowed' => (int)Configuration::get('PS_INVOICE'),
'reorderingAllowed' => !(bool)Configuration::get('PS_DISALLOW_HISTORY_REORDERING'),
'slowValidation' => Tools::isSubmit('slowvalidation')
diff --git a/controllers/front/OrderDetailController.php b/controllers/front/OrderDetailController.php
index 96a3656f3..3f9f89187 100644
--- a/controllers/front/OrderDetailController.php
+++ b/controllers/front/OrderDetailController.php
@@ -679,6 +679,7 @@ class OrderDetailControllerCore extends FrontController
'invoice' => (OrderState::invoiceAvailable($id_order_state) && count($order->getInvoicesCollection())),
'logable' => (bool) $order_status->logable,
'order_history' => $order->getHistory($this->context->language->id, false, true),
+ 'overbooking_order_states' => OrderState::getOverBookingStates(),
'products' => $products,
'discounts' => $order->getCartRules(),
'carrier' => $carrier,
diff --git a/install/data/img/os/Overbooking_partial_paid.gif b/install/data/img/os/Overbooking_partial_paid.gif
new file mode 100644
index 000000000..7a8f831fc
Binary files /dev/null and b/install/data/img/os/Overbooking_partial_paid.gif differ
diff --git a/install/data/xml/configuration.xml b/install/data/xml/configuration.xml
index 67b8602c1..984a749f4 100644
--- a/install/data/xml/configuration.xml
+++ b/install/data/xml/configuration.xml
@@ -332,6 +332,12 @@
0
+
+ 1
+
+
+ 0
+
1
@@ -431,6 +437,9 @@
11
+
+ 12
+
diff --git a/install/data/xml/order_state.xml b/install/data/xml/order_state.xml
index a1f70e4ec..cc016ffcd 100644
--- a/install/data/xml/order_state.xml
+++ b/install/data/xml/order_state.xml
@@ -26,7 +26,7 @@
-
+
@@ -34,7 +34,9 @@
-
+
+
+
diff --git a/install/langs/bg/data/order_state.xml b/install/langs/bg/data/order_state.xml
index c1d4db4c4..fd178eee0 100644
--- a/install/langs/bg/data/order_state.xml
+++ b/install/langs/bg/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/bn/data/order_state.xml b/install/langs/bn/data/order_state.xml
index f727c14a3..58046ed66 100644
--- a/install/langs/bn/data/order_state.xml
+++ b/install/langs/bn/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/br/data/order_state.xml b/install/langs/br/data/order_state.xml
index 7cb239191..27793a7d8 100644
--- a/install/langs/br/data/order_state.xml
+++ b/install/langs/br/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/cs/data/order_state.xml b/install/langs/cs/data/order_state.xml
index c349433f1..8517a8563 100644
--- a/install/langs/cs/data/order_state.xml
+++ b/install/langs/cs/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/de/data/order_state.xml b/install/langs/de/data/order_state.xml
index 921cb4aab..d1a0de2c9 100644
--- a/install/langs/de/data/order_state.xml
+++ b/install/langs/de/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/en/data/order_state.xml b/install/langs/en/data/order_state.xml
index b4714fb54..92aaec2fc 100644
--- a/install/langs/en/data/order_state.xml
+++ b/install/langs/en/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/es/data/order_state.xml b/install/langs/es/data/order_state.xml
index 91c9ef4b1..851eff8b9 100644
--- a/install/langs/es/data/order_state.xml
+++ b/install/langs/es/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/fa/data/order_state.xml b/install/langs/fa/data/order_state.xml
index a0a599e41..401c894b3 100644
--- a/install/langs/fa/data/order_state.xml
+++ b/install/langs/fa/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/fr/data/order_state.xml b/install/langs/fr/data/order_state.xml
index 736388cc3..5efb4e492 100644
--- a/install/langs/fr/data/order_state.xml
+++ b/install/langs/fr/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/he/data/order_state.xml b/install/langs/he/data/order_state.xml
index 9cb60de92..60813e4b9 100644
--- a/install/langs/he/data/order_state.xml
+++ b/install/langs/he/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/hr/data/order_state.xml b/install/langs/hr/data/order_state.xml
index d5e3c32c4..c7e15b1ec 100644
--- a/install/langs/hr/data/order_state.xml
+++ b/install/langs/hr/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/hu/data/order_state.xml b/install/langs/hu/data/order_state.xml
index bf97e806c..0b841f7b8 100644
--- a/install/langs/hu/data/order_state.xml
+++ b/install/langs/hu/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/id/data/order_state.xml b/install/langs/id/data/order_state.xml
index 3b87e26b2..448637c9a 100644
--- a/install/langs/id/data/order_state.xml
+++ b/install/langs/id/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/it/data/order_state.xml b/install/langs/it/data/order_state.xml
index d80b7467d..22870fc7a 100644
--- a/install/langs/it/data/order_state.xml
+++ b/install/langs/it/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/lt/data/order_state.xml b/install/langs/lt/data/order_state.xml
index e108d40ce..e4a741da6 100644
--- a/install/langs/lt/data/order_state.xml
+++ b/install/langs/lt/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/mk/data/order_state.xml b/install/langs/mk/data/order_state.xml
index 6f3789e59..17d5f73c4 100644
--- a/install/langs/mk/data/order_state.xml
+++ b/install/langs/mk/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/nl/data/order_state.xml b/install/langs/nl/data/order_state.xml
index b34506d95..d89ee35fd 100644
--- a/install/langs/nl/data/order_state.xml
+++ b/install/langs/nl/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/no/data/order_state.xml b/install/langs/no/data/order_state.xml
index b4714fb54..92aaec2fc 100644
--- a/install/langs/no/data/order_state.xml
+++ b/install/langs/no/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/pl/data/order_state.xml b/install/langs/pl/data/order_state.xml
index 08c49eb92..8f46aa9d3 100644
--- a/install/langs/pl/data/order_state.xml
+++ b/install/langs/pl/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/pt/data/order_state.xml b/install/langs/pt/data/order_state.xml
index 7c2bce22e..724f73eff 100644
--- a/install/langs/pt/data/order_state.xml
+++ b/install/langs/pt/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/qc/data/order_state.xml b/install/langs/qc/data/order_state.xml
index d499bf3b5..3ee8f53c5 100644
--- a/install/langs/qc/data/order_state.xml
+++ b/install/langs/qc/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/ro/data/order_state.xml b/install/langs/ro/data/order_state.xml
index 11ca25a0b..7e5691eb5 100644
--- a/install/langs/ro/data/order_state.xml
+++ b/install/langs/ro/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/ru/data/order_state.xml b/install/langs/ru/data/order_state.xml
index fb864990e..84888fc5b 100644
--- a/install/langs/ru/data/order_state.xml
+++ b/install/langs/ru/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/si/data/order_state.xml b/install/langs/si/data/order_state.xml
index 7d88f9612..c9ab88147 100644
--- a/install/langs/si/data/order_state.xml
+++ b/install/langs/si/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/sr/data/order_state.xml b/install/langs/sr/data/order_state.xml
index 753d2f254..22ccbb182 100644
--- a/install/langs/sr/data/order_state.xml
+++ b/install/langs/sr/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/sv/data/order_state.xml b/install/langs/sv/data/order_state.xml
index bad3427b1..404c276dd 100644
--- a/install/langs/sv/data/order_state.xml
+++ b/install/langs/sv/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/tw/data/order_state.xml b/install/langs/tw/data/order_state.xml
index 36c90c477..a13ccc3d4 100644
--- a/install/langs/tw/data/order_state.xml
+++ b/install/langs/tw/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/vn/data/order_state.xml b/install/langs/vn/data/order_state.xml
index 91a6c0096..c3a6b15b3 100644
--- a/install/langs/vn/data/order_state.xml
+++ b/install/langs/vn/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/install/langs/zh/data/order_state.xml b/install/langs/zh/data/order_state.xml
index 68f8b1f1f..c0c0c6766 100644
--- a/install/langs/zh/data/order_state.xml
+++ b/install/langs/zh/data/order_state.xml
@@ -33,11 +33,15 @@
- Overbooking (paid)
+ Overbooking (Paid)
- Overbooking (not paid)
+ Overbooking (Not paid)
+
+
+
+ Overbooking (Partial payment)
diff --git a/js/admin.js b/js/admin.js
index b62330201..7f648dc27 100644
--- a/js/admin.js
+++ b/js/admin.js
@@ -504,6 +504,14 @@ function changeCMSActivationAuthorization()
getE('PS_CONDITIONS_CMS_ID').disabled = 'disabled';
}
+function changeOverbookingOrderAction()
+{
+ if (getE('PS_OVERBOOKING_ORDER_ACTION').value == $("input[name='OVERBOOKING_ORDER_CANCEL_ACTION']").val())
+ $('#PS_MAX_OVERBOOKING_PER_HOTEL_PER_DAY').closest('.form-group').hide();
+ else
+ $('#PS_MAX_OVERBOOKING_PER_HOTEL_PER_DAY').closest('.form-group').show();
+}
+
function disableZipFormat()
{
if ($('#need_zip_code_on').prop('checked') == false)
diff --git a/js/admin/orders.js b/js/admin/orders.js
index e24800457..46ecdbf70 100644
--- a/js/admin/orders.js
+++ b/js/admin/orders.js
@@ -1844,6 +1844,11 @@ $(document).on('click', '#booking-documents-modal .documents-list .btn-delete-do
}
});
+$(document).on('click', '.reallocate_overbooking', function(e) {
+ e.preventDefault();
+ $('#reallocate_room_' + $(this).attr('id_htl_booking')).trigger('click');
+});
+
const BookingDocumentsModal = {
init: function(idHtlBooking, $this) {
BookingDocumentsModal.currentTr = $this;
diff --git a/mails/en/overbooking.html b/mails/en/overbooking.html
new file mode 100755
index 000000000..4fc0e43c6
--- /dev/null
+++ b/mails/en/overbooking.html
@@ -0,0 +1,381 @@
+
+
+
+
+
+ Message from {shop_name}
+
+
+
+
+
+
+
+
+ | |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+ Hi {firstname} {lastname},
+ Thank you for selecting our hotel!
+ Bookings in this order are Not Confirmed yet !!
+ We are sorry for your inconvenience. Please contact hotel to get final confirmation for your bookings.
+
+ |
+
+
+
+
+
+
+
+
+ | |
+
+
+ Order details
+
+ Order: {order_name} Placed on {date}
+ Payment: {payment}
+ Status: {order_status}
+
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+
+ | Room Image |
+ Room Description |
+ Hotel |
+ Room Capcity |
+ Unit Price |
+ Rooms Qty |
+ Check-in Date |
+ Check-out Date |
+ Total |
+
+
+
+ |
+ {cart_booking_data_html}
+ |
+
+
+
+
+ |
+
+
+ |
+ {extra_demands_details_html}
+ |
+
+
+
+
+
+
+ |
+ {discounts}
+ |
+
+
+
+
+
+ | |
+
+
+ Total Rooms Cost
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {room_price_tax_excl}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Extra Services Cost
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {additional_service_price_tax_excl}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+
+ | |
+
+
+ Discounts
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_discounts}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Total Convenience Fees
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_convenience_fee_te}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Total Tax
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_tax_paid}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Final Booking Amount
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_paid}
+
+ |
+ |
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ | |
+
+
+
+ Customer address
+
+ {invoice_block_html}
+
+
+
+ |
+ |
+
+
+ |
+
+
+ |
+
+
+
+
+
+ |
+
+
+ You can review your order and download your invoice from the "Order history" section of your customer account by clicking "My account" on our shop.
+
+ |
+
+
+ |
+
+
+ If you have a guest account, you can follow your order via the "Guest Tracking" section on our shop.
+
+ |
+
+
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
\ No newline at end of file
diff --git a/mails/en/overbooking.txt b/mails/en/overbooking.txt
new file mode 100644
index 000000000..a6bd05b32
--- /dev/null
+++ b/mails/en/overbooking.txt
@@ -0,0 +1,60 @@
+Message from {shop_name}
+Hi {firstname} {lastname},
+Thank you for selecting our hotel!
+Bookings in this order are Not Confirmed yet !!
+We are sorry for your inconvenience. Please contact hotel to get final confirmation for your bookings.
+
+Order details
+Order: {order_name} Placed on {date}
+Payment: {payment}
+Status: {order_status}
+
+Room Image
+Room Description
+Hotel
+Room Capcity
+Unit Price
+Rooms Qty
+Check-in Date
+Check-out Date
+Total
+
+{cart_booking_data_text}
+
+{extra_demands_details_text}
+
+{discounts}
+
+Total Rooms Cost
+{total_products}
+
+Total Extra Services Cost
+{total_extra_demands_te}
+
+Discounts
+{total_discounts}
+
+Total Rooms Tax
+{total_tax_paid}
+
+Extra Services Tax
+{extra_demands_tax}
+
+Final Booking Amount
+{total_paid}
+
+Customer address
+{invoice_block_html}
+
+You can review your order and download your invoice from the
+"Order history" [{history_url}] section of your
+customer account by clicking "My account"
+[{my_account_url}] on our shop.
+
+If you have a guest account, you can follow your order via the
+"Guest Tracking"
+[{guest_tracking_url}?id_order={order_name}] section
+on our shop.
+
+{shop_name} [{shop_url}] powered by
+Webkul(tm) [https://webkul.com]
\ No newline at end of file
diff --git a/mails/en/overbooking_admin.html b/mails/en/overbooking_admin.html
new file mode 100755
index 000000000..505142081
--- /dev/null
+++ b/mails/en/overbooking_admin.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+ Message from {shop_name}
+
+
+
+
+
+
+
+
+ | |
+
+
+
+
+
+
+
+ |
+
+
+
+
+ Hi {firstname} {lastname},
+ New Bookings created on {shop_name}!
+ Bookings in this order have Overbookings !!
+ This order is not confirmed yet. Please check the order details to resolve overbookings.
+
+ |
+
+
+
+
+
+
+
+
+ | |
+
+
+
+ Customer details
+
+ Name: {customer_name}
+ Email: {customer_email}
+
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+ | |
+
+
+
+ Order details
+
+ Order: {order_name} Placed on {date}
+ Payment: {payment}
+ Status: {order_status}
+
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+
+
+ | Room Image |
+ Room Description |
+ Hotel |
+ Room Capcity |
+ Unit Price |
+ Rooms Qty |
+ Check-in Date |
+ Check-out Date |
+ Total |
+
+
+ |
+ {cart_booking_data_html}
+ |
+
+
+
+ |
+ {extra_demands_details_html}
+ |
+
+
+ |
+
+ |
+
+
+
+
+
+ | |
+
+
+ Total Rooms Cost
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {room_price_tax_excl}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Extra Services Cost
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {additional_service_price_tax_excl}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Discounts
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_discounts}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Total Convenience Fees
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_convenience_fee_te}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Total Tax
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_tax_paid}
+
+ |
+ |
+
+
+ |
+
+
+
+
+
+ | |
+
+
+ Final Booking Amount
+
+ |
+ |
+
+
+ |
+
+
+
+ | |
+
+
+ {total_paid}
+
+ |
+ |
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
\ No newline at end of file
diff --git a/mails/en/overbooking_admin.txt b/mails/en/overbooking_admin.txt
new file mode 100644
index 000000000..a9feed298
--- /dev/null
+++ b/mails/en/overbooking_admin.txt
@@ -0,0 +1,51 @@
+Message from {shop_name}
+Hi {firstname} {lastname},
+
+New Bookings created on {shop_name}!
+Bookings in this order have Overbookings !!
+This order is not confirmed yet. Please check the order details to resolve overbookings.
+
+Customer details
+Name: {customer_name}
+Email: {customer_email}
+
+Order details
+Order: {order_name} Placed on {date}
+Payment: {payment}
+Status: {order_status}
+
+Room Image
+Room Description
+Hotel
+Room Capcity
+Unit Price
+Rooms Qty
+Check-in Date
+Check-out Date
+Total
+
+{cart_booking_data_text}
+
+{extra_demands_details_text}
+
+{discounts}
+
+Total Rooms Cost
+{total_products}
+
+Total Extra Services Cost
+{total_extra_demands_te}
+
+Discounts
+{total_discounts}
+
+Total Rooms Tax
+{total_tax_paid}
+
+Extra Services Tax
+{extra_demands_tax}
+
+Final Booking Amount
+{total_paid}
+
+{shop_name} powered by Webkul™
\ No newline at end of file
diff --git a/modules/bankwire/controllers/front/validation.php b/modules/bankwire/controllers/front/validation.php
index e9cd89014..c524724bf 100644
--- a/modules/bankwire/controllers/front/validation.php
+++ b/modules/bankwire/controllers/front/validation.php
@@ -55,9 +55,8 @@ class BankwireValidationModuleFrontController extends ModuleFrontController
// Check Order restrict condition before Payment by the customer
if (Module::isInstalled('hotelreservationsystem') && Module::isEnabled('hotelreservationsystem')) {
require_once _PS_MODULE_DIR_.'hotelreservationsystem/define.php';
- $order_restrict_error = HotelOrderRestrictDate::validateOrderRestrictDateOnPayment($this);
- if ($order_restrict_error) {
- die($this->errors);
+ if (HotelOrderRestrictDate::validateOrderRestrictDateOnPayment($this)) {
+ Tools::redirect('index.php?controller=order-opc');
}
}
diff --git a/modules/cheque/controllers/front/validation.php b/modules/cheque/controllers/front/validation.php
index 8c79afea1..5e4053988 100644
--- a/modules/cheque/controllers/front/validation.php
+++ b/modules/cheque/controllers/front/validation.php
@@ -54,9 +54,8 @@ class ChequeValidationModuleFrontController extends ModuleFrontController
/*Check Order restrict condition before Payment by the customer*/
if (Module::isInstalled('hotelreservationsystem') && Module::isEnabled('hotelreservationsystem')) {
require_once _PS_MODULE_DIR_.'hotelreservationsystem/define.php';
- $order_restrict_error = HotelOrderRestrictDate::validateOrderRestrictDateOnPayment($this);
- if ($order_restrict_error) {
- die($this->errors);
+ if (HotelOrderRestrictDate::validateOrderRestrictDateOnPayment($this)) {
+ Tools::redirect('index.php?controller=order-opc');
}
}
/*END*/
diff --git a/modules/hotelreservationsystem/classes/HotelBookingDetail.php b/modules/hotelreservationsystem/classes/HotelBookingDetail.php
index ad6d8ab74..f721a255b 100644
--- a/modules/hotelreservationsystem/classes/HotelBookingDetail.php
+++ b/modules/hotelreservationsystem/classes/HotelBookingDetail.php
@@ -168,6 +168,23 @@ class HotelBookingDetail extends ObjectModel
parent::__construct($id);
}
+ public function update($null_values = false)
+ {
+ $result = parent::update($null_values);
+
+ // if automatic overbooking resolution is enabled
+ if (Configuration::get('PS_OVERBOOKING_AUTO_RESOLVE')) {
+ // if room is getting free and this room is not already in back order then resolve the overbookings for this free room
+ // $this->is_cancelled == 1 is not checked because currently we always set is_refunded to 1 when room is free
+ // $this->is_back_order == 0 is checked because $this->is_back_order == 1 is used as room is free
+ if ($this->is_refunded == 1 && $this->is_back_order == 0) {
+ $this->resolveOverBookings();
+ }
+ }
+
+ return $result;
+ }
+
public function getBookingDataParams($params)
{
if (!isset($params['id_room_type'])) {
@@ -1956,6 +1973,7 @@ class HotelBookingDetail extends ObjectModel
{
$table = 'htl_booking_detail';
$data = array('is_refunded' => (int) $is_refunded);
+
if ($id_rooms) {
foreach ($id_rooms as $key_rm => $val_rm) {
$where = 'id_order='.(int)$id_order.' AND id_room = '.(int)$val_rm['id_room'].' AND `date_from`= \''.
@@ -1963,8 +1981,15 @@ class HotelBookingDetail extends ObjectModel
$result = Db::getInstance()->update($table, $data, $where);
}
} else {
- return Db::getInstance()->update($table, $data, 'id_order='.(int)$id_order);
+ $result = Db::getInstance()->update($table, $data, 'id_order='.(int)$id_order);
}
+
+ // if automatic overbooking resolution is enabled
+ if ($result && Configuration::get('PS_OVERBOOKING_AUTO_RESOLVE') && $is_refunded) {
+ // if room is getting free and this room is not already in back order then resolve the overbookings for this free room
+ $this->resolveOverBookings();
+ }
+
return $result;
}
@@ -3007,4 +3032,191 @@ class HotelBookingDetail extends ObjectModel
return false;
}
+
+ /**
+ * Get overbooked rooms in the order|hotel
+ * @param [int] $idOrder : id of the order
+ * @param [int] $idHotel : id of the hotel
+ * @param [string] $dateFrom
+ * @param [string] $dateTo
+ * @param [int] $datewiseBreakup : send 1 to get overbooked rooms in datewise breakup
+ * @param [int] $roomCount : send 1 to get the count of the rooms overbooked only
+ * @param [int] $bookedRoomFlag : send 0 for no action | send 1 to get booked room info | send 2 to get overbooked rooms which are free
+ *
+ * @return array | integer : array of overbooked rooms | count of overbooked rooms
+ */
+ public function getOverbookedRooms(
+ $idOrder = 0,
+ $idHotel = 0,
+ $dateFrom = '',
+ $dateTo = '',
+ $datewiseBreakup = 0,
+ $roomCount = 0,
+ $bookedRoomInfoFlag = 0
+ ) {
+ $result = array();
+
+ $sql = 'SELECT';
+ if ($roomCount) {
+ $sql .= ' COUNT(*)';
+ } else {
+ $sql .= ' *';
+ }
+
+ $sql .= ' FROM `'._DB_PREFIX_.'htl_booking_detail` WHERE `is_back_order` = 1 AND `is_refunded` = 0 AND `is_cancelled` = 0';
+
+ if ($idOrder) {
+ $sql .= ' AND `id_order` = '.(int) $idOrder;
+ }
+ if ($idHotel) {
+ $sql .= ' AND `id_hotel` = '.(int) $idHotel;
+ }
+
+ if ($datewiseBreakup && $dateFrom && $dateTo) {
+ for ($currentDate = $dateFrom; $currentDate < $dateTo; $currentDate = date('Y-m-d', strtotime('+1 day', strtotime($currentDate)))) {
+ $dateSql = $sql . ' AND `date_from` <= \''.pSQL($currentDate).'\' AND `date_to` > \''.pSQL($currentDate).'\'';
+
+ if ($roomCount) {
+ $result[$currentDate] = Db::getInstance()->getValue($dateSql);
+ } else {
+ $result[$currentDate] = Db::getInstance()->executeS($dateSql);
+ }
+ }
+ } else {
+ if ($dateFrom && $dateTo) {
+ $sql .= ' AND `date_from` < \''.pSQL($dateTo).'\' AND `date_to` > \''.pSQL($dateFrom).'\'';
+ }
+
+ if ($roomCount) {
+ $result = Db::getInstance()->getValue($sql);
+ } else {
+ $result = Db::getInstance()->executeS($sql);
+ }
+ }
+
+ if ($bookedRoomInfoFlag && !$roomCount && $result) {
+ $link = new Link();
+ foreach ($result as $key => $bookingInfo) {
+ $result[$key]['booked_room_info'] = $this->chechRoomBooked($bookingInfo['id_room'], $bookingInfo['date_from'], $bookingInfo['date_to']);
+ $result[$key]['orders_filter_link'] = $link->getAdminLink('AdminOrders');
+
+ // if need only rooms which are available to resolve overbooking the unset booked rooms
+ if ($bookedRoomInfoFlag == 2 && $result[$key]['booked_room_info']) {
+ unset($result[$key]);
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get all the orders which are in overbooking
+ * @param integer $onlyFutureDates : for orders which bookings dates are in future
+ * @return array
+ */
+ public function getOverBookedOrders($onlyFutureDates = 0)
+ {
+ $sql = 'SELECT DISTINCT `id_order` FROM `'._DB_PREFIX_.'htl_booking_detail` WHERE `is_back_order` = 1 AND `is_refunded` = 0 AND `is_cancelled` = 0';
+
+ if ($onlyFutureDates) {
+ $sql .= ' AND `date_to` > \''.pSQL(date('Y-m-d')).'\'';
+ }
+ $sql .= ' ORDER BY `id_order` ASC';
+
+ $result = Db::getInstance()->executeS($sql);
+
+ return array_column($result, 'id_order');
+ }
+
+ // Resolve overbookings by checking current available rooms
+ // Overbookings resolution will only be done if all overbookings are getting resolved in the order
+ public function resolveOverBookings($idHotelBooking = 0)
+ {
+ $result = false;
+
+ $overBookedOrders = array();
+ if ($idHotelBooking) {
+ if (Validate::isLoadedObject($objHtlBookingDetail = new HotelBookingDetail($idHotelBooking))) {
+ $overBookedOrders = array($objHtlBookingDetail->id_order);
+ }
+ } else {
+ $overBookedOrders = $this->getOverBookedOrders(1);
+ }
+
+ if ($overBookedOrders) {
+ foreach ($overBookedOrders as $idOrder) {
+ // get all overbooked rooms in the order so that we can decide status of the order after overbooking resolved
+ $overBookedRooms = $this->getOverbookedRooms($idOrder);
+ $totalOverBookedInOrder = count($overBookedRooms);
+
+ // if request for specific booking resolve
+ if ($idHotelBooking) {
+ $overBookedRooms = array((array)($objHtlBookingDetail));
+ }
+
+ if ($overBookedRooms) {
+ $resolvableOverbookings = array();
+ foreach($overBookedRooms as $roomBooking) {
+ $params = array(
+ 'idHotel' => $roomBooking['id_hotel'],
+ 'dateFrom' => $roomBooking['date_from'],
+ 'dateTo' => $roomBooking['date_to'],
+ 'idRoomType' => $roomBooking['id_product'],
+ 'searchOccupancy' => 0,
+ 'allowedIdRoomTypes' => implode(",", array($roomBooking['id_product']))
+ );
+
+ if ($availableRooms = $this->getSearchAvailableRooms($params)) {
+ if (isset($availableRooms['availableRoomTypes']['roomTypes'][$roomBooking['id_product']]['rooms'])
+ && $availableRooms['availableRoomTypes']['roomTypes'][$roomBooking['id_product']]['rooms']
+ ) {
+ $availableRoomsInfo = $availableRooms['availableRoomTypes']['roomTypes'][$roomBooking['id_product']]['rooms'];
+ if ($roomIdsAvailable = array_column($availableRoomsInfo, 'id_room')) {
+ // If room is still there in the available rooms list then we can resolve its overbooking
+ if (in_array($roomBooking['id_room'], $roomIdsAvailable)) {
+ $resolvableOverbookings[] = $roomBooking['id'];
+ }
+ }
+ }
+ }
+ }
+
+ // if request for specific booking Or all overbooked rooms are resolved then resolve the overbooking by setting is_back_order to 0
+ if ($idHotelBooking || (count($resolvableOverbookings) == $totalOverBookedInOrder)) {
+ foreach ($resolvableOverbookings as $idHtlBookingDtl) {
+ $objBookingDetail = new HotelBookingDetail($idHtlBookingDtl);
+ $objBookingDetail->is_back_order = 0;
+ $objBookingDetail->update();
+
+ $result = true;
+ }
+
+ // After all overbookings are resolved we can update the status of the order
+ if (count($resolvableOverbookings) == $totalOverBookedInOrder) {
+ $objOrder = new Order($idOrder);
+ $idOrderState = 0;
+ if ($objOrder->current_state == Configuration::get('PS_OS_OVERBOOKING_PAID')) {
+ $idOrderState = Configuration::get('PS_OS_PAYMENT_ACCEPTED');
+ } elseif ($objOrder->current_state == Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID')) {
+ $idOrderState = Configuration::get('PS_OS_PARTIAL_PAYMENT_ACCEPTED');
+ } elseif ($objOrder->current_state == Configuration::get('PS_OS_OVERBOOKING_UNPAID')) {
+ $idOrderState = Configuration::get('PS_OS_AWAITING_PAYMENT');
+ }
+
+ // if we have order state to change
+ if ($idOrderState) {
+ $objOrderHistory = new OrderHistory();
+ $objOrderHistory->id_order = (int)$idOrder;
+ $objOrderHistory->changeIdOrderState((int)$idOrderState, $objOrder, true);
+ $objOrderHistory->add();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return $result;
+ }
}
diff --git a/themes/hotel-reservation-theme/history.tpl b/themes/hotel-reservation-theme/history.tpl
index 4944af2e7..19af36c2c 100644
--- a/themes/hotel-reservation-theme/history.tpl
+++ b/themes/hotel-reservation-theme/history.tpl
@@ -84,7 +84,11 @@
{if isset($order.order_state)}
- {$order.order_state|escape:'html':'UTF-8'}
+ {if $order.current_state|in_array:$overbooking_order_states}
+ {l s='Order Not Confirmed'}
+ {else}
+ {$order.order_state|escape:'html':'UTF-8'}
+ {/if}
{/if}
|
diff --git a/themes/hotel-reservation-theme/order-detail.tpl b/themes/hotel-reservation-theme/order-detail.tpl
index f5ea4a25c..978f6672b 100644
--- a/themes/hotel-reservation-theme/order-detail.tpl
+++ b/themes/hotel-reservation-theme/order-detail.tpl
@@ -76,7 +76,15 @@
{foreach from=$order_history item=state name="orderStates"}
| {dateFormat date=$state.date_add full=0} |
- {$state.ostate_name|escape:'html':'UTF-8'} |
+
+
+ {if $state.id_order_state|in_array:$overbooking_order_states}
+ {l s='Order Not Confirmed'}
+ {else}
+ {$state.ostate_name|escape:'html':'UTF-8'}
+ {/if}
+
+ |
{/foreach}
|