diff --git a/admin/themes/default/template/controllers/orders/_product_line.tpl b/admin/themes/default/template/controllers/orders/_product_line.tpl index 6247eb54e..18ceebacc 100644 --- a/admin/themes/default/template/controllers/orders/_product_line.tpl +++ b/admin/themes/default/template/controllers/orders/_product_line.tpl @@ -227,27 +227,34 @@
- - - + {if isset($refundReqBookings) && $refundReqBookings && $data.id|in_array:$refundReqBookings && $data.is_cancelled} + + {else} + + + + {/if}
{/if} diff --git a/admin/themes/default/template/controllers/orders/form.tpl b/admin/themes/default/template/controllers/orders/form.tpl index 933d0a6cc..66ab9c223 100644 --- a/admin/themes/default/template/controllers/orders/form.tpl +++ b/admin/themes/default/template/controllers/orders/form.tpl @@ -139,6 +139,7 @@ $('body').on('click', '.delete_hotel_cart_data', function(){ if (confirm("{l s='Are you sure?'}")) { + var idCart = $(this).data('id_cart'); $.ajax({ type:"POST", url: "{$link->getAdminLink('AdminOrders')|addslashes}", @@ -147,7 +148,7 @@ action: "deleteRoomProcess", del_id: $(this).data('id'), id_product: $(this).data('id_product'), - id_cart: $(this).data('id_cart'), + id_cart: idCart, id_room: $(this).data('id_room'), date_from: $(this).data('date_from'), date_to: $(this).data('date_to'), @@ -159,7 +160,7 @@ { showSuccessMessage("{l s='Remove successful'}"); if (data.cart_rooms) - location.reload(); + window.location.href = "{$link->getAdminLink('AdminOrders',true)}" + '&addorder&cart_id=' + idCart; else window.location.href = "{$link->getAdminLink('AdminHotelRoomsBooking',true)}"; } @@ -1731,539 +1732,540 @@
{block name="leadin"}{/block}
{include file='controllers/orders/_current_cart_details_data.tpl'} -
-
- - {l s='Customer'} -
-
- -
-
-
-
- - - - -
-
- -
-
-
-
-
-
- {*
- + {* If cart has errors the do not allow to proceed with this cart *} +
+
+ + {l s='Customer'} +
+
+ +
+
+
+
+ + + + +
+
+ +
+
+
+
+
+
+ {*
+ - -
-
- - - - - - - - - - - -
{l s='ID'}{l s='Date'}{l s='Total'}
-
-
- - - - - - - - - - - - - - -
{l s='ID'}{l s='Date'}{l s='Products'}{l s='Total paid'}{l s='Payment'}{l s='Status'}
-
-
-
-->*} -
+ +
+
+ + + + + + + + + + + +
{l s='ID'}{l s='Date'}{l s='Total'}
+
+
+ + + + + + + + + + + + + + +
{l s='ID'}{l s='Date'}{l s='Products'}{l s='Total paid'}{l s='Payment'}{l s='Status'}
+
+
+
-->*} +
- + {strip} {addJsDef max_child_age=$max_child_age} {addJsDef max_child_in_room=$max_child_in_room} diff --git a/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl b/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl index 444182bab..e3cf64089 100644 --- a/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl +++ b/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl @@ -33,17 +33,25 @@
- -
+ {if isset($refundReqBookings) && $refundReqBookings && $data.id|in_array:$refundReqBookings && $data.is_refunded} + {dateFormat date=$data.date_from} + {else} + +
+ {/if}
- -
+ {if isset($refundReqBookings) && $refundReqBookings && $data.id|in_array:$refundReqBookings && $data.is_refunded} + {dateFormat date=$data.date_to} + {else} + +
+ {/if}
diff --git a/admin/themes/default/template/helpers/list/list_header.tpl b/admin/themes/default/template/helpers/list/list_header.tpl index c09153623..3b180415e 100644 --- a/admin/themes/default/template/helpers/list/list_header.tpl +++ b/admin/themes/default/template/helpers/list/list_header.tpl @@ -557,10 +557,11 @@ diff --git a/classes/Address.php b/classes/Address.php index 9d1b583dd..10c3cf0c4 100644 --- a/classes/Address.php +++ b/classes/Address.php @@ -483,6 +483,14 @@ class AddressCore extends ObjectModel return array(); } + public function cacheFieldsRequiredDatabase($all = false) + { + parent::cacheFieldsRequiredDatabase($all); + if ($this->id_hotel) { + self::$fieldsRequiredDatabase['Address'] = array(); + } + } + public function searchByName($query, $idLang = false) { if (!$idLang) { diff --git a/classes/Cart.php b/classes/Cart.php index 7500dd21e..6bd68b361 100644 --- a/classes/Cart.php +++ b/classes/Cart.php @@ -374,7 +374,7 @@ class CartCore extends ObjectModel if ($cart_vat_amount == 0 || $cart_amount_te == 0) { return 0; } else { - return Tools::ps_round($cart_vat_amount / $cart_amount_te, 3); + return Tools::ps_round($cart_vat_amount / $cart_amount_te, 6); } } diff --git a/classes/CartRule.php b/classes/CartRule.php index f48ffb3b1..634434e53 100644 --- a/classes/CartRule.php +++ b/classes/CartRule.php @@ -294,6 +294,13 @@ class CartRuleCore extends ObjectModel return array(); } + // Remove cart rule that does not match the id_customer + foreach ($result as $key => $cart_rule) { + if ($cart_rule['id_customer'] && $cart_rule['id_customer'] != $id_customer) { + unset($result[$key]); + } + } + // Remove cart rule that does not match the customer groups $customerGroups = Customer::getGroupsStatic($id_customer); @@ -1154,6 +1161,18 @@ class CartRuleCore extends ObjectModel $previous_reduction_amount = $prorata * $previous_reduction_amount * (1 + $cart_average_vat_rate); } + // First we convert the voucher value to the default currency + $previousCartRuleCurrency = new Currency($this->reduction_currency); + + if ($previous_reduction_amount == 0 || $previousCartRuleCurrency->conversion_rate == 0) { + $previous_reduction_amount = 0; + } else { + $previous_reduction_amount /= $previousCartRuleCurrency->conversion_rate; + } + + // Then we convert the voucher value in the default currency into the cart currency + $previous_reduction_amount *= $context->currency->conversion_rate; + $previous_reduction_amount = Tools::ps_round($previous_reduction_amount, _PS_PRICE_COMPUTE_PRECISION_); $current_cart_amount = max($current_cart_amount - (float)$previous_reduction_amount, 0); } diff --git a/classes/controller/AdminController.php b/classes/controller/AdminController.php index 4fd5dbd83..ea0c1ffa0 100644 --- a/classes/controller/AdminController.php +++ b/classes/controller/AdminController.php @@ -2313,6 +2313,7 @@ class AdminControllerCore extends Controller public function ajaxProcessRefreshModuleList($force_reload_cache = false) { $this->status = Module::refreshModuleList($force_reload_cache); + $this->ajaxDie(json_encode(array('status' => $this->status))); } /** diff --git a/classes/order/Order.php b/classes/order/Order.php index a4e7a5e6b..74fc0a450 100644 --- a/classes/order/Order.php +++ b/classes/order/Order.php @@ -797,8 +797,9 @@ class OrderCore extends ObjectModel public function getTaxesAverageUsed() { - // @todo should use order table to get tax average - return Cart::getTaxesAverageUsed((int)$this->id_cart); + $cart = new Cart((int) $this->id_cart); + + return $cart->getAverageProductsTaxRate() * 100; } /** @@ -2687,4 +2688,133 @@ class OrderCore extends ObjectModel { $this->transaction_id = $transactionId; } + + /** + * Validate and change order status + * @return array of status, errors, has_mail_error(if order status is changes but mail error occurs while sending mail) + */ + public function ChangeOrderStatus() + { + $result = array(); + $result['status'] = false; + $result['has_mail_error'] = false; + $result['errors'] = array(); + $objNewOrderState = new OrderState(Tools::getValue('id_order_state')); + if (!Validate::isLoadedObject($objNewOrderState)) { + $result['errors'][] = Tools::displayError('The new order status is invalid.'); + } else { + $objHotelBooking = new HotelBookingDetail(); + $objCurrentOrderState = $this->getCurrentOrderState(); + + if ($objCurrentOrderState->id == Configuration::get('PS_OS_REFUND')) { + $result['errors'][] = Tools::displayError('Order status can not be changed once order status is set to Refunded.'); + } elseif ($objCurrentOrderState->id == Configuration::get('PS_OS_CANCELED')) { + $result['errors'][] = Tools::displayError('Order status can not be changed once order status is set to Cancelled.'); + } elseif (in_array($objNewOrderState->id, array (Configuration::get('PS_OS_OVERBOOKING_PAID'), Configuration::get('PS_OS_OVERBOOKING_UNPAID'), Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID')))) { + if (!$objHotelBooking->getOverbookedRooms($this->id)) { + $result['errors'][] = Tools::displayError('Order status can not be changed to any overbooking status as there are no overbooked rooms in the order.'); + } + } elseif ($objNewOrderState->id == Configuration::get('PS_OS_REFUND') + && !$this->hasCompletelyRefunded(Order::ORDER_COMPLETE_REFUND_FLAG) + ) { + $result['errors'][] = Tools::displayError('Order status can not be set to Refunded until all bookings in the order are completely refunded.'); + } elseif ($objNewOrderState->id == Configuration::get('PS_OS_CANCELED') + && !$this->hasCompletelyRefunded(Order::ORDER_COMPLETE_CANCELLATION_FLAG) + ) { + $result['errors'][] = Tools::displayError('Order status can not be set to Cancelled until all bookings in the order are cancelled.'); + } elseif ($objCurrentOrderState->id == Configuration::get('PS_OS_ERROR') && !($objNewOrderState->id == Configuration::get('PS_OS_ERROR'))) { + // All rooms must be available before changing status from Payment Error to Other status in which rooms are getting blocked again + if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) { + foreach ($orderBookings as $orderBooking) { + // If booking is refunded then no need to check inventory + if ((OrderReturn::getOrdersReturnDetail($this->id, 0, $orderBooking['id']) && $orderBooking['is_refunded']) + || ($orderBooking['is_cancelled'] && $orderBooking['is_refunded']) + ) { + continue; + } else { + // if inventory is available for that booking + $bookingParams = array( + 'date_from' => $orderBooking['date_from'], + 'date_to' => $orderBooking['date_to'], + 'hotel_id' => $orderBooking['id_hotel'], + 'id_room_type' => $orderBooking['id_product'], + 'only_search_data' => 1 + ); + + $objHotelBookingDetail = new HotelBookingDetail($orderBooking['id']); + if ($searchRoomsInfo = $objHotelBooking->getBookingData($bookingParams)) { + if (isset($searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available']) + && $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available'] + ) { + $availableRoomsInfo = $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available']; + if ($roomIdsAvailable = array_column($availableRoomsInfo, 'id_room')) { + // Check If room is still there in the available rooms list + if (!in_array($orderBooking['id_room'], $roomIdsAvailable)) { + $result['errors'][] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.'); + + break; + } else { + $objHotelBookingDetail->is_refunded = 0; + $objHotelBookingDetail->save(); + } + } else { + $result['errors'][] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.'); + break; + } + } + } else { + $result['errors'][] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.'); + + break; + } + } + } + } + } elseif ($objCurrentOrderState->id == $objNewOrderState->id) { + $result['errors'][] = Tools::displayError('The order has already been assigned this status.'); + } + } + + if (!count($result['errors'])) { + // Create new OrderHistory + $context = Context::getContext(); + $history = new OrderHistory(); + $history->id_order = $this->id; + $history->id_employee = (int)$context->employee->id; + + $useExistingsPayment = false; + if (!$this->hasInvoice()) { + $useExistingsPayment = true; + } + $history->changeIdOrderState((int)$objNewOrderState->id, $this, $useExistingsPayment); + + // Save all changes + $templateVars = array(); + if ($history->add(true)) { + if (!$history->sendEmail($this, $templateVars)) { + // if an error occurred while sending an email the set has_mail_error to true + $result['has_mail_error'] = true; + $result['errors'][] = Tools::displayError('We were unable to send an email to the customer while changing order status.'); + } + + // synchronizes quantities if needed.. + if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { + foreach ($this->getProducts() as $product) { + if (StockAvailable::dependsOnStock($product['product_id'])) { + StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']); + } + } + } + } else { + $result['errors'][] = Tools::displayError('An error occurred while changing order status.'); + } + } + + // if no errors then return status true + if (!count($result['errors'])) { + $result['status'] = true; + } + + return $result; + } } diff --git a/controllers/admin/AdminCartsController.php b/controllers/admin/AdminCartsController.php index 108b51a75..3f3798675 100644 --- a/controllers/admin/AdminCartsController.php +++ b/controllers/admin/AdminCartsController.php @@ -42,11 +42,11 @@ class AdminCartsControllerCore extends AdminController $this->allow_export = true; $this->_orderWay = 'DESC'; $this->context = Context::getContext(); - $this->_select = 'CONCAT(c.`firstname`, \' \', c.`lastname`) `customer`, a.id_cart total, TIME_TO_SEC(TIMEDIFF(\''.pSQL(date('Y-m-d H:i:00', time())).'\', a.`date_add`)) AS `time_diff`, + IFNULL(GROUP_CONCAT(DISTINCT o.`id_order`), 0) AS `ids_order`, - IF (IFNULL(o.id_order, \''.$this->l('Non ordered cart').'\') = \''.$this->l('Non ordered cart').'\', IF(TIME_TO_SEC(TIMEDIFF(\''.pSQL(date('Y-m-d H:i:00', time())).'\', a.`date_add`)) > 86400, \''.$this->l('Abandoned cart').'\', \''.$this->l('Non ordered cart').'\'), GROUP_CONCAT(DISTINCT o.`id_order`)) AS filter_ids_order, + IF (IFNULL(o.id_order, \''.$this->l('Non ordered cart').'\') = \''.$this->l('Non ordered cart').'\', IF(TIME_TO_SEC(TIMEDIFF(\''.pSQL(date('Y-m-d H:i:00', time())).'\', a.`date_add`)) > '._TIME_1_DAY_.', \''.$this->l('Abandoned cart').'\', \''.$this->l('Non ordered cart').'\'), GROUP_CONCAT(DISTINCT o.`id_order`)) AS filter_ids_order, IF(o.id_order, 1, 0) badge_success, IF(o.id_order, 0, 1) badge_danger, IF(co.id_guest, 1, 0) id_guest'; $this->_join = 'LEFT JOIN '._DB_PREFIX_.'customer c ON (c.id_customer = a.id_customer) LEFT JOIN '._DB_PREFIX_.'currency cu ON (cu.id_currency = a.id_currency) @@ -54,10 +54,6 @@ class AdminCartsControllerCore extends AdminController LEFT JOIN `'._DB_PREFIX_.'connections` co ON (a.id_guest = co.id_guest AND TIME_TO_SEC(TIMEDIFF(\''.pSQL(date('Y-m-d H:i:00', time())).'\', co.`date_add`)) < 1800)'; $this->_group = ' GROUP BY a.`id_cart`'; - if (Tools::getValue('action') == 'filterOnlyAbandonedCarts') { - $this->_filterHaving = ' AND `ids_order` = 0 AND `time_diff` > 86400'; - } - $this->fields_list = array( 'id_cart' => array( 'title' => $this->l('ID'), @@ -96,7 +92,7 @@ class AdminCartsControllerCore extends AdminController 'type' => 'bool', 'havingFilter' => true, 'class' => 'fixed-width-xs', - 'icon' => array(0 => 'icon-', 1 => 'icon-user') + 'callback' => 'getOnlineStatus', ) ); $this->shopLinkType = 'shop'; @@ -117,10 +113,32 @@ class AdminCartsControllerCore extends AdminController } parent::__construct(); - $this->list_no_link = true; } + public function postProcess() + { + if (Tools::getValue('action') == 'filterOnlyAbandonedCarts') { + $this->processResetFilters(); + $this->context->cookie->{'submitFilter'.$this->table} = true; + $prefix = $this->getCookieFilterPrefix(); + $this->context->cookie->{$prefix.$this->table.'Filter_filter_ids_order'} = $this->l('Abandoned cart'); + if (($dateFrom = Tools::getValue('date_from')) + && ($dateTo = Tools::getValue('date_to')) + && strtotime($dateTo) >= strtotime($dateFrom) + ) { + //Updating the date format of the filter dates to the required format. + $dateFrom = date('Y-m-d', strtotime($dateFrom)); + $dateTo = date('Y-m-d', strtotime($dateTo)); + $this->context->cookie->{$prefix.$this->table.'Filter_'.$this->fields_list['date_add']['filter_key']} = json_encode(array($dateFrom, $dateTo)); + } + + $this->redirect_after = $this->context->link->getAdminLink('AdminCarts'); + } + + parent::postProcess(); + } + public function getOrderColumn($idsOrder, $tr) { $smartyVars = array(); @@ -129,7 +147,7 @@ class AdminCartsControllerCore extends AdminController $smartyVars['type'] = 'orders'; $smartyVars['ids_order'] = $idsOrder; } else { - if ($tr['time_diff'] > 86400) { + if ($tr['time_diff'] > _TIME_1_DAY_) { $smartyVars['type'] = 'abandoned'; } else { $smartyVars['type'] = 'non_orderd'; @@ -143,6 +161,11 @@ class AdminCartsControllerCore extends AdminController return $tpl->fetch(); } + public function getOnlineStatus($status) + { + return $status ? $this->l('Yes') : $this->l('No'); + } + public function initPageHeaderToolbar() { if (empty($this->display)) { @@ -184,7 +207,7 @@ class AdminCartsControllerCore extends AdminController $date_from = date(Context::getContext()->language->date_format_lite, strtotime('-2 day')); $date_to = date(Context::getContext()->language->date_format_lite, strtotime('-1 day')); $helper->subtitle = sprintf($this->l('From %s to %s', null, null, false), $date_from, $date_to); - $helper->href = $this->context->link->getAdminLink('AdminCarts').'&action=filterOnlyAbandonedCarts'; + $helper->href = $this->context->link->getAdminLink('AdminCarts').'&action=filterOnlyAbandonedCarts&date_from='.$date_from.'&date_to='.$date_to; $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=abandoned_cart'; $kpis[] = $helper; diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index c08b5f111..d56966e0c 100644 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -285,11 +285,6 @@ class AdminOrdersControllerCore extends AdminController 'payment' => array( 'title' => $this->l('Payment') ), - 'currency' => array( - 'title' => $this->l('Order Currency'), - 'hint' => $this->l('This is the currency in which customer created the order.'), - 'havingFilter' => true, - ), 'order_source' => array( 'title' => $this->l('Order Source'), 'type' => 'select', @@ -374,36 +369,17 @@ class AdminOrdersControllerCore extends AdminController $this->errors[] = $this->l('You have to select a shop before creating new orders.'); } - $id_cart = (int)Tools::getValue('id_cart'); - $cart = new Cart((int)$id_cart); - if ($id_cart && !Validate::isLoadedObject($cart)) { - $this->errors[] = $this->l('This cart does not exists'); - } - if ($id_cart && Validate::isLoadedObject($cart) && !$cart->id_customer) { - $this->errors[] = $this->l('The cart must have a customer'); - } - if (count($this->errors) && !Tools::getValue('submitAddorder')) { - return false; - } - - // check page is whether ad new order page or order detail page - if ((Tools::isSubmit('addorder') && ($id_cart = Tools::getValue('cart_id'))) - || (Tools::isSubmit('submitAddOrder') && ($id_cart = Tools::getValue('id_cart'))) - ) { + // check page is new order creation page and cart id is set + if (Tools::isSubmit('addorder') && ($id_cart = Tools::getValue('cart_id'))) { // set smarty variables if new order creation process has errors $cart = new Cart($id_cart); $cart_order_exists = $cart->orderExists(); if (!$cart_order_exists) { $this->context->cart = $cart; - if ($this->context->employee->isSuperAdmin()) { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; - } else { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; - } - if (!Configuration::get($backOrderConfigKey)) { - $objHotelCartBookingData = new HotelCartBookingData(); - $objHotelCartBookingData->removeBackdateRoomsFromCart($this->context->cart->id); - } + + // validate cart for removing invalid data from cart before new order creation + $this->errors = array_merge($this->errors, HotelCartBookingData::validateCartBookings()); + $this->context->currency = new Currency((int)$cart->id_currency); $cart_detail_data = array(); $cart_detail_data_obj = new HotelCartBookingData(); @@ -420,61 +396,68 @@ class AdminOrdersControllerCore extends AdminController $this->context->smarty->assign('cart_normal_data', $normalCartProduct); } + if (empty($cart_detail_data) && empty($normalCartProduct)) { + // if no rooms added in the cart and user visits add order page then redirect to BOOK NOW page + Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); + } + + $payment_modules = array(); + foreach (PaymentModule::getInstalledPaymentModules() as $p_module) { + $payment_modules[] = Module::getInstanceById((int)$p_module['id_module']); + } + + $paymentTypes = array(); + foreach ($this->getPaymentsTypes() as $paymentType) { + if ($paymentType['value'] != OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT) { + $paymentTypes[] = $paymentType; + } + } + + $occupancyRequiredForBooking = false; + if (Configuration::get('PS_BACKOFFICE_ROOM_BOOKING_TYPE') == HotelBookingDetail::PS_ROOM_UNIT_SELECTION_TYPE_OCCUPANCY) { + $occupancyRequiredForBooking = true; + } + $objHotelAdvancedPayment = new HotelAdvancedPayment(); $this->context->smarty->assign(array( 'order_total' => $cart->getOrderTotal(true), 'is_advance_payment_active' => $objHotelAdvancedPayment->isAdvancePaymentAvailableForCurrentCart(), 'advance_payment_amount_without_tax' => $cart->getOrderTotal(false, Cart::ADVANCE_PAYMENT), 'advance_payment_amount_with_tax' => $cart->getOrderTotal(true, Cart::ADVANCE_PAYMENT), + 'cart' => $cart, + 'currencies' => Currency::getCurrenciesByIdShop(Context::getContext()->shop->id), + 'langs' => Language::getLanguages(true, Context::getContext()->shop->id), + 'payment_modules' => $payment_modules, + 'payment_types' => $paymentTypes, + 'currency' => new Currency((int)$cart->id_currency), + 'max_child_in_room' => Configuration::get('WK_GLOBAL_MAX_CHILD_IN_ROOM'), + 'max_child_age' => Configuration::get('WK_GLOBAL_CHILD_MAX_AGE'), + 'occupancy_required_for_booking' => $occupancyRequiredForBooking, )); - if (empty($cart_detail_data) && empty($normalCartProduct)) { - // if no rooms added in the cart and user visits add order page then redirect to BOOK NOW page - Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); - } + } else { + Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); } $this->context->smarty->assign('is_order_created', $cart_order_exists); + } else { + Tools::redirectAdmin($this->context->link->getAdminLink('AdminHotelRoomsBooking')); } + //end parent::renderForm(); unset($this->toolbar_btn['save']); $this->addJqueryPlugin(array('autocomplete', 'fancybox', 'typewatch')); - $payment_modules = array(); - foreach (PaymentModule::getInstalledPaymentModules() as $p_module) { - $payment_modules[] = Module::getInstanceById((int)$p_module['id_module']); - } - - $paymentTypes = array(); - foreach ($this->getPaymentsTypes() as $paymentType) { - if ($paymentType['value'] != OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT) { - $paymentTypes[] = $paymentType; - } - } - - $occupancyRequiredForBooking = false; - if (Configuration::get('PS_BACKOFFICE_ROOM_BOOKING_TYPE') == HotelBookingDetail::PS_ROOM_UNIT_SELECTION_TYPE_OCCUPANCY) { - $occupancyRequiredForBooking = true; - } - $this->context->smarty->assign(array( 'recyclable_pack' => (int)Configuration::get('PS_RECYCLABLE_PACK'), 'gift_wrapping' => (int)Configuration::get('PS_GIFT_WRAPPING'), - 'cart' => $cart, - 'currencies' => Currency::getCurrenciesByIdShop(Context::getContext()->shop->id), - 'langs' => Language::getLanguages(true, Context::getContext()->shop->id), - 'payment_modules' => $payment_modules, - 'payment_types' => $paymentTypes, 'show_toolbar' => $this->show_toolbar, 'toolbar_btn' => $this->toolbar_btn, 'toolbar_scroll' => $this->toolbar_scroll, 'PS_CATALOG_MODE' => Configuration::get('PS_CATALOG_MODE'), 'title' => array($this->l('Orders'), $this->l('Create order')), - 'currency' => new Currency((int)$cart->id_currency), - 'max_child_in_room' => Configuration::get('WK_GLOBAL_MAX_CHILD_IN_ROOM'), - 'max_child_age' => Configuration::get('WK_GLOBAL_CHILD_MAX_AGE'), - 'occupancy_required_for_booking' => $occupancyRequiredForBooking, )); + $this->content .= $this->createTemplate('form.tpl')->fetch(); } @@ -927,6 +910,10 @@ class AdminOrdersControllerCore extends AdminController $smartyVars['roomTypeServiceProducts'] = $roomTypeServiceProducts; } + $objOrderReturn = new OrderReturn(); + $refundReqBookings = $objOrderReturn->getOrderRefundRequestedBookings($objOrder->id, 0, 1); + $smartyVars['refundReqBookings'] = $refundReqBookings; + $this->context->smarty->assign($smartyVars); $modal = array( @@ -1057,28 +1044,13 @@ class AdminOrdersControllerCore extends AdminController if (!Validate::isLoadedObject($order)) { $this->errors[] = sprintf(Tools::displayError('Order #%d cannot be loaded'), $id_order); } else { - $current_order_state = $order->getCurrentOrderState(); - if ($current_order_state->id == $order_state->id) { - $this->errors[] = $this->displayWarning(sprintf('Order #%d has already been assigned this status.', $id_order)); - } else { - $history = new OrderHistory(); - $history->id_order = $order->id; - $history->id_employee = (int)$this->context->employee->id; - - $use_existings_payment = !$order->hasInvoice(); - $history->changeIdOrderState((int)$order_state->id, $order, $use_existings_payment); - - $carrier = new Carrier($order->id_carrier, $order->id_lang); - $templateVars = array(); - - if ($history->addWithemail(true, $templateVars)) { - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - foreach ($order->getProducts() as $product) { - if (StockAvailable::dependsOnStock($product['product_id'])) { - StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']); - } - } - } + $result = $order->changeOrderStatus(); + if (!$result['status']) { + if (isset($result['has_mail_error']) && $result['has_mail_error']) { + $this->errors[] = sprintf( + Tools::displayError('Unable to send email to the customer while changing order status for order #%d.'), + $id_order + ); } else { $this->errors[] = sprintf(Tools::displayError('Cannot change status for order #%d.'), $id_order); } @@ -1087,6 +1059,7 @@ class AdminOrdersControllerCore extends AdminController } } } + if (!count($this->errors)) { Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$this->token); } @@ -1292,115 +1265,11 @@ class AdminOrdersControllerCore extends AdminController /* Change order status, add a new entry in order history and send an e-mail to the customer if needed */ elseif (Tools::isSubmit('submitState') && isset($order)) { if ($this->tabAccess['edit'] === '1') { - $order_state = new OrderState(Tools::getValue('id_order_state')); - - if (!Validate::isLoadedObject($order_state)) { - $this->errors[] = Tools::displayError('The new order status is invalid.'); + $result = $order->changeOrderStatus(); + if ($result['status']) { + Tools::redirectAdmin(self::$currentIndex.'&id_order='.(int)$order->id.'&conf=5&vieworder&token='.$this->token); } else { - $current_order_state = $order->getCurrentOrderState(); - - if ($current_order_state->id == Configuration::get('PS_OS_REFUND')) { - $this->errors[] = Tools::displayError('Order status can not be changed once order status is set to Refunded.'); - } elseif ($current_order_state->id == Configuration::get('PS_OS_CANCELED')) { - $this->errors[] = Tools::displayError('Order status can not be changed once order status is set to Cancelled.'); - } elseif (in_array($order_state->id, array (Configuration::get('PS_OS_OVERBOOKING_PAID'), Configuration::get('PS_OS_OVERBOOKING_UNPAID'), Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID')))) { - $objHotelBooking = new HotelBookingDetail(); - if (!$objHotelBooking->getOverbookedRooms($order->id)) { - $this->errors[] = Tools::displayError('Order status can not be changed to any overbooking status as there are no overbooked rooms in the order.'); - } - } elseif ($order_state->id == Configuration::get('PS_OS_REFUND') - && !$order->hasCompletelyRefunded(Order::ORDER_COMPLETE_REFUND_FLAG) - ) { - $this->errors[] = Tools::displayError('Order status can not be set to Refunded until all bookings in the order are completely refunded.'); - } elseif ($order_state->id == Configuration::get('PS_OS_CANCELED') - && !$order->hasCompletelyRefunded(Order::ORDER_COMPLETE_CANCELLATION_FLAG) - ) { - $this->errors[] = Tools::displayError('Order status can not be set to Cancelled until all bookings in the order are cancelled.'); - } elseif ($current_order_state->id == Configuration::get('PS_OS_ERROR') && !($order_state->id == Configuration::get('PS_OS_ERROR'))) { - // All rooms must be available before changing status from Payment Error to Other status in which rooms are getting blocked again - $objHotelBooking = new HotelBookingDetail(); - if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($order->id)) { - foreach ($orderBookings as $orderBooking) { - // If booking is refunded then no need to check inventory - if ((OrderReturn::getOrdersReturnDetail($order->id, 0, $orderBooking['id']) && $orderBooking['is_refunded']) - || ($orderBooking['is_cancelled'] && $orderBooking['is_refunded']) - ) { - continue; - } else { - // if inventory is available for that booking - $bookingParams = array( - 'date_from' => $orderBooking['date_from'], - 'date_to' => $orderBooking['date_to'], - 'hotel_id' => $orderBooking['id_hotel'], - 'id_room_type' => $orderBooking['id_product'], - 'only_search_data' => 1 - ); - - $objHotelBookingDetail = new HotelBookingDetail($orderBooking['id']); - if ($searchRoomsInfo = $objHotelBooking->getBookingData($bookingParams)) { - if (isset($searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available']) - && $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available'] - ) { - $availableRoomsInfo = $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available']; - if ($roomIdsAvailable = array_column($availableRoomsInfo, 'id_room')) { - // Check If room is still there in the available rooms list - if (!in_array($orderBooking['id_room'], $roomIdsAvailable)) { - $this->errors[] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.'); - - break; - } else { - $objHotelBookingDetail->is_refunded = 0; - $objHotelBookingDetail->save(); - } - } else { - $this->errors[] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.'); - break; - } - } - } else { - $this->errors[] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.'); - - break; - } - } - } - } - } elseif ($current_order_state->id == $order_state->id) { - $this->errors[] = Tools::displayError('The order has already been assigned this status.'); - } - - // If no errors then we change the order status - if (!count($this->errors)) { - // Create new OrderHistory - $history = new OrderHistory(); - $history->id_order = $order->id; - $history->id_employee = (int)$this->context->employee->id; - - $use_existings_payment = false; - if (!$order->hasInvoice()) { - $use_existings_payment = true; - } - $history->changeIdOrderState((int)$order_state->id, $order, $use_existings_payment); - - $carrier = new Carrier($order->id_carrier, $order->id_lang); - $templateVars = array(); - - // Save all changes - if ($history->addWithemail(true, $templateVars)) { - // synchronizes quantities if needed.. - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - foreach ($order->getProducts() as $product) { - if (StockAvailable::dependsOnStock($product['product_id'])) { - StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']); - } - } - } - - Tools::redirectAdmin(self::$currentIndex.'&id_order='.(int)$order->id.'&conf=5&vieworder&token='.$this->token); - } - - $this->errors[] = Tools::displayError('An error occurred while changing order status, or we were unable to send an email to the customer.'); - } + $this->errors = array_merge($this->errors, $result['errors']); } } else { $this->errors[] = Tools::displayError('You do not have permission to edit this.'); @@ -1624,9 +1493,21 @@ class AdminOrdersControllerCore extends AdminController } elseif (!Validate::isUnsignedInt($payment_type)) { $this->errors[] = Tools::displayError('Payment source is invalid'); // Amount cannot be less than paid amount by guest in negative price - } elseif ($amount < 0 && ($order->total_paid_real + $amount) < 0) { - $this->errors[] = sprintf(Tools::displayError('Amount cannot be less than -%s'), Tools::displayPrice($order->total_paid_real, new Currency($order->id_currency))); - } else { + } elseif ($amount < 0) { + if ($currency->id == $order->id_currency) { + if (($order->total_paid_real + $amount) < 0) { + $this->errors[] = sprintf(Tools::displayError('Amount cannot be less than -%s'), Tools::displayPrice($order->total_paid_real, new Currency($order->id_currency))); + } + } else { + $convertedAmount = Tools::ps_round(Tools::convertPriceFull($amount, $currency, new Currency($order->id_currency)), 6); + $convertedPaidAmount = Tools::ps_round(Tools::convertPriceFull($order->total_paid_real, new Currency($order->id_currency), $currency), 6); + if (($order->total_paid_real + $convertedAmount) < 0) { + $this->errors[] = sprintf(Tools::displayError('Amount cannot be less than -%s (-%s)'), Tools::displayPrice($convertedPaidAmount, $currency), Tools::displayPrice($order->total_paid_real, new Currency($order->id_currency))); + } + } + } + + if (!count($this->errors)) { if (!$order->addOrderPayment( $amount, Tools::getValue('payment_method'), @@ -1673,6 +1554,9 @@ class AdminOrdersControllerCore extends AdminController if ($this->tabAccess['edit'] === '1') { $objCart = new Cart($id_cart); if (Validate::isLoadedObject($objCart)) { + $this->context->cart = $objCart; + + $this->errors = HotelCartBookingData::validateCartBookings(); $orderTotal = $objCart->getOrderTotal(true, Cart::BOTH); if ($objCart->is_advance_payment) { $advancePaymentAmount = $objCart->getOrderTotal(true, Cart::ADVANCE_PAYMENT); @@ -1690,7 +1574,7 @@ class AdminOrdersControllerCore extends AdminController if ($paymentAmount == '') { $this->errors[] = Tools::displayError('Please enter valid Payment amount of the order.'); } elseif ($paymentAmount && !Validate::isPrice($paymentAmount)) { - $this->errors[] = Tools::displayError('Payment amount is invalid. Please enter correct amount.'); + $this->errors[] = Tools::displayError('Payment amount is invalid. Please enter valid amount.'); } else { $paymentAmount = (float) $paymentAmount; } @@ -1717,23 +1601,6 @@ class AdminOrdersControllerCore extends AdminController } } - // Validate if booking dates are allowed - if ($this->context->employee->isSuperAdmin()) { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; - } else { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; - } - if (!Configuration::get($backOrderConfigKey)) { - $objCartBookingData = new HotelCartBookingData(); - if ($cartBookingData = $objCartBookingData->getCartCurrentDataByCartId($cart->id)) { - foreach ($cartBookingData as $cartRoom) { - if (strtotime($cartRoom['date_from']) < strtotime(date('Y-m-d'))) { - $this->errors[] = Tools::displayError('You cannot book rooms before today date.'); - } - } - } - } - if (!count($this->errors)) { $this->context->currency = new Currency((int) $objCart->id_currency); $this->context->customer = new Customer((int) $objCart->id_customer); @@ -1811,10 +1678,6 @@ class AdminOrdersControllerCore extends AdminController if ($objPaymentModule->currentOrder) { Tools::redirectAdmin(self::$currentIndex.'&id_order='.$objPaymentModule->currentOrder.'&vieworder'.'&token='.$this->token.'&conf=3'); } - } else { - // if errors render add order form - $_GET['addorder'] = '1'; - $_GET['cart_id'] = $id_cart; } } else { $this->errors[] = Tools::displayError('Cart can not be loaded.'); @@ -2045,6 +1908,41 @@ class AdminOrdersControllerCore extends AdminController } } + // update Order refund prices (order_return and order_return_detail) + if ($orderReturns = OrderReturn::getOrdersReturn($order->id_customer, $order->id)) { + $fields = array( + 'refunded_amount', + ); + foreach ($orderReturns as $orderReturn) { + $objOrderReturn = new OrderReturn($orderReturn['id_order_return']); + foreach ($fields as $field) { + $objOrderReturn->{$field} = Tools::convertPriceFull( + $objOrderReturn->{$field}, + $old_currency, + $currency + ); + } + $objOrderReturn->update(); + } + } + + if ($orderReturnDetails = OrderReturn::getOrdersReturnDetail($order->id)) { + $fields = array( + 'refunded_amount', + ); + foreach ($orderReturnDetails as $orderReturnDetail) { + $objOrderReturnDetail = new OrderReturnDetail($orderReturnDetail['id_order_return_detail']); + foreach ($fields as $field) { + $objOrderReturnDetail->{$field} = Tools::convertPriceFull( + $objOrderReturnDetail->{$field}, + $old_currency, + $currency + ); + } + $objOrderReturnDetail->update(); + } + } + // If everything is updated, then redirect to view order with success message Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token); } else { @@ -2125,7 +2023,7 @@ class AdminOrdersControllerCore extends AdminController switch (Tools::getValue('discount_type')) { // Percent type case 1: - if ($discount_value < 100) { + if ($discount_value <= 100) { if (isset($order_invoice)) { $cart_rules[$order_invoice->id]['value_tax_incl'] = Tools::ps_round($order_invoice->total_paid_tax_incl * $discount_value / 100, 2); $cart_rules[$order_invoice->id]['value_tax_excl'] = Tools::ps_round($order_invoice->total_paid_tax_excl * $discount_value / 100, 2); @@ -2217,60 +2115,62 @@ class AdminOrdersControllerCore extends AdminController $this->errors[] = Tools::displayError('The discount type is invalid.'); } - $res = true; - foreach ($cart_rules as &$cart_rule) { - $cartRuleObj = new CartRule(); - $cartRuleObj->date_from = date('Y-m-d H:i:s', strtotime('-1 hour', strtotime($order->date_add))); - $cartRuleObj->date_to = date('Y-m-d H:i:s', strtotime('+1 hour')); - $cartRuleObj->name[Configuration::get('PS_LANG_DEFAULT')] = Tools::getValue('discount_name'); - $cartRuleObj->quantity = 0; - $cartRuleObj->quantity_per_user = 1; - if (Tools::getValue('discount_type') == 1) { - $cartRuleObj->reduction_percent = $discount_value; - } elseif (Tools::getValue('discount_type') == 2) { - $cartRuleObj->reduction_amount = $cart_rule['value_tax_excl']; - } elseif (Tools::getValue('discount_type') == 3) { - $cartRuleObj->free_shipping = 1; + if (!count($this->errors)) { + $res = true; + foreach ($cart_rules as &$cart_rule) { + $cartRuleObj = new CartRule(); + $cartRuleObj->date_from = date('Y-m-d H:i:s', strtotime('-1 hour', strtotime($order->date_add))); + $cartRuleObj->date_to = date('Y-m-d H:i:s', strtotime('+1 hour')); + $cartRuleObj->name[Configuration::get('PS_LANG_DEFAULT')] = Tools::getValue('discount_name'); + $cartRuleObj->quantity = 0; + $cartRuleObj->quantity_per_user = 1; + if (Tools::getValue('discount_type') == 1) { + $cartRuleObj->reduction_percent = $discount_value; + } elseif (Tools::getValue('discount_type') == 2) { + $cartRuleObj->reduction_amount = $cart_rule['value_tax_excl']; + } elseif (Tools::getValue('discount_type') == 3) { + $cartRuleObj->free_shipping = 1; + } + $cartRuleObj->active = 0; + if ($res = $cartRuleObj->add()) { + $cart_rule['id'] = $cartRuleObj->id; + $cart_rule['free_shipping'] = $cartRuleObj->free_shipping; + } else { + break; + } } - $cartRuleObj->active = 0; - if ($res = $cartRuleObj->add()) { - $cart_rule['id'] = $cartRuleObj->id; - $cart_rule['free_shipping'] = $cartRuleObj->free_shipping; + + if ($res) { + foreach ($cart_rules as $id_order_invoice => $cart_rule) { + // Create OrderCartRule + $order_cart_rule = new OrderCartRule(); + $order_cart_rule->id_order = $order->id; + $order_cart_rule->id_cart_rule = $cart_rule['id']; + $order_cart_rule->id_order_invoice = $id_order_invoice; + $order_cart_rule->name = Tools::getValue('discount_name'); + $order_cart_rule->value = $cart_rule['value_tax_incl']; + $order_cart_rule->value_tax_excl = $cart_rule['value_tax_excl']; + $order_cart_rule->free_shipping = $cart_rule['free_shipping']; + $res &= $order_cart_rule->add(); + + $order->total_discounts = Tools::ps_round($order->total_discounts + $order_cart_rule->value, 6); + $order->total_discounts_tax_incl = Tools::ps_round($order->total_discounts_tax_incl + $order_cart_rule->value, 6); + $order->total_discounts_tax_excl = Tools::ps_round($order->total_discounts_tax_excl + $order_cart_rule->value_tax_excl, 6); + $order->total_paid = Tools::ps_round($order->total_paid - $order_cart_rule->value, 6); + $order->total_paid_tax_incl = Tools::ps_round($order->total_paid_tax_incl - $order_cart_rule->value, 6); + $order->total_paid_tax_excl = Tools::ps_round($order->total_paid_tax_excl - $order_cart_rule->value_tax_excl, 6); + } + + // Update Order + $res &= $order->update(); + } + + if ($res) { + Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token); } else { - break; + $this->errors[] = Tools::displayError('An error occurred during the OrderCartRule creation'); } } - - if ($res) { - foreach ($cart_rules as $id_order_invoice => $cart_rule) { - // Create OrderCartRule - $order_cart_rule = new OrderCartRule(); - $order_cart_rule->id_order = $order->id; - $order_cart_rule->id_cart_rule = $cart_rule['id']; - $order_cart_rule->id_order_invoice = $id_order_invoice; - $order_cart_rule->name = Tools::getValue('discount_name'); - $order_cart_rule->value = $cart_rule['value_tax_incl']; - $order_cart_rule->value_tax_excl = $cart_rule['value_tax_excl']; - $order_cart_rule->free_shipping = $cart_rule['free_shipping']; - $res &= $order_cart_rule->add(); - - $order->total_discounts += $order_cart_rule->value; - $order->total_discounts_tax_incl += $order_cart_rule->value; - $order->total_discounts_tax_excl += $order_cart_rule->value_tax_excl; - $order->total_paid -= $order_cart_rule->value; - $order->total_paid_tax_incl -= $order_cart_rule->value; - $order->total_paid_tax_excl -= $order_cart_rule->value_tax_excl; - } - - // Update Order - $res &= $order->update(); - } - - if ($res) { - Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token); - } else { - $this->errors[] = Tools::displayError('An error occurred during the OrderCartRule creation'); - } } } else { $this->errors[] = Tools::displayError('You do not have permission to edit this.'); @@ -2429,7 +2329,7 @@ class AdminOrdersControllerCore extends AdminController $dateFrom = date(Context::getContext()->language->date_format_lite, strtotime('-2 day')); $dateTo = date(Context::getContext()->language->date_format_lite, strtotime('-1 day')); $helper->subtitle = sprintf($this->l('From %s to %s', null, null, false), $dateFrom, $dateTo); - $helper->href = $this->context->link->getAdminLink('AdminCarts').'&action=filterOnlyAbandonedCarts'; + $helper->href = $this->context->link->getAdminLink('AdminCarts').'&action=filterOnlyAbandonedCarts&date_from='.$dateFrom.'&date_to='.$dateTo; $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=abandoned_cart'; $helper->tooltip = $this->l('Total number of abandoned carts in given period of time.', null, null, false); $kpis[] = $helper; @@ -4567,103 +4467,6 @@ class AdminOrdersControllerCore extends AdminController $children = $occupancy['children']; $child_ages = $occupancy['child_ages']; - /*By webkul to validate fields before deleting the cart and order data form the tables*/ - if ($id_hotel == '') { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Hotel Id is mising.'), - ))); - } elseif ($id_room == '') { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Room Id is missing.'), - ))); - } elseif ($new_date_from == '') { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please Enter Check In Date.'), - ))); - } elseif (!Validate::isDateFormat($new_date_from)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please Enter a Valid Check In Date.'), - ))); - } elseif ($new_date_to == '') { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please Enter Check Out Date.'), - ))); - } elseif (!Validate::isDateFormat($new_date_to)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please Enter a valid Check out Date.'), - ))); - } elseif ($new_date_from < $curr_date) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Check In date should not be after current date.'), - ))); - } elseif ($new_date_to <= $new_date_from) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Check out Date Should be after Check In date.'), - ))); - } elseif ($room_unit_price == '') { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please enter unit price.'), - ))); - } elseif (!Validate::isPrice($room_unit_price)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please enter a valid unit price.'), - ))); - } elseif (!Validate::isUnsignedInt($product_quantity)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Invalid quantity.'), - ))); - } - - // validations if order is with occupancy - if (!isset($adults) || !$adults || !Validate::isUnsignedInt($adults)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Invalid number of adults.'), - ))); - } elseif (!Validate::isUnsignedInt($children)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Invalid number of children.'), - ))); - } - - if ($children > 0) { - if (!isset($child_ages) || ($children != count($child_ages))) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Please provide all children age.'), - ))); - } else { - foreach($child_ages as $childAge) { - if (!Validate::isUnsignedInt($childAge)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Invalid children age.'), - ))); - } - } - } - } - - $rooms_booked = $obj_booking_detail->getRoomBookinInformationForDateRangeByOrder($id_room, $old_date_from, $old_date_to, $new_date_from, $new_date_to); - if ($rooms_booked) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('This Room Unavailable For Selected Duration.'), - ))); - } - // By webkul to calculate rates of the product from hotelreservationsystem tables with feature prices.... // add feature price for updated price @@ -5609,8 +5412,48 @@ class AdminOrdersControllerCore extends AdminController { $this->doEditValidation($order_detail, $order, $order_invoice); + $id_hotel_booking = Tools::getValue('id_booking_detail'); $product_price_tax_incl = str_replace(',', '.', Tools::getValue('product_price_tax_incl')); $product_price_tax_excl = str_replace(',', '.', Tools::getValue('product_price_tax_excl')); + $product_informations = $_POST['edit_product']; + $new_date_from = trim(date('Y-m-d', strtotime($product_informations['date_from']))); + $new_date_to = trim(date('Y-m-d', strtotime($product_informations['date_to']))); + $old_date_from = date('Y-m-d', strtotime(trim(Tools::getValue('date_from')))); + $old_date_to = date('Y-m-d', strtotime(trim(Tools::getValue('date_to')))); + $id_hotel = trim(Tools::getValue('id_hotel')); + $id_room = trim(Tools::getValue('id_room')); + $id_product = trim(Tools::getValue('id_product')); + $room_unit_price = trim(Tools::getValue('room_unit_price')); + $obj_booking_detail = new HotelBookingDetail(); + $product_quantity = (int) $obj_booking_detail->getNumberOfDays($new_date_from, $new_date_to); + $old_product_quantity = (int) $obj_booking_detail->getNumberOfDays($old_date_from, $old_date_to); + $qty_diff = $product_quantity - $old_product_quantity; + $occupancy = array_shift(Tools::getValue('occupancy')); + $adults = $occupancy['adults']; + $children = $occupancy['children']; + $child_ages = $occupancy['child_ages']; + + // If order is refunded, the validate changes which are not allowed + $objOrderReturn = new OrderReturn(); + $refundReqBookings = $objOrderReturn->getOrderRefundRequestedBookings($order->id, 0, 1); + if ($refundReqBookings && (in_array($id_hotel_booking, $refundReqBookings))) { + $objBookingDetail = new HotelBookingDetail($id_hotel_booking); + // If order is cancelled, we can't edit order + if ($objBookingDetail->is_refunded && $objBookingDetail->is_cancelled) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Booking cannot be edited if booking is cancelled.'), + ))); + // If order is refunded, we can't edit dates + } elseif ($objBookingDetail->is_refunded + && (strtotime($old_date_from) != strtotime($new_date_from) || strtotime($old_date_to) != strtotime($new_date_to)) + ) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Check-In/Check-Out dates cannot be changed if booking is refunded.'), + ))); + } + } if (!Validate::isPrice($product_price_tax_incl) || !Validate::isPrice($product_price_tax_excl)) { die(json_encode(array( @@ -5619,46 +5462,89 @@ class AdminOrdersControllerCore extends AdminController ))); } - $product_informations = Tools::getValue('edit_product'); - $old_date_from = date('Y-m-d', strtotime(trim(Tools::getValue('date_from')))); - $old_date_to = date('Y-m-d', strtotime(trim(Tools::getValue('date_to')))); - $new_date_from = trim(date('Y-m-d', strtotime($product_informations['date_from']))); - $new_date_to = trim(date('Y-m-d', strtotime($product_informations['date_to']))); - $obj_booking_detail = new HotelBookingDetail(); - $product_quantity = (int) $obj_booking_detail->getNumberOfDays($new_date_from, $new_date_to); - $id_room = Tools::getValue('id_room'); - - if (trim(Tools::getValue('id_hotel')) == '') { + if ($id_hotel == '') { die(json_encode(array( 'result' => false, 'error' => Tools::displayError('Hotel Id is mising.'), ))); - } elseif (trim($id_room) == '') { + } elseif ($id_room == '') { die(json_encode(array( 'result' => false, 'error' => Tools::displayError('Room Id is missing.'), ))); - } elseif (trim(date('Y-m-d', strtotime($product_informations['date_from']))) == '') { + } elseif ($new_date_from == '') { die(json_encode(array( 'result' => false, - 'error' => Tools::displayError('Please enter check-in date.'), + 'error' => Tools::displayError('Please enter Check-In date.'), ))); } elseif (!Validate::isDateFormat($new_date_from)) { die(json_encode(array( 'result' => false, - 'error' => Tools::displayError('Please enter a valid check-in date.'), + 'error' => Tools::displayError('Please enter a valid Check-In date.'), ))); } elseif ($new_date_to == '') { die(json_encode(array( 'result' => false, - 'error' => Tools::displayError('Please enter check-out date.'), + 'error' => Tools::displayError('Please enter Check-Out date.'), ))); } elseif (!Validate::isDateFormat($new_date_to)) { die(json_encode(array( 'result' => false, - 'error' => Tools::displayError('Please enter a valid check-out date.'), + 'error' => Tools::displayError('Please enter a valid Check-out date.'), + ))); + } elseif ($new_date_to <= $new_date_from) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Check-out date should be after Check-In date.'), + ))); + } elseif ($room_unit_price == '') { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Please enter unit price.'), + ))); + } elseif (!Validate::isPrice($room_unit_price)) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Please enter a valid unit price.'), + ))); + } elseif (!Validate::isUnsignedInt($product_quantity)) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Invalid quantity.'), ))); } + + // validations if order is with occupancy + if (!isset($adults) || !$adults || !Validate::isUnsignedInt($adults)) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Invalid number of adults.'), + ))); + } elseif (!Validate::isUnsignedInt($children)) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Invalid number of children.'), + ))); + } + + if ($children > 0) { + if (!isset($child_ages) || ($children != count($child_ages))) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Please provide all children age.'), + ))); + } else { + foreach($child_ages as $childAge) { + if (!Validate::isUnsignedInt($childAge)) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('Invalid children age.'), + ))); + } + } + } + } + if ($this->context->employee->isSuperAdmin()) { $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; } else { @@ -5669,24 +5555,18 @@ class AdminOrdersControllerCore extends AdminController if ($new_date_from < $compareDate) { die(json_encode(array( 'result' => false, - 'error' => sprintf(Tools::displayError('Check-in date should not be date before %s.'),$compareDate) + 'error' => sprintf(Tools::displayError('Check-In date should not be date before %s.'),$compareDate) ))); } } - if ($new_date_to <= $new_date_from) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Check-out date should be after check-in date.'), - ))); - } elseif (!Validate::isUnsignedInt($product_quantity)) { - die(json_encode(array( - 'result' => false, - 'error' => Tools::displayError('Invalid quantity.'), - ))); - } - $rooms_booked = $obj_booking_detail->getRoomBookinInformationForDateRangeByOrder($id_room, $old_date_from, $old_date_to, $new_date_from, $new_date_to); - if ($rooms_booked) { + if ($rooms_booked = $obj_booking_detail->getRoomBookinInformationForDateRangeByOrder( + $id_room, + $old_date_from, + $old_date_to, + $new_date_from, + $new_date_to + )) { die(json_encode(array( 'result' => false, 'error' => Tools::displayError('This room is unavailable for selected duration.'), diff --git a/controllers/admin/AdminStatsController.php b/controllers/admin/AdminStatsController.php index 2de11a362..782f989f8 100644 --- a/controllers/admin/AdminStatsController.php +++ b/controllers/admin/AdminStatsController.php @@ -78,13 +78,15 @@ class AdminStatsControllerCore extends AdminStatsTabController return $visits; } - public static function getAbandonedCarts($date_from, $date_to) + + public static function getAbandonedCarts($date_from, $date_to, $timeDiff = false) { return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' - SELECT COUNT(DISTINCT id_guest) - FROM `'._DB_PREFIX_.'cart` - WHERE `date_add` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'" - AND NOT EXISTS (SELECT 1 FROM `'._DB_PREFIX_.'orders` WHERE `'._DB_PREFIX_.'orders`.id_cart = `'._DB_PREFIX_.'cart`.id_cart) + SELECT COUNT(`id_cart`) + FROM `'._DB_PREFIX_.'cart` c + WHERE `date_add` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"'. + (($timeDiff) ? 'AND TIME_TO_SEC(TIMEDIFF(\''.pSQL(date('Y-m-d H:i:00', time())).'\', `date_add`)) > '.$timeDiff : ' ').' + AND NOT EXISTS (SELECT 1 FROM `'._DB_PREFIX_.'orders` o WHERE o.`id_cart` = c.`id_cart`) '.Shop::addSqlRestriction()); } @@ -638,7 +640,11 @@ class AdminStatsControllerCore extends AdminStatsTabController break; case 'abandoned_cart': - $value = AdminStatsController::getAbandonedCarts(date('Y-m-d H:i:s', strtotime('-2 day')), date('Y-m-d H:i:s', strtotime('-1 day'))); + $value = AdminStatsController::getAbandonedCarts( + date('Y-m-d', strtotime('-2 day')).' 0:0:0', + date('Y-m-d', strtotime('-1 day')).' 23:59:59', + _TIME_1_DAY_ + ); break; case 'installed_modules': diff --git a/controllers/front/AuthController.php b/controllers/front/AuthController.php index fe8caa4a3..a706b5ede 100644 --- a/controllers/front/AuthController.php +++ b/controllers/front/AuthController.php @@ -438,6 +438,12 @@ class AuthControllerCore extends FrontController $this->errors[] = Tools::displayError('You must register at least one phone number.'); } + if (!Tools::getValue('is_new_customer', 1)) { + if ($idCustomer = Customer::customerExists(Tools::getValue('email'), true, false)) { + $customer = new Customer($idCustomer); + } + } + $this->errors = array_unique(array_merge($this->errors, $customer->validateController())); // Check the requires fields which are settings in the BO @@ -601,13 +607,7 @@ class AuthControllerCore extends FrontController $customer->active = 1; // New Guest customer if (Tools::isSubmit('is_new_customer')) { - if (isset($idCustomer) && $idCustomer) { - // update guest customer details - $customer = new Customer($idCustomer); - $customer->firstname = Tools::getValue('firstname'); - $customer->lastname = Tools::getValue('lastname'); - } - $customer->is_guest = 1; + $customer->is_guest = !Tools::getValue('is_new_customer', 1); } else { $customer->is_guest = 0; } diff --git a/controllers/front/CategoryController.php b/controllers/front/CategoryController.php index 3823504ab..0fc5f8efb 100644 --- a/controllers/front/CategoryController.php +++ b/controllers/front/CategoryController.php @@ -181,22 +181,6 @@ class CategoryControllerCore extends FrontController $booking_data = $objBookingDetail->dataForFrontSearch($bookingParams); - // set default occupancies in required format - if (isset($booking_data['rm_data']) && $booking_data['rm_data']) { - foreach ($booking_data['rm_data'] as &$roomTypeData) { - $occupancy = array( - array( - 'adults' => $roomTypeData['adults'], - 'children' => 0, - 'child_ages' => array(), - ), - ); - - $roomTypeData['occupancies'] = $occupancy; - $roomTypeData['occupancy_adults'] = $roomTypeData['adults']; // only one room by default - } - } - $obj_booking_detail = new HotelBookingDetail(); $num_days = $obj_booking_detail->getNumberOfDays($date_from, $date_to); diff --git a/controllers/front/OrderOpcController.php b/controllers/front/OrderOpcController.php index 2cd2a223c..95a0adceb 100644 --- a/controllers/front/OrderOpcController.php +++ b/controllers/front/OrderOpcController.php @@ -426,7 +426,7 @@ class OrderOpcControllerCore extends ParentOrderController public function initContent() { // validate room types before payment by customer - $orderRestrictErr = HotelCartBookingData::validateCartBookings(); + $this->errors = HotelCartBookingData::validateCartBookings(); parent::initContent(); @@ -494,7 +494,7 @@ class OrderOpcControllerCore extends ParentOrderController // $objCurrency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); $this->context->smarty->assign( array( - 'orderRestrictErr' => $orderRestrictErr, + 'orderRestrictErr' => count($this->errors) ? 1 : 0, // 'allDemands' => $allDemands, // 'defaultcurrencySign' => $objCurrency->sign, 'THEME_DIR' => _THEME_DIR_, diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index ec77ebd09..1028ae6e0 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -427,14 +427,27 @@ class ProductControllerCore extends FrontController if (Configuration::get('PS_FRONT_ROOM_UNIT_SELECTION_TYPE') == HotelBookingDetail::PS_ROOM_UNIT_SELECTION_TYPE_QUANTITY) { $occupancy_value = 1; } else { - $occupancy_value = array( - array( - 'adults' => $room_info_by_product_id['adults'], - 'children' => 0, - 'child_ages' => array(), - ), - ); + $useDefaultOccupancy = true; + // if coming from hotel page do not set occupancy, otherwise set base adult occupancy + if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == Tools::secureReferrer($_SERVER['HTTP_REFERER'])) { // Assure us the previous page was one of the site + $idCategoryHotel = $hotel_branch_obj->id_category; + $categoryPageLink = $this->context->link->getCategoryLink($idCategoryHotel); + if (Tools::strpos($_SERVER['HTTP_REFERER'], $categoryPageLink) === 0) { + $useDefaultOccupancy = false; + } + } + + if ($useDefaultOccupancy) { + $occupancy_value = array( + array( + 'adults' => $room_info_by_product_id['adults'], + 'children' => 0, + 'child_ages' => array(), + ), + ); + } } + $this->assignBookingFormVars($this->product->id, $date_from, $date_to, $occupancy_value); $this->assignServiceProductVars(); diff --git a/install/langs/bg/data/order_state.xml b/install/langs/bg/data/order_state.xml index ba7230bc7..f4661ce31 100644 --- a/install/langs/bg/data/order_state.xml +++ b/install/langs/bg/data/order_state.xml @@ -46,6 +46,6 @@ Получено частично плащане - + diff --git a/install/langs/bn/data/order_state.xml b/install/langs/bn/data/order_state.xml index dd6f8417b..079e3acba 100644 --- a/install/langs/bn/data/order_state.xml +++ b/install/langs/bn/data/order_state.xml @@ -46,6 +46,6 @@ আংশিক পেমেন্ট প্রাপ্ত - + diff --git a/install/langs/br/data/order_state.xml b/install/langs/br/data/order_state.xml index 306182ff7..e9a75f914 100644 --- a/install/langs/br/data/order_state.xml +++ b/install/langs/br/data/order_state.xml @@ -46,6 +46,6 @@ Pagamento parcial recebido - + diff --git a/install/langs/cs/data/order_state.xml b/install/langs/cs/data/order_state.xml index 8120bd196..bdbe0e77e 100644 --- a/install/langs/cs/data/order_state.xml +++ b/install/langs/cs/data/order_state.xml @@ -46,6 +46,6 @@ Částečná platba přijata - + \ No newline at end of file diff --git a/install/langs/de/data/order_state.xml b/install/langs/de/data/order_state.xml index 3366f5e62..65b042db0 100644 --- a/install/langs/de/data/order_state.xml +++ b/install/langs/de/data/order_state.xml @@ -46,6 +46,6 @@ Teilzahlung erhalten - + diff --git a/install/langs/en/data/order_state.xml b/install/langs/en/data/order_state.xml index b8cf92365..16e519f1a 100644 --- a/install/langs/en/data/order_state.xml +++ b/install/langs/en/data/order_state.xml @@ -46,6 +46,6 @@ Partial payment received - + diff --git a/install/langs/es/data/order_state.xml b/install/langs/es/data/order_state.xml index ebe33ab5d..f47bf65d3 100644 --- a/install/langs/es/data/order_state.xml +++ b/install/langs/es/data/order_state.xml @@ -46,6 +46,6 @@ Pago parcial recibido - + diff --git a/install/langs/fa/data/order_state.xml b/install/langs/fa/data/order_state.xml index ee8611aa7..8c992e07b 100644 --- a/install/langs/fa/data/order_state.xml +++ b/install/langs/fa/data/order_state.xml @@ -46,6 +46,6 @@ پرداخت جزئی دریافت شد - + diff --git a/install/langs/fr/data/order_state.xml b/install/langs/fr/data/order_state.xml index bccde25eb..55aa13404 100644 --- a/install/langs/fr/data/order_state.xml +++ b/install/langs/fr/data/order_state.xml @@ -46,6 +46,6 @@ Paiement partiel reçu - + diff --git a/install/langs/he/data/order_state.xml b/install/langs/he/data/order_state.xml index b9c8e24de..7bfc432fc 100644 --- a/install/langs/he/data/order_state.xml +++ b/install/langs/he/data/order_state.xml @@ -46,6 +46,6 @@ תשלום חלקי התקבל - + diff --git a/install/langs/hr/data/order_state.xml b/install/langs/hr/data/order_state.xml index e6805423b..39eaaa302 100644 --- a/install/langs/hr/data/order_state.xml +++ b/install/langs/hr/data/order_state.xml @@ -46,6 +46,6 @@ Primljena djelomična uplata - + diff --git a/install/langs/hu/data/order_state.xml b/install/langs/hu/data/order_state.xml index 5d53757b9..9b2b9c956 100644 --- a/install/langs/hu/data/order_state.xml +++ b/install/langs/hu/data/order_state.xml @@ -46,6 +46,6 @@ Részleges kifizetés megérkezett - + diff --git a/install/langs/id/data/order_state.xml b/install/langs/id/data/order_state.xml index 90b3ac4a1..853175220 100644 --- a/install/langs/id/data/order_state.xml +++ b/install/langs/id/data/order_state.xml @@ -46,6 +46,6 @@ Pembayaran sebagian diterima - + diff --git a/install/langs/it/data/order_state.xml b/install/langs/it/data/order_state.xml index e77a35b36..a328ca9ae 100644 --- a/install/langs/it/data/order_state.xml +++ b/install/langs/it/data/order_state.xml @@ -46,6 +46,6 @@ Pagamento parziale ricevuto - + diff --git a/install/langs/lt/data/order_state.xml b/install/langs/lt/data/order_state.xml index 270e6c6c6..d58ef02e0 100644 --- a/install/langs/lt/data/order_state.xml +++ b/install/langs/lt/data/order_state.xml @@ -46,6 +46,6 @@ Gautas dalinis apmokėjimas - + diff --git a/install/langs/mk/data/order_state.xml b/install/langs/mk/data/order_state.xml index 20086e951..d128aebe8 100644 --- a/install/langs/mk/data/order_state.xml +++ b/install/langs/mk/data/order_state.xml @@ -46,6 +46,6 @@ Примено е делумно плаќање - + diff --git a/install/langs/nl/data/order_state.xml b/install/langs/nl/data/order_state.xml index c2d7da6c7..c970d6d93 100644 --- a/install/langs/nl/data/order_state.xml +++ b/install/langs/nl/data/order_state.xml @@ -46,6 +46,6 @@ Gedeeltelijke betaling ontvangen - + diff --git a/install/langs/no/data/order_state.xml b/install/langs/no/data/order_state.xml index b8cf92365..16e519f1a 100644 --- a/install/langs/no/data/order_state.xml +++ b/install/langs/no/data/order_state.xml @@ -46,6 +46,6 @@ Partial payment received - + diff --git a/install/langs/pl/data/order_state.xml b/install/langs/pl/data/order_state.xml index 4cb1831b6..644e3d9ab 100644 --- a/install/langs/pl/data/order_state.xml +++ b/install/langs/pl/data/order_state.xml @@ -46,6 +46,6 @@ Otrzymano częściową płatność - + diff --git a/install/langs/pt/data/order_state.xml b/install/langs/pt/data/order_state.xml index 91361bf5c..382b23550 100644 --- a/install/langs/pt/data/order_state.xml +++ b/install/langs/pt/data/order_state.xml @@ -46,6 +46,6 @@ Pagamento parcial recebido - + diff --git a/install/langs/qc/data/order_state.xml b/install/langs/qc/data/order_state.xml index 7873dbeb6..fce19d5f6 100644 --- a/install/langs/qc/data/order_state.xml +++ b/install/langs/qc/data/order_state.xml @@ -46,6 +46,6 @@ Paiement partiel reçu - + diff --git a/install/langs/ro/data/order_state.xml b/install/langs/ro/data/order_state.xml index 7b310b557..68afd22b7 100644 --- a/install/langs/ro/data/order_state.xml +++ b/install/langs/ro/data/order_state.xml @@ -46,6 +46,6 @@ Plata parțială primită - + diff --git a/install/langs/ru/data/order_state.xml b/install/langs/ru/data/order_state.xml index e5fb90335..983bc12dc 100644 --- a/install/langs/ru/data/order_state.xml +++ b/install/langs/ru/data/order_state.xml @@ -46,6 +46,6 @@ Частичная оплата получена - + diff --git a/install/langs/si/data/order_state.xml b/install/langs/si/data/order_state.xml index af6b0edd2..73d97f838 100644 --- a/install/langs/si/data/order_state.xml +++ b/install/langs/si/data/order_state.xml @@ -46,6 +46,6 @@ අර්ධ ගෙවීමක් ලැබී ඇත - + diff --git a/install/langs/sr/data/order_state.xml b/install/langs/sr/data/order_state.xml index f2f17a60e..f2a5e6529 100644 --- a/install/langs/sr/data/order_state.xml +++ b/install/langs/sr/data/order_state.xml @@ -46,6 +46,6 @@ Делимична уплата примљена - + diff --git a/install/langs/sv/data/order_state.xml b/install/langs/sv/data/order_state.xml index 312b0b533..e55775740 100644 --- a/install/langs/sv/data/order_state.xml +++ b/install/langs/sv/data/order_state.xml @@ -46,6 +46,6 @@ Delbetalning mottagen - + diff --git a/install/langs/tw/data/order_state.xml b/install/langs/tw/data/order_state.xml index 366a726a3..f535a0c61 100644 --- a/install/langs/tw/data/order_state.xml +++ b/install/langs/tw/data/order_state.xml @@ -46,6 +46,6 @@ 已收到部分付款 - + diff --git a/install/langs/vn/data/order_state.xml b/install/langs/vn/data/order_state.xml index e8d3f740c..9b79504d1 100644 --- a/install/langs/vn/data/order_state.xml +++ b/install/langs/vn/data/order_state.xml @@ -46,6 +46,6 @@ Đã nhận được một phần thanh toán - + diff --git a/install/langs/zh/data/order_state.xml b/install/langs/zh/data/order_state.xml index 93728e668..7e868eec7 100644 --- a/install/langs/zh/data/order_state.xml +++ b/install/langs/zh/data/order_state.xml @@ -46,6 +46,6 @@ 已收到部分付款 - + diff --git a/install/theme/view.css b/install/theme/view.css index 1d135b54d..95593aa66 100644 --- a/install/theme/view.css +++ b/install/theme/view.css @@ -90,10 +90,10 @@ div#leftpannel{ } div#buttons{ - clear:both; - margin:0 0 0 295px; - height:60px; + margin-top: 20px; + margin-bottom: 20px; width:650px; + padding:0 14px; } * html div#buttons { margin-bottom:60px; diff --git a/install/theme/views/footer.phtml b/install/theme/views/footer.phtml index 44dc055c7..9ae867a65 100644 --- a/install/theme/views/footer.phtml +++ b/install/theme/views/footer.phtml @@ -1,20 +1,20 @@ - - -
- isLastStep()): ?> - next_button): ?> - - - +
+ isLastStep()): ?> + next_button): ?> + + + + - - isFirstStep() && $this->previous_button): ?> - - -
+ isFirstStep() && $this->previous_button): ?> + + +
+ +
l('If you need some assistance, you can get tailored help from our support team. The official documentation is also here to guide you.'), $this->getTailoredHelp(), $this->getDocumentationLink()) ?>
diff --git a/install/theme/views/header.phtml b/install/theme/views/header.phtml index 6a04e0ea9..db3b9bfc6 100644 --- a/install/theme/views/header.phtml +++ b/install/theme/views/header.phtml @@ -119,7 +119,7 @@ -
+
diff --git a/js/admin/orders.js b/js/admin/orders.js index 8a551b4fa..097961a27 100644 --- a/js/admin/orders.js +++ b/js/admin/orders.js @@ -2515,13 +2515,6 @@ const AddRoomBookingModal = { $('#new_product .booking_guest_occupancy').removeClass('disabled'); setRoomTypeGuestOccupancy($('#new_product .booking_occupancy_wrapper')); } - if (data.room_type_info) { - $('#new_product .max_adults').val(data.room_type_info.max_adults); - $('#new_product .max_children').val(data.room_type_info.max_children); - $('#new_product .max_guests').val(data.room_type_info.max_guests); - $('#new_product .num_adults').attr('max', data.room_type_info.max_adults); - $('#new_product .num_children').attr('max', data.room_type_info.max_children); - } // Keep product variable current_product = data; diff --git a/js/daterangepicker/qlodaterangepicker.js b/js/daterangepicker/qlodaterangepicker.js index 369ea9325..401d2b6bc 100644 --- a/js/daterangepicker/qlodaterangepicker.js +++ b/js/daterangepicker/qlodaterangepicker.js @@ -22,6 +22,9 @@ var dateRangePickerOrg = $.fn.dateRangePicker; $.fn.dateRangePicker = function(opt) { if(typeof opt === "object") { + let container = $(this).parent(); + container.css({ position: 'relative' }); + const custom_opt = { format: 'DD-MM-YYYY', showTopbar: false, @@ -31,14 +34,14 @@ minDays: 2, startOfWeek: 'monday', hoveringTooltip: false, - container: '#page', + container: container, + inline: true, customArrowPrevSymbol: '', customArrowNextSymbol: '', - getValue: function() - { + getValue: function() { return $(this).find('span').html(); }, - setValue: function(s, s1, s2) { + setValue: function(s) { if (s) { $(this).find('span').html(s.replace('to', '  ')); } else { @@ -48,15 +51,56 @@ } } } + $.each(opt, function(index) { delete custom_opt[index]; }); $.extend(true, opt, custom_opt); - } var args = Array.prototype.slice.call(arguments,0); - return dateRangePickerOrg.apply(this, args); + + const dateRangePickerInput = dateRangePickerOrg.apply(this, args); + const calendarDom = $(dateRangePickerInput).data('dateRangePicker').getDatePicker(); + + dateRangePickerInput.on('datepicker-open', function() { + const positionClass = getPositionClass(dateRangePickerInput, calendarDom); + $(calendarDom).removeClass('top bottom').addClass(positionClass); + setPosition(dateRangePickerInput, calendarDom, positionClass) + }); + + return dateRangePickerInput; + + // helper function definitions + function getPositionClass(dateRangePickerInput, calendarDom) { + const inputElementHeight = dateRangePickerInput.outerHeight(); + const spaceTop = dateRangePickerInput.offset().top - $(window).scrollTop(); + const spaceBottom = $(window).height() - inputElementHeight - spaceTop; + const maxHeightNeeded = $(calendarDom).get(0).scrollHeight; + + let positionClass = 'bottom'; + // determine position class + if (spaceBottom < maxHeightNeeded && spaceTop > spaceBottom) { + positionClass = 'top'; + } + + return positionClass; + } + + function setPosition(dateRangePickerInput, calendarDom, positionClass) { + const inputElementHeight = dateRangePickerInput.outerHeight(); + + const css = {}; + if (positionClass == 'top') { + css.top = 'unset'; + css.bottom = inputElementHeight; + } else { + css.bottom = 'unset'; + css.top = $(dateRangePickerInput).position().top + inputElementHeight; + } + + $(calendarDom).css(css); + } } -})(jQuery); \ No newline at end of file +})(jQuery); diff --git a/mails/en/partial_payment_accepted.html b/mails/en/partial_payment_accepted.html new file mode 100644 index 000000000..45940907a --- /dev/null +++ b/mails/en/partial_payment_accepted.html @@ -0,0 +1,138 @@ + + + + + + Message from {shop_name} + + + + + + + + + + + + +
  + + + + + + + + + + + + + + + + + +{extra_mail_content_html} + + + + + + + + + + + + + +
+ + Hi {firstname} {lastname},
+ Thank you for booking with {shop_name}! +
+
+ + + + + + +
  + +

+ Order {order_name} - Payment processed

+ + Your payment for order with the reference {order_name} was successfully processed.

+ + Total Booking Amount: {total_paid}

+ Partial Payment Amount: {advance_paid_amount}

+ Total Paid Amount: {total_paid_real}

+
+
 
+
+ + + You can review your order and download your invoice from the "Order history" section of your customer account by clicking "My account" on our website. + +
+ + + If you have a guest account, you can follow your order via the "Guest Tracking" section on our website. + +
+
 
+ + diff --git a/mails/en/partial_payment_accepted.txt b/mails/en/partial_payment_accepted.txt new file mode 100644 index 000000000..799594197 --- /dev/null +++ b/mails/en/partial_payment_accepted.txt @@ -0,0 +1,26 @@ + +[/{shop_url}] + +Hi {firstname} {lastname}, + +Thank you for booking with {shop_name}! + +Order {order_name} - Payment processed + +Your payment for order with the reference {order_name} was successfully processed. + +Total Booking Amount: {total_paid} +Partial Payment Amount: {advance_paid_amount} +Total Paid Amount: {total_paid_real} + +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 website. + +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 website. + +{shop_name} [/{shop_url}] powered by Webkul(tm) +[https://webkul.com] + diff --git a/modules/bankwire/bankwire.php b/modules/bankwire/bankwire.php index a5add709a..442a6b97a 100644 --- a/modules/bankwire/bankwire.php +++ b/modules/bankwire/bankwire.php @@ -208,14 +208,16 @@ class Bankwire extends PaymentModule } $objOrder = $params['objOrder']; - $orderState = $objOrder->getCurrentState(); + $idOrderState = $objOrder->getCurrentState(); + $objOrderState = new OrderState($idOrderState); + $history = $objOrder->getHistory($this->context->language->id); + $initialStatus = array_pop($history); $smartyVars = array(); - if (in_array( - $orderState, - array( - Configuration::get('PS_OS_AWAITING_PAYMENT'), + if ($idOrderState == Configuration::get('PS_OS_AWAITING_PAYMENT') + || ($objOrderState->logable + && $initialStatus['id_order_state'] == Configuration::get('PS_OS_AWAITING_PAYMENT') ) - )) { + ) { $objCart = new Cart($objOrder->id_cart); if ($objCart->is_advance_payment) { $cartTotal = $objOrder->getOrdersTotalPaid(1); diff --git a/modules/blockcart/ajax-cart.js b/modules/blockcart/ajax-cart.js index c1cb4b1e7..9dfd93abd 100644 --- a/modules/blockcart/ajax-cart.js +++ b/modules/blockcart/ajax-cart.js @@ -478,6 +478,9 @@ var ajaxCart = { else $(callerElement).removeProp('disabled'); } + if (!addedFromProductPage) { + resetOccupancyField($(callerElement).closest('.booking_room_fields').find('.booking_occupancy_wrapper')); + } emptyCustomizations(); }, diff --git a/modules/cheque/cheque.php b/modules/cheque/cheque.php index 63bb05629..002f207e3 100644 --- a/modules/cheque/cheque.php +++ b/modules/cheque/cheque.php @@ -191,13 +191,15 @@ class Cheque extends PaymentModule return; } $objOrder = $params['objOrder']; - $orderState = $objOrder->getCurrentState(); - if (in_array( - $orderState, - array( - Configuration::get('PS_OS_AWAITING_PAYMENT') - ) - )) { + $idOrderState = $objOrder->getCurrentState(); + $objOrderState = new OrderState($idOrderState); + $history = $objOrder->getHistory($this->context->language->id); + $initialStatus = array_pop($history); + if ($idOrderState == Configuration::get('PS_OS_AWAITING_PAYMENT') + || ($objOrderState->logable + && $initialStatus['id_order_state'] == Configuration::get('PS_OS_AWAITING_PAYMENT') + ) + ) { $objCart = new Cart($objOrder->id_cart); if ($objCart->is_advance_payment) { $cartTotal = $objOrder->getOrdersTotalPaid(1); diff --git a/modules/hotelreservationsystem/classes/HotelCartBookingData.php b/modules/hotelreservationsystem/classes/HotelCartBookingData.php index dc32346d2..df5c6c616 100644 --- a/modules/hotelreservationsystem/classes/HotelCartBookingData.php +++ b/modules/hotelreservationsystem/classes/HotelCartBookingData.php @@ -248,7 +248,7 @@ class HotelCartBookingData extends ObjectModel */ public function getCartCurrentDataByCartId($cart_id) { - $result = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'htl_cart_booking_data` WHERE `id_cart`='.$cart_id); + $result = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'htl_cart_booking_data` WHERE `id_cart`='.(int)$cart_id); if ($result) { return $result; } else { @@ -925,23 +925,34 @@ class HotelCartBookingData extends ObjectModel return true; } + // validate cart data if not available then remove from cart public static function validateCartBookings() { $context = Context::getContext(); - $errors = array(); + $objModule = Module::getInstanceByName('hotelreservationsystem'); + + // For admin cart validations use this variable + $forAdminCart = 0; + if (isset($context->employee->id)) { + $forAdminCart = 1; + } // validate room types if bookable from front office if ($cartProducts = $context->cart->getProducts()) { - $objHotelCartBookingData = new HotelCartBookingData(); - foreach ($cartProducts as $product) { - if ($product['booking_product'] && !$product['show_at_front']) { - $objHotelCartBookingData->deleteCartBookingData($context->cart->id, $product['id_product']); + if (!$forAdminCart) { + $objHotelCartBookingData = new HotelCartBookingData(); + foreach ($cartProducts as $product) { + if ($product['booking_product'] && !$product['show_at_front']) { + $objHotelCartBookingData->deleteCartBookingData($context->cart->id, $product['id_product']); + } } } + } else { + $errors[] = $objModule->l('No booking found in the cart.', 'HotelOrderRestrictDate'); } - // validate service products + // validate service products if not active not then remove from cart if ($cartProducts = $context->cart->getProducts()) { $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail(); foreach ($cartProducts as $product) { @@ -954,8 +965,20 @@ class HotelCartBookingData extends ObjectModel } } + // for admin/employee remove bookings of the back dates from cart if not allowed + if ($forAdminCart) { + if ($context->employee->isSuperAdmin()) { + $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; + } else { + $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; + } + if (!Configuration::get($backOrderConfigKey)) { + $objHotelCartBookingData = new HotelCartBookingData(); + $objHotelCartBookingData->removeBackdateRoomsFromCart($context->cart->id); + } + } + // validate room types for restriction date - $objModule = Module::getInstanceByName('hotelreservationsystem'); if ($cartProducts = $context->cart->getProducts()) { $objHotelCartBookingData = new HotelCartBookingData(); $objHotelBookingDetail = new HotelBookingDetail(); @@ -977,43 +1000,43 @@ class HotelCartBookingData extends ObjectModel } foreach ($cartData as $roomData) { - if ($maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($roomData['id_hotel'])) { - if (strtotime('-1 day', strtotime($maxOrderDate)) < strtotime($roomData['date_from']) - || strtotime($maxOrderDate) < strtotime($roomData['date_to']) - ) { - $objHotelBranchInformation = new HotelBranchInformation( - $roomData['id_hotel'], - $context->language->id - ); - $errors[] = sprintf( - 'You can not book rooms for hotel \'%s\' after date %s. Please remove rooms from %s - %s to proceed.', - $objHotelBranchInformation->hotel_name, - Tools::displayDate($maxOrderDate), - Tools::displayDate($roomData['date_from']), - Tools::displayDate($roomData['date_to']) - ); - $error = true; + if (!$forAdminCart) { + if ($maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($roomData['id_hotel'])) { + if (strtotime('-1 day', strtotime($maxOrderDate)) < strtotime($roomData['date_from']) + || strtotime($maxOrderDate) < strtotime($roomData['date_to']) + ) { + $objHotelBranchInformation = new HotelBranchInformation( + $roomData['id_hotel'], + $context->language->id + ); + $errors[] = sprintf( + 'You can not book rooms for hotel \'%s\' after date %s. Please remove rooms from %s - %s to proceed.', + $objHotelBranchInformation->hotel_name, + Tools::displayDate($maxOrderDate), + Tools::displayDate($roomData['date_from']), + Tools::displayDate($roomData['date_to']) + ); + } } - } - $preparationTime = HotelOrderRestrictDate::getPreparationTime($roomData['id_hotel']); - if ($preparationTime !== false) { - $minOrderDate = date('Y-m-d', strtotime('+'. ($preparationTime) .' days')); - if (strtotime($minOrderDate) > strtotime($roomData['date_from']) - || strtotime($minOrderDate . ' +1 day')> strtotime($roomData['date_to']) - ) { - $objHotelBranchInformation = new HotelBranchInformation( - $roomData['id_hotel'], - $context->language->id - ); - $errors[] = sprintf( - 'You can not book rooms for hotel \'%s\' before date %s. Please remove rooms from %s - %s to proceed.', - $objHotelBranchInformation->hotel_name, - Tools::displayDate($minOrderDate), - Tools::displayDate($roomData['date_from']), - Tools::displayDate($roomData['date_to']) - ); - $error = true; + $preparationTime = HotelOrderRestrictDate::getPreparationTime($roomData['id_hotel']); + if ($preparationTime !== false) { + $minOrderDate = date('Y-m-d', strtotime('+'. ($preparationTime) .' days')); + if (strtotime($minOrderDate) > strtotime($roomData['date_from']) + || strtotime($minOrderDate . ' +1 day')> strtotime($roomData['date_to']) + ) { + $objHotelBranchInformation = new HotelBranchInformation( + $roomData['id_hotel'], + $context->language->id + ); + $errors[] = sprintf( + 'You can not book rooms for hotel \'%s\' before date %s. Please remove rooms from %s - %s to proceed.', + $objHotelBranchInformation->hotel_name, + Tools::displayDate($minOrderDate), + Tools::displayDate($roomData['date_from']), + Tools::displayDate($roomData['date_to']) + ); + } } } @@ -1025,32 +1048,27 @@ class HotelCartBookingData extends ObjectModel 'only_search_data' => 1, ); $bookingSearchData = $objHotelBookingDetail->dataForFrontSearch($bookingParams); - $isRmBooked = 0; + $isRoomBooked = 0; if (count($bookingSearchData['rm_data'][$product['id_product']]['data']['available']) < count($roomData['id_rms'])) { foreach ($roomData['id_rms'] as $searchRoomData) { - if($isRmBooked = $objHotelBookingDetail->chechRoomBooked($searchRoomData, $roomData['date_from'], $roomData['date_to'])){ + if($isRoomBooked = $objHotelBookingDetail->chechRoomBooked($searchRoomData, $roomData['date_from'], $roomData['date_to'])){ break; } } - if ($isRmBooked) { + if ($isRoomBooked) { $errors[] = sprintf($objModule->l('The Room \'%s\' has been booked by another customer from \'%s\' to \'%s\' Please remove rooms from cart to proceed', 'HotelOrderRestrictDate'), $product['name'], date('d-m-Y', strtotime($roomData['date_from'])), date('d-m-Y', strtotime($roomData['date_to']))); - $error = true; } else { $errors[] = sprintf($objModule->l('The Room \'%s\' is no longer avalable from \'%s\' to \'%s\' Please remove rooms from cart to proceed', 'HotelOrderRestrictDate'), $product['name'], date('d-m-Y', strtotime($roomData['date_from'])), date('d-m-Y', strtotime($roomData['date_to']))); - $error = true; } } } } } else { - $error = true; $errors[] = $objModule->l('You can not book rooms from "', 'HotelOrderRestrictDate'). $product['name'] .$objModule->l('". Please remove rooms from "', 'HotelOrderRestrictDate'). $product['name'] . $objModule->l('" from cart to proceed.', 'HotelOrderRestrictDate'); } } } - $context->controller->errors = array_merge($context->controller->errors, $errors); - return $errors; } diff --git a/modules/hotelreservationsystem/classes/HotelHelper.php b/modules/hotelreservationsystem/classes/HotelHelper.php index 8aee39b6f..0b615f59a 100644 --- a/modules/hotelreservationsystem/classes/HotelHelper.php +++ b/modules/hotelreservationsystem/classes/HotelHelper.php @@ -199,6 +199,8 @@ class HotelHelper Configuration::updateValue('WK_HOTEL_LOCATION_ENABLE', 1); Configuration::updateValue('WK_HOTEL_NAME_ENABLE', 1); + Configuration::updateValue('WK_HOTEL_NAME_SEARCH_THRESHOLD', 5); + Configuration::updateValue('WK_SEARCH_AUTO_FOCUS_NEXT_FIELD', 1); Configuration::updateValue('WK_ROOM_LEFT_WARNING_NUMBER', 10); Configuration::updateValue('WK_HTL_ESTABLISHMENT_YEAR', 2010); diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php index 5fad5a10b..e40082572 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php @@ -94,7 +94,7 @@ class RoomTypeServiceProductCartDetail extends ObjectModel )) { $updateQty = $product['quantity']; if (Product::getProductPriceCalculation($product['id_product']) == Product::PRICE_CALCULATION_METHOD_PER_DAY) { - $objHotelCartBookingData = new HotelCartBookingData($idHtlCartData); + $objHotelCartBookingData = new HotelCartBookingData($htlCartBookingId); $numdays = HotelHelper::getNumberOfDays($objHotelCartBookingData->date_from, $objHotelCartBookingData->date_to); $updateQty *= $numdays; } diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php index bfbf62f2b..7300566ee 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php @@ -72,8 +72,10 @@ class RoomTypeServiceProductPrice extends ObjectModel if ($result = Db::getInstance()->getRow(' SELECT spp.`price`, spp.`id_tax_rules_group`, p.`auto_add_to_cart`, p.`price_addition_type` FROM `'._DB_PREFIX_.'product` p - LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` sp ON (sp.`id_product` = p.`id_product`) - LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product_price` spp ON (spp.`id_product` = p.`id_product`) + LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` sp + ON (sp.`id_product` = p.`id_product`) + LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product_price` spp + ON (spp.`id_product` = sp.`id_product` AND spp.`id_element` = sp.`id_element` AND spp.`element_type` = sp.`element_type`) WHERE p.`id_product`='.(int)$idProduct. ' AND sp.`id_element`='.(int)$idElement. ' AND sp.`element_type`='.(int)$elementType) diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php index 30b34ea38..2d8d7ff6d 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminHotelGeneralSettingsController.php @@ -81,6 +81,32 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController 'hint' => $this->l('This option can be disabled if only one active hotel in the website. In case of more than one active hotel, Hotel Name will always be shown in the search panel.'), ), + 'WK_SEARCH_AUTO_FOCUS_NEXT_FIELD' => array( + 'title' => $this->l('Focus next field automatically'), + 'cast' => 'intval', + 'type' => 'bool', + 'default' => '0', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + ), + array( + 'id' => 'active_off', + 'value' => 0, + ), + ), + 'hint' => $this->l('Enable if you want the next booking search field to be focused automatically after setting value for a field.'), + ), + 'WK_HOTEL_NAME_SEARCH_THRESHOLD' => array( + 'title' => $this->l('Hotel name search threshold'), + 'type' => 'text', + 'required' => true, + 'validation' => 'isUnsignedInt', + 'hint' => $this->l('Enter the number of hotels after which user can search hotel by name.'), + 'desc' => $this->l('Set to 0 to always show the search box.'), + 'class' => 'fixed-width-xxl', + ), ), 'submit' => array( 'title' => $this->l('Save'), @@ -312,6 +338,8 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController public function postProcess() { if (Tools::isSubmit('submitOptions'.$this->table)) { + $hotelNameSearchThreshold = Tools::getValue('WK_HOTEL_NAME_SEARCH_THRESHOLD'); + // check if field is atleast in default language. Not available in default prestashop $defaultLangId = Configuration::get('PS_LANG_DEFAULT'); $objDefaultLanguage = Language::getLanguage((int) $defaultLangId); @@ -324,6 +352,12 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController // End occupancy fields validation + if (!$hotelNameSearchThreshold && $hotelNameSearchThreshold !== '0') { + $this->errors[] = $this->l('Hotel name search threshold field is required.'); + } elseif (!Validate::isUnsignedInt($hotelNameSearchThreshold)) { + $this->errors[] = $this->l('Hotel name search threshold field is invalid.'); + } + if (!trim(Tools::getValue('WK_HTL_CHAIN_NAME_'.$defaultLangId))) { $this->errors[] = $this->l('Hotel chain name is required at least in ').$objDefaultLanguage['name']; } else { diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php index 0edf2d641..04b02fe59 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php @@ -42,6 +42,9 @@ class AdminHotelRoomsBookingController extends ModuleAdminController $objCart = new Cart($this->context->cookie->id_cart); if (Validate::isLoadedObject($objCart) && !$objCart->orderExists()) { $this->context->cart = $objCart; + + // validate cart for removing invalid data from cart + HotelCartBookingData::validateCartBookings(); } else { $this->context->cookie->id_cart = 0; // remove invalid id_cart $this->context->cart = new Cart(); @@ -63,15 +66,6 @@ class AdminHotelRoomsBookingController extends ModuleAdminController $objCustomer->id_guest = (int) $this->context->cookie->id_guest; $this->context->customer = $objCustomer; - if ($this->context->employee->isSuperAdmin()) { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_SUPERADMIN'; - } else { - $backOrderConfigKey = 'PS_BACKDATE_ORDER_EMPLOYEES'; - } - if (!Configuration::get($backOrderConfigKey)) { - $htlCart = new HotelCartBookingData(); - $htlCart->removeBackdateRoomsFromCart($this->context->cart->id); - } } protected function createNewCart() @@ -819,19 +813,6 @@ class AdminHotelRoomsBookingController extends ModuleAdminController $objHotelRoomType = new HotelRoomType(); foreach ($booking_data['rm_data'] as $key_bk_data => $value_bk_data) { $booking_data['rm_data'][$key_bk_data]['room_type_info'] = $objHotelRoomType->getRoomTypeInfoByIdProduct($value_bk_data['id_product']); - - // set default occupancies in required format - $occupancy = array( - array( - 'adults' => $value_bk_data['adults'], - 'children' => 0, - 'child_ages' => array(), - ), - ); - - $booking_data['rm_data'][$key_bk_data]['occupancies'] = $occupancy; - $booking_data['rm_data'][$key_bk_data]['occupancy_adults'] = $booking_data['rm_data'][$key_bk_data]['adults']; // only one room by default - if (isset($value_bk_data['data']['booked']) && $value_bk_data['data']['booked']) { foreach ($value_bk_data['data']['booked'] as $booked_k1 => $booked_v1) { if (isset($booked_v1['detail']) && $booked_v1['detail']) { diff --git a/modules/hotelreservationsystem/hotelreservationsystem.php b/modules/hotelreservationsystem/hotelreservationsystem.php index bf6473245..76a6c3bae 100644 --- a/modules/hotelreservationsystem/hotelreservationsystem.php +++ b/modules/hotelreservationsystem/hotelreservationsystem.php @@ -509,6 +509,7 @@ class HotelReservationSystem extends Module 'htl_room_type_global_demand', 'htl_room_type_global_demand_advance_option', 'htl_order_refund_rules', + 'htl_settings_link', ); //If Admin update new language when we do entry in module all lang tables. HotelHelper::updateLangTables($newIdLang, $langTables); diff --git a/modules/hotelreservationsystem/views/templates/admin/hotel_rooms_booking/helpers/view/_partials/booking-rooms.tpl b/modules/hotelreservationsystem/views/templates/admin/hotel_rooms_booking/helpers/view/_partials/booking-rooms.tpl index 20013d8d0..70bcd1cd3 100644 --- a/modules/hotelreservationsystem/views/templates/admin/hotel_rooms_booking/helpers/view/_partials/booking-rooms.tpl +++ b/modules/hotelreservationsystem/views/templates/admin/hotel_rooms_booking/helpers/view/_partials/booking-rooms.tpl @@ -56,79 +56,40 @@