diff --git a/.gitignore b/.gitignore index ae0a05c8f..9ce95681a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ composer.lock img/** !/img/404.gif +!/img/.htaccess !/img/admin/ !/img/admin/*.gif !/img/admin/*.png diff --git a/admin/backups/.htaccess b/admin/backups/.htaccess index 93169e4eb..3de9e4008 100644 --- a/admin/backups/.htaccess +++ b/admin/backups/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/admin/export/.htaccess b/admin/export/.htaccess index 93169e4eb..3de9e4008 100644 --- a/admin/export/.htaccess +++ b/admin/export/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/admin/import/.htaccess b/admin/import/.htaccess index 93169e4eb..3de9e4008 100644 --- a/admin/import/.htaccess +++ b/admin/import/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/admin/tabs/.htaccess b/admin/tabs/.htaccess index 93169e4eb..3de9e4008 100644 --- a/admin/tabs/.htaccess +++ b/admin/tabs/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/admin/themes/default/template/controllers/addresses/helpers/form/form.tpl b/admin/themes/default/template/controllers/addresses/helpers/form/form.tpl index ec102910d..9fd0f69e6 100644 --- a/admin/themes/default/template/controllers/addresses/helpers/form/form.tpl +++ b/admin/themes/default/template/controllers/addresses/helpers/form/form.tpl @@ -29,31 +29,29 @@ {if $input.name == 'vat_number'}
{/if} - - {if $input.type == 'text_customer' && !isset($customer)} - - {else} - {$smarty.block.parent} - {/if} + {$smarty.block.parent} {/block} -{block name="field"} +{block name="input"} {if $input.type == 'text_customer'} {if isset($customer)} -
- - {$customer->lastname} {$customer->firstname} ({$customer->email}) - -
+ + {$customer->lastname} {$customer->firstname} ({$customer->email}) + - {else} - - -
- - -
- {/if} + function resetCustomerRelatedAddressFields() { + $('input[name=firstname]').val(''); + $('input[name=lastname]').val(''); + $('input[name=company]').val(''); + $('input[name=id_customer]').val(''); + } + {else} {$smarty.block.parent} {/if} diff --git a/admin/themes/default/template/controllers/login/header.tpl b/admin/themes/default/template/controllers/login/header.tpl index aff412764..d1d17ce21 100644 --- a/admin/themes/default/template/controllers/login/header.tpl +++ b/admin/themes/default/template/controllers/login/header.tpl @@ -39,7 +39,7 @@ - {$shop_name} {if $meta_title != ''}{if isset($navigationPipe)}{$navigationPipe|escape:'html':'UTF-8'}{else}>{/if} {$meta_title}{/if} (PrestaShop™) + {$shop_name} {if $meta_title != ''}{if isset($navigationPipe)}{$navigationPipe|escape:'html':'UTF-8'}{else}>{/if} {$meta_title}{/if} (QloApps™) {if isset($css_files)} {foreach from=$css_files key=css_uri item=media} diff --git a/admin/themes/default/template/controllers/products/additionalfacilities.tpl b/admin/themes/default/template/controllers/products/additionalfacilities.tpl index c3a58eb34..eb40e083e 100644 --- a/admin/themes/default/template/controllers/products/additionalfacilities.tpl +++ b/admin/themes/default/template/controllers/products/additionalfacilities.tpl @@ -43,7 +43,7 @@ {l s='Price'} - {l s='Tax rate'} + {l s='Tax rule'} {l s='Per day price calculation'} diff --git a/admin/themes/default/template/controllers/products/serviceproduct.tpl b/admin/themes/default/template/controllers/products/serviceproduct.tpl index e7b2001cb..ac93c1ed9 100644 --- a/admin/themes/default/template/controllers/products/serviceproduct.tpl +++ b/admin/themes/default/template/controllers/products/serviceproduct.tpl @@ -27,7 +27,7 @@ {l s='Price'} - {l s='Tax'} + {l s='Tax rule'} diff --git a/admin/themes/default/template/helpers/options/options.tpl b/admin/themes/default/template/helpers/options/options.tpl index 24a6094cd..527850f73 100644 --- a/admin/themes/default/template/helpers/options/options.tpl +++ b/admin/themes/default/template/helpers/options/options.tpl @@ -138,6 +138,9 @@ {elseif isset($input.empty_message)} {$input.empty_message} + {else} + {/if}
{elseif $field['type'] == 'bool'} diff --git a/classes/.htaccess b/classes/.htaccess index 93169e4eb..3de9e4008 100644 --- a/classes/.htaccess +++ b/classes/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/classes/BoOrder.php b/classes/BoOrder.php new file mode 100644 index 000000000..b6046c5c8 --- /dev/null +++ b/classes/BoOrder.php @@ -0,0 +1,31 @@ + +* @copyright 2010-2022 Webkul IN +* @license https://store.webkul.com/license.html +*/ + +class BoOrder extends PaymentModule +{ + public $active = 1; + public $name = 'bo_order'; + + public function __construct() + { + $this->displayName = $this->l('Back office order'); + $this->validateOrderAmount = false; + } +} \ No newline at end of file diff --git a/classes/Customer.php b/classes/Customer.php index a8c4c3609..a1ef3279e 100644 --- a/classes/Customer.php +++ b/classes/Customer.php @@ -294,21 +294,37 @@ class CustomerCore extends ObjectModel } /** - * Return customers list + * Returns a list of customers. * - * @param null|bool $only_active Returns only active customers when true - * @return array Customers + * @param null|bool $active Optional. Filter customers by their active status. If null, no filter is applied. + * @param null|bool $deleted Optional. Filter customers by their deleted status. If null, no filter is applied. + * @param null|bool $havingAddress Optional. Filter customers having|not having address. If true, only customers having an address are returned. + * If false, only customers without an address are returned. If null, no filter is applied. + * @return array List of customers matching the specified criteria. */ - public static function getCustomers($only_active = null) + public static function getCustomers($active = null, $deleted = null, $havingAddress = null) { - $sql = 'SELECT `id_customer`, `email`, `firstname`, `lastname` - FROM `'._DB_PREFIX_.'customer` - WHERE 1 '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER). - ($only_active ? ' AND `active` = 1' : '').' - ORDER BY `id_customer` ASC'; + $sqlSelect = 'SELECT c.`id_customer`, c.`email`, c.`firstname`, c.`lastname`'; + $sqlFrom = 'FROM `'._DB_PREFIX_.'customer` c'; + $sqlJoin = ''; + $sqlWhere = 'WHERE 1 '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER). + (!is_null($active) ? ' AND c.`active` = '.(int) $active: ' ' ). + (!is_null($deleted) ? ' AND c.`deleted` = '.(int) $deleted : ' '); + $sqlOrderBy = 'ORDER BY c.`id_customer` ASC'; + $sqlGroupBy = 'GROUP BY c.`id_customer`'; + + if (!is_null($havingAddress)) { + $sqlJoin .= ' LEFT JOIN `'._DB_PREFIX_.'address` a + ON a.`id_customer` = c.`id_customer` AND a.`deleted`=0'; + $sqlWhere .= (($havingAddress) ? ' AND a.`id_address` IS NOT NULL': ' AND a.`id_address` IS NULL'); + } + + $sql = $sqlSelect .' '. $sqlFrom.' '.$sqlJoin.' '.$sqlWhere.' '.$sqlGroupBy.' '.$sqlOrderBy; + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); } + /** * Return customer instance from its e-mail (optionnaly check password) * @@ -951,4 +967,5 @@ class CustomerCore extends ObjectModel $sql_filter .= Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'main'); return parent::getWebserviceObjectList($sql_join, $sql_filter, $sql_sort, $sql_limit); } + } diff --git a/classes/PaymentModule.php b/classes/PaymentModule.php index d7e75b7d2..cea68af08 100644 --- a/classes/PaymentModule.php +++ b/classes/PaymentModule.php @@ -33,6 +33,7 @@ abstract class PaymentModuleCore extends Module public $currencies = true; public $currencies_mode = 'checkbox'; public $payment_type = OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT; + public $validateOrderAmount = true; public function install() { @@ -162,7 +163,7 @@ abstract class PaymentModuleCore extends Module */ public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, - $secure_key = false, Shop $shop = null) + $secure_key = false, Shop $shop = null, $send_mails = true) { if (self::DEBUG_MODE) { PrestaShopLogger::addLog('PaymentModule::validateOrder - Function called', 1, null, 'Cart', (int)$id_cart, true); @@ -418,8 +419,7 @@ abstract class PaymentModuleCore extends Module // If webservice order request then no need to impose equal amounts(total cart and sent amount) condition if ($order_status->logable && number_format($cart_total_paid, _PS_PRICE_COMPUTE_PRECISION_) != number_format($amount_paid, _PS_PRICE_COMPUTE_PRECISION_) - && $this->name != 'wsorder' - && $this->name != 'bo_order' + && ($this->validateOrderAmount) ) { // if customer is paying full payment amount $id_order_state = Configuration::get('PS_OS_ERROR'); @@ -684,24 +684,25 @@ abstract class PaymentModuleCore extends Module if ($voucher->add()) { // If the voucher has conditions, they are now copied to the new voucher CartRule::copyConditions($cart_rule['obj']->id, $voucher->id); - - $params = array( - '{voucher_amount}' => Tools::displayPrice($voucher->reduction_amount, $this->context->currency, false), - '{voucher_num}' => $voucher->code, - '{firstname}' => $this->context->customer->firstname, - '{lastname}' => $this->context->customer->lastname, - '{id_order}' => $order->reference, - '{order_name}' => $order->getUniqReference() - ); - Mail::Send( - (int)$order->id_lang, - 'voucher', - sprintf(Mail::l('New voucher for your order %s', (int)$order->id_lang), $order->reference), - $params, - $this->context->customer->email, - $this->context->customer->firstname.' '.$this->context->customer->lastname, - null, null, null, null, _PS_MAIL_DIR_, false, (int)$order->id_shop - ); + if ($send_mails) { + $params = array( + '{voucher_amount}' => Tools::displayPrice($voucher->reduction_amount, $this->context->currency, false), + '{voucher_num}' => $voucher->code, + '{firstname}' => $this->context->customer->firstname, + '{lastname}' => $this->context->customer->lastname, + '{id_order}' => $order->reference, + '{order_name}' => $order->getUniqReference() + ); + Mail::Send( + (int)$order->id_lang, + 'voucher', + sprintf(Mail::l('New voucher for your order %s', (int)$order->id_lang), $order->reference), + $params, + $this->context->customer->email, + $this->context->customer->firstname.' '.$this->context->customer->lastname, + null, null, null, null, _PS_MAIL_DIR_, false, (int)$order->id_shop + ); + } } } @@ -1050,10 +1051,12 @@ abstract class PaymentModuleCore extends Module // Set the order status $new_history = new OrderHistory(); $new_history->id_order = (int)$order->id; - $new_history->changeIdOrderState((int)$id_order_state, $order, true); - - $new_history->addWithemail(true, $extra_vars); + if ($send_mails) { + $new_history->addWithemail(true, $extra_vars); + } else { + $new_history->add(true); + } // Switch to back order if needed $objHotelBookingDetail = new HotelBookingDetail(); @@ -1089,7 +1092,11 @@ abstract class PaymentModuleCore extends Module $history = new OrderHistory(); $history->id_order = (int)$order->id; $history->changeIdOrderState($id_order_state, $order, true); - $history->addWithemail(); + if ($send_mails) { + $history->addWithemail(); + } else { + $history->add(); + } } unset($order_detail); @@ -1098,7 +1105,11 @@ abstract class PaymentModuleCore extends Module $order = new Order((int)$order->id); // Send an e-mail to customer (one order = one email) - if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && $this->context->customer->id) { + if ($id_order_state != Configuration::get('PS_OS_ERROR') + && $id_order_state != Configuration::get('PS_OS_CANCELED') + && $this->context->customer->id + && $send_mails + ) { $invoice = new Address($order->id_address_invoice); $delivery = new Address($order->id_address_delivery); $delivery_state = $delivery->id_state ? new State($delivery->id_state) : false; @@ -1327,9 +1338,7 @@ abstract class PaymentModuleCore extends Module } } } - if ($idHotel - && Validate::isLoadedObject($objHotel = new HotelBranchInformation($idHotel)) - ) { + if ($idHotel && Validate::isLoadedObject($objHotel = new HotelBranchInformation($idHotel))) { if (Configuration::get('PS_ORDER_CONF_MAIL_TO_HOTEL_MANAGER')){ // If order currenct state is overbooking, the send overbooking email or send order confirmation email if ($isOverBookingStatus) { diff --git a/classes/Validate.php b/classes/Validate.php index 9a080dd61..65fa7f790 100644 --- a/classes/Validate.php +++ b/classes/Validate.php @@ -364,7 +364,7 @@ class ValidateCore */ public static function isCityName($city) { - return preg_match(Tools::cleanNonUnicodeSupport('/^[^!<>;?=+@#"°{}_$%]*$/u'), $city); + return preg_match(Tools::cleanNonUnicodeSupport('/^\p{L}+[^!<>;?=+@#"°{}_$%]*$/u'), $city); } /** diff --git a/classes/cache/Cache.php b/classes/cache/Cache.php index d13b97791..96b0fed3f 100644 --- a/classes/cache/Cache.php +++ b/classes/cache/Cache.php @@ -502,7 +502,7 @@ abstract class CacheCore $this->_deleteMulti($invalidKeys); if ($keyToKeep) { - $this->sql_tables_cached[$table][$keyToKeep] = $toKeep ?? null; + $this->sql_tables_cached[$table][$keyToKeep] = isset($toKeep) ? $toKeep : null; } } $this->adjustTableCacheSize = false; diff --git a/classes/pdf/HTMLTemplateInvoice.php b/classes/pdf/HTMLTemplateInvoice.php index 3d28fca40..6065a4d45 100644 --- a/classes/pdf/HTMLTemplateInvoice.php +++ b/classes/pdf/HTMLTemplateInvoice.php @@ -822,7 +822,9 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate */ protected function getTemplateByCountry($iso_country) { - $file = Configuration::get('PS_INVOICE_MODEL'); + // $file = Configuration::get('PS_INVOICE_MODEL'); + // @todo redesign invoice template for b2b, for now we have ony one template design. + $file = 'invoice'; // try to fetch the iso template $template = $this->getTemplate($file.'.'.$iso_country); diff --git a/classes/webservice/WebserviceOrder.php b/classes/webservice/WebserviceOrder.php index 4b1d337e4..860fcc0c0 100644 --- a/classes/webservice/WebserviceOrder.php +++ b/classes/webservice/WebserviceOrder.php @@ -26,5 +26,6 @@ class WebserviceOrderCore extends PaymentModule public function __construct() { $this->displayName = $this->l('Order from API'); + $this->validateOrderAmount = false; } } diff --git a/config/.htaccess b/config/.htaccess index 93169e4eb..3de9e4008 100644 --- a/config/.htaccess +++ b/config/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/config/xml/.htaccess b/config/xml/.htaccess index 93169e4eb..3de9e4008 100644 --- a/config/xml/.htaccess +++ b/config/xml/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/controllers/admin/AdminAddressesController.php b/controllers/admin/AdminAddressesController.php index 83a646cb6..5f6bb472d 100644 --- a/controllers/admin/AdminAddressesController.php +++ b/controllers/admin/AdminAddressesController.php @@ -112,18 +112,43 @@ class AdminAddressesControllerCore extends AdminController public function renderForm() { + $customerField =array( + 'type' => 'text_customer', + 'label' => $this->l('Customer'), + 'name' => 'id_customer', + 'required' => false, + ); + if ($this->loadObject(true) + && !$this->object->id + && !Tools::getValue('liteDisplaying') + ) { + $customerEmails = array(array( + 'email' => $this->l('Select Customer'), + 'id_customer' => 0, + 'id_address'=> 0 + )); + $customerEmails = array_merge($customerEmails, Customer::getCustomers(null, 0, 0)); + $customerField = array( + 'type' => 'select', + 'label' => $this->l('Customer'), + 'name' => 'id_customer', + 'required' => true, + 'class' => 'chosen', + 'options' => array( + 'query' => $customerEmails, + 'id' => 'id_customer', + 'name' => 'email' + ), + ); + } + $this->fields_form = array( 'legend' => array( 'title' => $this->l('Addresses'), 'icon' => 'icon-envelope-alt' ), 'input' => array( - array( - 'type' => 'text_customer', - 'label' => $this->l('Customer'), - 'name' => 'id_customer', - 'required' => false, - ), + $customerField, array( 'type' => 'text', 'label' => $this->l('Identification Number'), @@ -191,9 +216,8 @@ class AdminAddressesControllerCore extends AdminController } $this->tpl_form_vars = array( - 'customer' => isset($customer) ? $customer : null, - 'tokenCustomer' => isset($token_customer) ? $token_customer : null, - 'back_url' => urldecode(Tools::getValue('back')) + 'customer' => (isset($customer) && ($this->object->id || Tools::getValue('liteDisplaying'))) ? $customer : null, + 'tokenCustomer' => isset($token_customer) ? $token_customer : null ); // Order address fields depending on country format @@ -503,7 +527,7 @@ class AdminAddressesControllerCore extends AdminController return $out; } - /** + /** * Method called when an ajax request is made * @see AdminController::postProcess() */ diff --git a/controllers/admin/AdminCustomersController.php b/controllers/admin/AdminCustomersController.php index 008ef64c6..fe099e12c 100644 --- a/controllers/admin/AdminCustomersController.php +++ b/controllers/admin/AdminCustomersController.php @@ -739,6 +739,9 @@ class AdminCustomersControllerCore extends AdminController $helper->color = 'color4'; $helper->title = $this->l('New Customers', null, null, false); $nbDaysNewCustomers = Validate::isUnsignedInt(Configuration::get('PS_KPI_NEW_CUSTOMERS_NB_DAYS')) ? Configuration::get('PS_KPI_NEW_CUSTOMERS_NB_DAYS') : 30; + $date_from = date('Y-m-d', strtotime('-'.$nbDaysNewCustomers.' day')); + $date_to = date('Y-m-d'); + $helper->href = $this->context->link->getAdminLink('AdminCustomers').'&customerFilter_date_add[]='.$date_from.'&customerFilter_date_add[]='.$date_to; $helper->subtitle = sprintf($this->l('%d Days', null, null, false), (int) $nbDaysNewCustomers); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=total_new_customers'; $helper->tooltip = $this->l('The total number of new customers who registered in given period of time.', null, null, false); @@ -958,7 +961,7 @@ class AdminCustomersControllerCore extends AdminController // If customer is going to be deleted permanently then if customer has orders the change this customer as an anonymous customer if (Validate::isLoadedObject($objCustomer = $this->loadObject())) { if ($this->delete_mode == 'real' && Order::getCustomerOrders($objCustomer->id, true)) { - $objCustomer->email = 'anonymous'.'-'.$objCustomer->id.'@'.Tools::getShopDomain(); + $objCustomer->email = 'anonymous'.'-'.$objCustomer->id.'@'.Tools::link_rewrite(Configuration::get('PS_SHOP_NAME')).'_anonymous.com'; $objCustomer->deleted = 1; if (!$objCustomer->update()) { $this->errors[] = Tools::displayError('Some error ocurred while deleting the Customer'); @@ -1040,7 +1043,7 @@ class AdminCustomersControllerCore extends AdminController $this->redirect_after = false; } // Check that the new email is not already in use - $customer_email = strval(Tools::getValue('email')); + $customer_email = trim(strval(Tools::getValue('email'))); $customer = new Customer(); if (Validate::isEmail($customer_email)) { $customer->getByEmail($customer_email); @@ -1048,6 +1051,9 @@ class AdminCustomersControllerCore extends AdminController $this->errors[] = Tools::displayError('An account already exists for this email address:').' '.$customer_email; $this->display = 'edit'; return $customer; + } elseif (Customer::customerExists($customer_email, false, true)) { + $this->errors[] = Tools::displayError('The email is already associated with a banned account. Please use a different one.'); + $this->display = 'edit'; } elseif (trim(Tools::getValue('passwd')) == '') { $this->validateRules(); $this->errors[] = Tools::displayError('Password can not be empty.'); @@ -1068,7 +1074,7 @@ class AdminCustomersControllerCore extends AdminController public function processUpdate() { if (Validate::isLoadedObject($this->object)) { - $customer_email = strval(Tools::getValue('email')); + $customer_email = trim(strval(Tools::getValue('email'))); // check if e-mail already used if ($customer_email != $this->object->email) { @@ -1297,4 +1303,41 @@ class AdminCustomersControllerCore extends AdminController die('ok'); } } + + public function ajaxProcessVerifyCustomerEmail() + { + $response = array('status' => true); + $idCustomer = Tools::getValue('id_customer', 0); + if (($email = trim(strval(Tools::getValue('email')))) + && ($idCustomerByEmail = Customer::customerExists($email, true, false)) + && (Validate::isLoadedObject($objCustomer = new Customer($idCustomerByEmail))) + && $idCustomerByEmail != $idCustomer // the admin is trying to add/update the account + ) { + $response['status'] = false; + if ($objCustomer->deleted) { + $response['msg'] = Tools::displayError('This email is already associated with a banned account. Please use a different one.'); + } else { + $response['msg'] = Tools::displayError('An account already exists for this email address.'); + } + } + + $this->ajaxDie(json_encode($response)); + } + + public function setMedia() + { + parent::setMedia(); + if ($this->loadObject(true) + && ($this->display == 'edit' || $this->display == 'add') + ) { + $idCustomer = $this->object->id ? $this->object->id : 0; + Media::addJSDef( + array( + 'customer_controller_url' => self::$currentIndex.'&token='.$this->token, + 'id_customer' => $idCustomer + ) + ); + $this->addJS(_PS_JS_DIR_.'admin/customers.js'); + } + } } diff --git a/controllers/admin/AdminOrderPreferencesController.php b/controllers/admin/AdminOrderPreferencesController.php index 4068a6f09..241ed1c29 100644 --- a/controllers/admin/AdminOrderPreferencesController.php +++ b/controllers/admin/AdminOrderPreferencesController.php @@ -82,6 +82,7 @@ class AdminOrderPreferencesControllerCore extends AdminController ) ); + $maxOrderDate = Tools::getValue('MAX_GLOBAL_BOOKING_DATE', Configuration::get('MAX_GLOBAL_BOOKING_DATE')); $this->fields_options = array( 'order_restrict' => array( 'title' => $this->l('Order Restrict'), @@ -92,11 +93,13 @@ class AdminOrderPreferencesControllerCore extends AdminController 'hint' => $this->l('Maximum date of check-out for which rooms of your hotels can be booked.'), 'type' => 'text', 'id' => 'max_global_book_date', + 'auto_value' => false, + 'value' => date('d-m-Y', strtotime($maxOrderDate)), 'class' => 'fixed-width-xxl readonly', ), 'GLOBAL_PREPARATION_TIME' => array( - 'title' => $this->l('Preparation time'), - 'hint' => $this->l('Number of days required to prepare a room for a guest\'s stay. For example, if you set this value to 3 and someone is booking on 2nd of March he can only book rooms for dates from and after 3 days, i.e, 5th of March.'), + 'title' => $this->l('Minimum booking offset'), + 'hint' => $this->l('The minimum booking offset is the minimum number of days before the check-in date that a guest must book a room. For example, if you set this value to 3 and someone is booking on 2nd of March he can only book rooms for dates from and after 3 days, i.e, 5th of March.'), 'desc' => $this->l('Set to 0 to disable this feature.'), 'type' => 'text', 'class' => 'fixed-width-xl', @@ -329,6 +332,7 @@ class AdminOrderPreferencesControllerCore extends AdminController $this->errors[] = Tools::displayError('Please assign a valid CMS page for Terms and Conditions.'); } + $_POST['MAX_GLOBAL_BOOKING_DATE'] = date('Y-m-d', strtotime(Tools::getValue('MAX_GLOBAL_BOOKING_DATE'))); $maxGlobalBookingDate = Tools::getValue('MAX_GLOBAL_BOOKING_DATE'); $globalPreparationTime = Tools::getValue('GLOBAL_PREPARATION_TIME'); $maxGlobalBookingDateFormatted = date('Y-m-d', strtotime($maxGlobalBookingDate)); @@ -342,9 +346,9 @@ class AdminOrderPreferencesControllerCore extends AdminController } if ($globalPreparationTime === '') { - $this->errors[] = Tools::displayError('Field \'Preparation time\' can not be empty.'); + $this->errors[] = Tools::displayError('Field \'Minimum booking offset\' can not be empty.'); } elseif ($globalPreparationTime !== '0' && !Validate::isUnsignedInt($globalPreparationTime)) { - $this->errors[] = Tools::displayError('Field \'Preparation time\' is invalid.'); + $this->errors[] = Tools::displayError('Field \'Minimum booking offset\' is invalid.'); } } diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index 0c0af163a..731570bdf 100644 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -24,17 +24,6 @@ * International Registered Trademark & Property of PrestaShop SA */ -class BoOrder extends PaymentModule -{ - public $active = 1; - public $name = 'bo_order'; - - public function __construct() - { - $this->displayName = $this->l('Back office order'); - } -} - /** * @property Order $object */ diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 7cec3f256..626a7984b 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -201,13 +201,15 @@ class AdminProductsControllerCore extends AdminController LEFT JOIN `'._DB_PREFIX_.'address` aa ON (aa.`id_hotel` = hb.`id`) LEFT JOIN `'._DB_PREFIX_.'feature_product` fp ON (fp.`id_product` = a.`id_product`) LEFT JOIN `'._DB_PREFIX_.'htl_room_type_demand` hrtd ON (hrtd.`id_product` = a.`id_product`) - LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` hrtsp ON ((hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_HOTEL.' AND hrtsp.`id_element` = hrt.`id_hotel`) OR (hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE.' AND hrtsp.`id_element` = a.`id_product`))'; + LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` hrtsp ON ((hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_HOTEL.' AND hrtsp.`id_element` = hrt.`id_hotel`) OR (hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE.' AND hrtsp.`id_element` = a.`id_product`)) + LEFT JOIN `'._DB_PREFIX_.'htl_advance_payment` hap ON (hap.`id_product` = a.`id_product`)'; - $this->_select .= ' (SELECT COUNT(hri.`id`) FROM `'._DB_PREFIX_.'htl_room_information` hri WHERE hri.`id_product` = a.`id_product`) as num_rooms, '; + $this->_select .= ' a.`show_at_front`, (SELECT COUNT(hri.`id`) FROM `'._DB_PREFIX_.'htl_room_information` hri WHERE hri.`id_product` = a.`id_product`) as num_rooms, '; $this->_select .= 'hrt.`adults`, hrt.`children`, hrt.`max_guests`, hb.`id` as id_hotel, aa.`city`, hbl.`hotel_name`, '; $this->_select .= 'shop.`name` AS `shopname`, a.`id_shop_default`, '; $this->_select .= $alias_image.'.`id_image` AS `id_image`, cl.`name` AS `name_category`, '.$alias.'.`price`, 0 AS `price_final`, a.`is_virtual`, pd.`nb_downloadable`, sav.`quantity` AS `sav_quantity`, '.$alias.'.`active`, IF(sav.`quantity`<=0, 1, 0) AS `badge_danger`'; - $this->_select .= ', IFNULL((SELECT hap.`active` FROM `'._DB_PREFIX_.'htl_advance_payment` hap WHERE hap.`id_product` = a.`id_product`), 0) AS advance_payment'; + $this->_select .= ', IFNULL(hap.`active`, 0) AS advance_payment'; + $this->_select .= ', IF(IFNULL(hap.`active`, 0), 1, 0) badge_success, IF(IFNULL(hap.`active`, 0), 0, 1) badge_danger '; if ($join_category) { $this->_join .= ' INNER JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = a.`id_product` AND cp.`id_category` = '.(int)$this->_category->id.') '; @@ -319,10 +321,23 @@ class AdminProductsControllerCore extends AdminController 'optional' => true, ); + $this->fields_list['show_at_front'] = array( + 'title' => $this->l('Show at front'), + 'align' => 'text-center', + 'type' => 'bool', + 'active' => 'show_at_front', + 'optional' => true, + 'havingFilter' => true, + 'visible_default' => true, + 'orderby' => false, + ); + if (Configuration::get('WK_ALLOW_ADVANCED_PAYMENT')) { $this->fields_list['advance_payment'] = array( 'title' => $this->l('Advance Payment'), - 'active' => 'advance_payment', + 'callback' => 'getAdvancePaymentStatus', + 'badge_success' => true, + 'badge_danger' => true, 'align' => 'text-center', 'type' => 'bool', 'optional' => true, @@ -431,6 +446,18 @@ class AdminProductsControllerCore extends AdminController } } + public function getAdvancePaymentStatus($val, $row) + { + if ($val) { + $str_return = $this->l('Yes'); + } else { + $str_return = $this->l('No'); + } + + return $str_return; + } + + private function buildCategoryOptions($category) { $space = str_repeat(' ', 5 * (($category['level_depth'] - $this->objLocationsCategory->level_depth) - 1)); @@ -816,6 +843,13 @@ class AdminProductsControllerCore extends AdminController if (!$id_hotel_new) { $id_hotel_new = $room_type_info['id_hotel']; } + + if ($product->hasAttributes()) { + Product::updateDefaultAttribute($product->id); + } else { + Product::duplicateSpecificPrices($id_product_old, $product->id); + } + $id_room_type_new = HotelRoomType::duplicateRoomType( $id_product_old, $product->id, @@ -839,11 +873,6 @@ class AdminProductsControllerCore extends AdminController } else { $this->errors[] = Tools::displayError('An error occurred while duplicating room type.'); } - if ($product->hasAttributes()) { - Product::updateDefaultAttribute($product->id); - } else { - Product::duplicateSpecificPrices($id_product_old, $product->id); - } if (!Tools::getValue('noimage') && !Image::duplicateProductImages($id_product_old, $product->id, $combination_images)) { $this->errors[] = Tools::displayError('An error occurred while copying images.'); @@ -1336,10 +1365,10 @@ class AdminProductsControllerCore extends AdminController $this->errors[] = Tools::displayError('You do not have permission to add this.'); } } - // Toggle Advance Payment - elseif (Tools::getIsset('advance_payment'.$this->table)) { + // Toggle Show at front + elseif (Tools::getIsset('show_at_front'.$this->table)) { if ($this->tabAccess['edit'] === '1') { - $this->action = 'toggleAdvancePayment'; + $this->action = 'toggleShowAtFront'; } else { $this->errors[] = Tools::displayError('You do not have permission to edit this.'); } @@ -1896,38 +1925,21 @@ class AdminProductsControllerCore extends AdminController return $res; } - public function processToggleAdvancePayment() + public function processToggleShowAtFront() { - if (Configuration::get('WK_ALLOW_ADVANCED_PAYMENT')) { - $this->loadObject(true); - if (!Validate::isLoadedObject($this->object)) { - return false; - } + if (!$this->loadObject()) { + return false; + } - if (!Product::isBookingProduct($this->object->id)) { - return false; - } + if (!Product::isBookingProduct($this->object->id)) { + return false; + } - $objHotelAdvancedPayment = new HotelAdvancedPayment(); - $roomTypeAdvancePaymentInfo = $objHotelAdvancedPayment->getIdAdvPaymentByIdProduct($this->object->id); - if ($roomTypeAdvancePaymentInfo) { - $objHotelAdvancedPayment = new HotelAdvancedPayment($roomTypeAdvancePaymentInfo['id']); - $objHotelAdvancedPayment->active = !$objHotelAdvancedPayment->active; - } else { - $objHotelAdvancedPayment->id_product = $this->object->id; - $objHotelAdvancedPayment->payment_type = ''; - $objHotelAdvancedPayment->value = ''; - $objHotelAdvancedPayment->id_currency = ''; - $objHotelAdvancedPayment->tax_include = ''; - $objHotelAdvancedPayment->calculate_from = 0; - $objHotelAdvancedPayment->active = 1; - } - - if ($objHotelAdvancedPayment->save()) { - Tools::redirectAdmin(self::$currentIndex.'&token='.$this->token.'&conf=4'); - } else { - $this->errors[] = $this->l('Something went wrong while updating Advance payment status.'); - } + $this->object->show_at_front = !$this->object->show_at_front; + if ($this->object->save()) { + Tools::redirectAdmin(self::$currentIndex.'&token='.$this->token.'&conf=4'); + } else { + $this->errors[] = $this->l('An error occurred while updating "show at front".'); } } @@ -2463,7 +2475,7 @@ class AdminProductsControllerCore extends AdminController $helper->title = $this->l('Occupied Rooms', null, null, false); $helper->subtitle = $this->l('Today', null, null, false); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=occupied_rooms'; - $helper->tooltip = $this->l('The current count of rooms that are currently occupied by guests.', null, null, false); + $helper->tooltip = $this->l('The count of rooms that are currently occupied by guests.', null, null, false); $kpis[] = $helper; $helper = new HelperKpi(); @@ -2473,7 +2485,7 @@ class AdminProductsControllerCore extends AdminController $helper->title = $this->l('Vacant Rooms', null, null, false); $helper->subtitle = $this->l('Today', null, null, false); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=vacant_rooms'; - $helper->tooltip = $this->l('The count of rooms that are currently unoccupied and available for booking.', null, null, false); + $helper->tooltip = $this->l('The count of rooms that are either booked but currently unoccupied or available for booking', null, null, false); $kpis[] = $helper; $helper = new HelperKpi(); @@ -2483,7 +2495,7 @@ class AdminProductsControllerCore extends AdminController $helper->title = $this->l('Booked Rooms', null, null, false); $helper->subtitle = $this->l('Today', null, null, false); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=booked_rooms'; - $helper->tooltip = $this->l('The number of rooms that are currently booked but not yet occupied.', null, null, false); + $helper->tooltip = $this->l('The total number of rooms that are currently booked and and awaiting guest check-in', null, null, false); $kpis[] = $helper; $helper = new HelperKpi(); @@ -2493,7 +2505,7 @@ class AdminProductsControllerCore extends AdminController $helper->title = $this->l('Disabled Rooms', null, null, false); $helper->subtitle = $this->l('Today', null, null, false); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=disabled_rooms'; - $helper->tooltip = $this->l('The number of rooms that are currently disabled.', null, null, false); + $helper->tooltip = $this->l('The total number of rooms that are currently disabled.', null, null, false); $kpis[] = $helper; $helper = new HelperKpi(); @@ -2503,7 +2515,7 @@ class AdminProductsControllerCore extends AdminController $helper->title = $this->l('Online Bookable Rooms', null, null, false); $helper->subtitle = $this->l('Today', null, null, false); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=online_bookable_rooms'; - $helper->tooltip = $this->l('The total number of rooms that can be booked only using website.', null, null, false); + $helper->tooltip = $this->l('The total number of rooms that can be booked directly from the front office.', null, null, false); $kpis[] = $helper; $helper = new HelperKpi(); @@ -2513,7 +2525,7 @@ class AdminProductsControllerCore extends AdminController $helper->title = $this->l('Offline Bookable Rooms', null, null, false); $helper->subtitle = $this->l('Today', null, null, false); $helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=offline_bookable_rooms'; - $helper->tooltip = $this->l('The number of rooms that can be booked either through website or offline channels (e.g., phone or in-person).', null, null, false); + $helper->tooltip = $this->l('The total number of rooms available for booking through the back office.', null, null, false); $kpis[] = $helper; $helper = new HelperKpi(); diff --git a/controllers/admin/AdminSpecificPriceRuleController.php b/controllers/admin/AdminSpecificPriceRuleController.php index 4694f46e3..783aced1d 100644 --- a/controllers/admin/AdminSpecificPriceRuleController.php +++ b/controllers/admin/AdminSpecificPriceRuleController.php @@ -172,6 +172,7 @@ class AdminSpecificPriceRuleControllerCore extends AdminController 'name' => 'name', 'maxlength' => 32, 'required' => true, + 'col' => 3, 'hint' => $this->l('Forbidden characters').' <>;=#{}' ), array( @@ -222,8 +223,8 @@ class AdminSpecificPriceRuleControllerCore extends AdminController 'name' => 'price', 'disabled' => ($this->object->price == -1 ? 1 : 0), 'maxlength' => 10, - 'suffix' => $this->context->currency->getSign('right'), - + 'suffix' => $this->context->currency->sign, + 'col' => 3, ), array( 'type' => 'checkbox', @@ -279,6 +280,7 @@ class AdminSpecificPriceRuleControllerCore extends AdminController 'type' => 'text', 'label' => $this->l('Reduction'), 'name' => 'reduction', + 'col' => 3, 'required' => true, ), ), @@ -297,16 +299,12 @@ class AdminSpecificPriceRuleControllerCore extends AdminController ); $price = $this->getFieldValue($this->object, 'price'); - if ($price != -1 && Validate::isPrice($price)) { - $price = number_format($price, 6); - } else { + if ($price == -1 || !Validate::isPrice($price)) { $price = ''; } $reduction = $this->getFieldValue($this->object, 'reduction'); - if (Validate::isPrice($reduction)) { - $reduction = number_format($reduction, 6); - } else { + if (!Validate::isPrice($reduction)) { $reduction = 0; } diff --git a/controllers/admin/AdminStatsController.php b/controllers/admin/AdminStatsController.php index 782f989f8..b2ef1e69b 100644 --- a/controllers/admin/AdminStatsController.php +++ b/controllers/admin/AdminStatsController.php @@ -573,20 +573,20 @@ class AdminStatsControllerCore extends AdminStatsTabController { $sql = 'SELECT p.`id_product`, ( - SELECT IFNULL(SUM(ROUND((DATEDIFF(LEAST(hbd.`date_to`, "'.pSQL($dateTo).'"), GREATEST(hbd.`date_from`, "'.pSQL($dateFrom).'")) / DATEDIFF(hbd.`date_to`, hbd.`date_from`)) * hbd.`total_price_tax_excl`, 2)), 0) + SELECT count(hbd.`id_product`) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd LEFT JOIN `'._DB_PREFIX_.'orders` o ON (o.`id_order` = hbd.`id_order`) WHERE hbd.`id_product` = p.`id_product` AND o.`valid` = 1 AND hbd.`date_to` > "'.pSQL($dateFrom).'" AND hbd.`date_from` < "'.pSQL($dateTo).'" - ) AS totalRevenue - FROM `'._DB_PREFIX_.'product` p + ) as total_booked FROM `'._DB_PREFIX_.'product` p INNER JOIN `'._DB_PREFIX_.'htl_room_type` hrt ON (hrt.`id_product` = p.`id_product`) - WHERE p.`active` = 1 AND p.`booking_product` = 1'. + WHERE p.`active` = 1 AND p.`booking_product` = 1 '. (!is_null($idHotel) ? HotelBranchInformation::addHotelRestriction($idHotel, 'hrt') : '').' - HAVING totalRevenue > 0 - ORDER BY totalRevenue DESC'; + GROUP By p.`id_product` + HAVING total_booked > 0 + ORDER BY total_booked DESC'; return Db::getInstance()->getValue($sql); } @@ -856,20 +856,36 @@ class AdminStatsControllerCore extends AdminStatsTabController break; case 'occupied_rooms': - $value = AdminStatsController::getOccupiedRooms(0); + $value = AdminStatsController::getDistinctRoomBookingsCount( + date('Y-m-d', strtotime('-1 day')), + date('Y-m-d'), + 0, + HotelBookingDetail::STATUS_CHECKED_IN + ); break; case 'vacant_rooms': - $totalAvailableRooms = AdminStatsController::getAvailableRoomsForDiscreteDates(date('Y-m-d'), null, 0); - $totalAvailableRooms = $totalAvailableRooms[strtotime(date('Y-m-d'))]; - $totalOccupiedRooms = AdminStatsController::getOccupiedRooms(0); - $value = $totalAvailableRooms - $totalOccupiedRooms; + $totalUnAvailRooms = AdminStatsController::getDisabledRoomsForDiscreteDates(date('Y-m-d'), null, 0); + $totalUnAvailRooms = $totalUnAvailRooms[strtotime(date('Y-m-d'))]; + $totalRooms = AdminStatsController::getTotalRooms(0); + $totalOccupiedRooms = AdminStatsController::getDistinctRoomBookingsCount( + date('Y-m-d', strtotime('-1 day')), + date('Y-m-d'), + 0, + HotelBookingDetail::STATUS_CHECKED_IN + ); + $value = $totalRooms - ($totalUnAvailRooms + $totalOccupiedRooms); break; case 'booked_rooms': - $value = AdminStatsController::getBookedRooms(0); + $value = AdminStatsController::getDistinctRoomBookingsCount( + date('Y-m-d'), + date('Y-m-d', strtotime('+1 day')), + 0, + HotelBookingDetail::STATUS_ALLOTED + ); break; @@ -965,6 +981,12 @@ class AdminStatsControllerCore extends AdminStatsTabController case 'average_lead_time': $dateToday = date('Y-m-d'); $value = Tools::ps_round(AdminStatsController::getAverageLeadTime(), 2); + if ($value && $value <= 1) { + $value .= ' '.$this->l('day'); + } else { + $value .= ' '.$this->l('days'); + } + break; case 'average_guest_in_booking': $dateToday = date('Y-m-d'); @@ -1103,13 +1125,14 @@ class AdminStatsControllerCore extends AdminStatsTabController ); } - public static function getTotalRooms($idHotel = null) + public static function getTotalRooms($idHotel = null, $active = null) { $sql = 'SELECT COUNT(hri.`id`) FROM `'._DB_PREFIX_.'htl_room_information` hri INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = hri.`id_product`) WHERE p.`booking_product` = 1 '. + (!is_null($active) ? ' AND p.`active` ='.(int) $active : ' '). (!is_null($idHotel) ? HotelBranchInformation::addHotelRestriction($idHotel, 'hri') : ''); return Db::getInstance()->getValue($sql); @@ -1123,16 +1146,7 @@ class AdminStatsControllerCore extends AdminStatsTabController $occupancyData = array('count_total' => 0, 'count_occupied' => 0, 'count_available' => 0, 'count_unavailable' => 0); - $countTotal = Db::getInstance()->getValue( - 'SELECT COUNT(hri.`id`) - FROM `'._DB_PREFIX_.'htl_room_information` hri - INNER JOIN `'._DB_PREFIX_.'htl_branch_info` hbi - ON (hbi.`id` = hri.`id_hotel`) - LEFT JOIN `'._DB_PREFIX_.'product` p - ON (p.`id_product` = hri.`id_product`) - WHERE p.`active` = 1'. - HotelBranchInformation::addHotelRestriction($idsHotel, 'hri') - ); + $countTotal = self::getTotalRooms($idsHotel, true); $occupancyData['count_total'] = $countTotal; // Occupied rooms are booked rooms that are not refunded in the date range @@ -1417,7 +1431,27 @@ class AdminStatsControllerCore extends AdminStatsTabController return $result; } - public static function getTotalOccupiedRooms($dateFrom, $dateTo, $idHotel = null) + public static function getDistinctRoomBookingsCount($dateFrom = false, $dateTo = false, $idHotel = null, $roomBookingStatus = null) + { + $sql = 'SELECT COUNT(DISTINCT hbd.`id_room`) + FROM `'._DB_PREFIX_.'htl_booking_detail` hbd + LEFT JOIN `'._DB_PREFIX_.'htl_room_information` hri + ON (hri.`id` = hbd.`id_room`) + LEFT JOIN `'._DB_PREFIX_.'product` p + ON (p.`id_product` = hri.`id_product`) + WHERE p.`active` = 1 + AND hbd.`is_refunded` = 0 + AND hbd.`is_cancelled` = 0 '. + (($dateFrom && $dateTo) ? ' AND hbd.`date_from` <= "'.pSQL($dateTo).' 00:00:00" AND hbd.`date_to` > "'.pSQL($dateFrom).' 00:00:00" ': ' '). + (!is_null($roomBookingStatus) ? ' AND hbd.`id_status` = '.(int) $roomBookingStatus : ' '). + (!is_null($idHotel) ? HotelBranchInformation::addHotelRestriction($idHotel, 'hbd') : ''); + $result = Db::getInstance()->getValue($sql); + + return $result ? $result : 0; + + } + + public static function getTotalBookedRooms($dateFrom, $dateTo, $idHotel = null) { $sql = 'SELECT COUNT(hbd.`id_room`) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd @@ -1795,46 +1829,6 @@ class AdminStatsControllerCore extends AdminStatsTabController return $result; } - /** - * Returns the number of rooms that have been checked-in. - */ - public static function getOccupiedRooms($idHotel = null) - { - $sql = 'SELECT COUNT(DISTINCT hbd.`id_room`) - FROM `'._DB_PREFIX_.'htl_booking_detail` hbd - LEFT JOIN `'._DB_PREFIX_.'htl_room_information` hri - ON (hri.`id` = hbd.`id_room`) - LEFT JOIN `'._DB_PREFIX_.'product` p - ON (p.`id_product` = hri.`id_product`) - WHERE p.`active` = 1 - AND hbd.`is_refunded` = 0 - AND hbd.`is_cancelled` = 0 - AND hbd.`id_status` = '.(int) HotelBookingDetail::STATUS_CHECKED_IN. - (!is_null($idHotel) ? HotelBranchInformation::addHotelRestriction($idHotel, 'hbd') : ''); - $result = Db::getInstance()->getValue($sql); - - return $result; - } - - /** - * Returns the number of rooms that have been booked but not checked-in yet. - */ - public static function getBookedRooms($idHotel = null) - { - $dateToday = date('Y-m-d'); - - $sql = 'SELECT COUNT(DISTINCT hbd.`id_room`) - FROM `'._DB_PREFIX_.'htl_booking_detail` hbd - WHERE hbd.`is_refunded` = 0 - AND hbd.`is_cancelled` = 0 - AND hbd.`id_status` = '.(int) HotelBookingDetail::STATUS_ALLOTED.' - AND hbd.`date_from` = "'.pSQL($dateToday).' 00:00:00"'. - (!is_null($idHotel) ? HotelBranchInformation::addHotelRestriction($idHotel, 'hbd') : ''); - $result = Db::getInstance()->getValue($sql); - - return $result; - } - public static function getTotalFrequentCustomers($nbOrders = 5, $idHotel = null) { $sql = 'SELECT COUNT(t.`id_customer`) @@ -1891,7 +1885,7 @@ class AdminStatsControllerCore extends AdminStatsTabController public static function getTotalNewCustomers($nbDaysNewCustomers) { - $maxDateAdd = date('Y-m-d H:i:s', strtotime('-'.$nbDaysNewCustomers.' day')); + $maxDateAdd = date('Y-m-d', strtotime('-'.$nbDaysNewCustomers.' day')); $sql = 'SELECT COUNT(c.`id_customer`) FROM `'._DB_PREFIX_.'customer` c WHERE c.`date_add` >= "'.pSQL($maxDateAdd).'" AND c.`deleted` = 0'; @@ -1976,7 +1970,7 @@ class AdminStatsControllerCore extends AdminStatsTabController $nightsBookedByDate = self::getRoomNightsData($dateFrom, $dateTo, $idHotel); $totalNightsBooked = array_sum($nightsBookedByDate); - $totalOccupiedRoom = self::getTotalOccupiedRooms($dateFrom, $dateTo, $idHotel); + $totalOccupiedRoom = self::getTotalBookedRooms($dateFrom, $dateTo, $idHotel); return $totalOccupiedRoom ? ($totalNightsBooked / $totalOccupiedRoom) : 0; } diff --git a/controllers/admin/AdminStatusesController.php b/controllers/admin/AdminStatusesController.php index e10140b77..aadb4ee44 100644 --- a/controllers/admin/AdminStatusesController.php +++ b/controllers/admin/AdminStatusesController.php @@ -707,6 +707,15 @@ class AdminStatusesControllerCore extends AdminController $theme = new Theme($this->context->shop->id_theme); $default_path = '../mails/'; $theme_path = '../themes/'.$theme->directory.'/mails/'; // Mail templates can also be found in the theme folder + $templatesToIgnore = array( + 'footer.html', + 'header.html', + 'shipped.html', + 'in_transit.html', + 'download_products.html', + 'header_order_conf.html', + 'test.html' + ); $array = array(); foreach (Language::getLanguages(false) as $language) { @@ -722,7 +731,9 @@ class AdminStatusesControllerCore extends AdminController // We merge all available emails in one array $templates = array_unique(array_merge(scandir(_PS_ADMIN_DIR_.'/'.$default_path.$iso_code), $theme_templates)); foreach ($templates as $key => $template) { - if (!strncmp(strrev($template), 'lmth.', 5)) { + if (!strncmp(strrev($template), 'lmth.', 5) + && !in_array($template, $templatesToIgnore) + ) { $search_result = array_search($template, $theme_templates); $array[$iso_code][] = array( 'id' => substr($template, 0, -5), diff --git a/controllers/front/CategoryController.php b/controllers/front/CategoryController.php index 0fc5f8efb..cd78e3395 100644 --- a/controllers/front/CategoryController.php +++ b/controllers/front/CategoryController.php @@ -101,16 +101,8 @@ class CategoryControllerCore extends FrontController // validate dates if available $dateFrom = Tools::getValue('date_from'); $dateTo = Tools::getValue('date_to'); - - $currentTimestamp = strtotime(date('Y-m-d')); - $dateFromTimestamp = strtotime($dateFrom); - $dateToTimestamp = strtotime($dateTo); - - if ($dateFrom != '' && ($dateFromTimestamp === false || ($dateFromTimestamp < $currentTimestamp))) { - Tools::redirect($this->context->link->getPageLink('pagenotfound')); - } - - if ($dateTo != '' && ($dateToTimestamp === false || ($dateToTimestamp < $currentTimestamp))) { + $idHotel = HotelBranchInformation::getHotelIdByIdCategory($id_category); + if (!HotelHelper::validateDateRangeForHotel($dateFrom, $dateTo, $idHotel)) { Tools::redirect($this->context->link->getPageLink('pagenotfound')); } @@ -165,6 +157,16 @@ class CategoryControllerCore extends FrontController $currency = new Currency($this->context->currency->id); if ($id_hotel = HotelBranchInformation::getHotelIdByIdCategory($id_category)) { + $preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($id_hotel); + if ($preparationTime + && strtotime('+ '.$preparationTime.' day') >= strtotime($date_from) + ) { + $date_from = date('Y-m-d', strtotime('+ '.$preparationTime.' day')); + if (strtotime($date_from) >= strtotime($date_to)) { + $date_to = date('Y-m-d', strtotime($date_from) + 86400); + } + } + $id_cart = $this->context->cart->id; $id_guest = $this->context->cookie->id_guest; diff --git a/controllers/front/CmsController.php b/controllers/front/CmsController.php index 01a4726bb..c855df6b4 100644 --- a/controllers/front/CmsController.php +++ b/controllers/front/CmsController.php @@ -79,8 +79,8 @@ class CmsControllerCore extends FrontController } elseif (Validate::isLoadedObject($this->cms_category) && $this->cms_category->active && $this->cms_category->isAssociatedToShop()) { $this->assignCase = 2; } else { - header('HTTP/1.1 404 Not Found'); - header('Status: 404 Not Found'); + // incase the cms page in invalid i.e, url is tampered + Tools::redirect($this->context->link->getPageLink('pagenotfound')); } } @@ -134,6 +134,9 @@ class CmsControllerCore extends FrontController 'path' => ($this->cms_category->id !== 1) ? Tools::getPath($this->cms_category->id, $this->cms_category->name, false, 'CMS') : '', 'body_classes' => array($this->php_self.'-'.$this->cms_category->id, $this->php_self.'-'.$this->cms_category->link_rewrite) )); + } else { + // incase the cms page is inactive + Tools::redirect($this->context->link->getPageLink('pagenotfound')); } $this->setTemplate(_PS_THEME_DIR_.'cms.tpl'); diff --git a/controllers/front/ContactController.php b/controllers/front/ContactController.php index 42a3fb30c..5a65c9795 100644 --- a/controllers/front/ContactController.php +++ b/controllers/front/ContactController.php @@ -308,6 +308,7 @@ class ContactControllerCore extends FrontController $this->context->smarty->assign( array( 'hotelsInfo' => $hotelsInfo, + 'viewOnMap' => Configuration::get('WK_GOOGLE_ACTIVE_MAP'), 'gblHtlPhone' => $gblHtlPhone, 'gblHtlEmail' => $gblHtlEmail, 'gblHtlAddress' => $gblHtlAddress, diff --git a/controllers/front/GuestTrackingController.php b/controllers/front/GuestTrackingController.php index 6a097dbc2..79ec067c2 100644 --- a/controllers/front/GuestTrackingController.php +++ b/controllers/front/GuestTrackingController.php @@ -614,7 +614,9 @@ class GuestTrackingControllerCore extends FrontController if ($idHotel = HotelBookingDetail::getIdHotelByIdOrder($objOrder->id)) { $objHotelBranchInformation = new HotelBranchInformation($idHotel, $this->context->language->id); if (Validate::isLoadedObject($objHotelBranchInformation)) { - if ($apiKey = Configuration::get('PS_API_KEY')) { + if (($apiKey = Configuration::get('PS_API_KEY')) + && Configuration::get('WK_GOOGLE_ACTIVE_MAP') + ) { if (floatval($objHotelBranchInformation->latitude) != 0 && floatval($objHotelBranchInformation->longitude) != 0 ) { diff --git a/controllers/front/OrderDetailController.php b/controllers/front/OrderDetailController.php index 6bebed805..d7b3d9ca7 100644 --- a/controllers/front/OrderDetailController.php +++ b/controllers/front/OrderDetailController.php @@ -423,6 +423,7 @@ class OrderDetailControllerCore extends FrontController 'obj_hotel_branch_information' => $objHotelBranchInformation, 'hotel_address_info' => $hotelAddressInfo, 'hotel_refund_rules' => $hotelRefundRules, + 'view_on_map' => Configuration::get('WK_GOOGLE_ACTIVE_MAP'), ) ); @@ -797,7 +798,9 @@ class OrderDetailControllerCore extends FrontController if ($idHotel = HotelBookingDetail::getIdHotelByIdOrder(Tools::getValue('id_order'))) { $objHotelBranchInformation = new HotelBranchInformation($idHotel, $this->context->language->id); if (Validate::isLoadedObject($objHotelBranchInformation)) { - if ($apiKey = Configuration::get('PS_API_KEY')) { + if (($apiKey = Configuration::get('PS_API_KEY')) + && Configuration::get('WK_GOOGLE_ACTIVE_MAP') + ) { if (floatval($objHotelBranchInformation->latitude) != 0 && floatval($objHotelBranchInformation->longitude) != 0 ) { diff --git a/controllers/front/OrderOpcController.php b/controllers/front/OrderOpcController.php index feed31828..ee809dc2f 100644 --- a/controllers/front/OrderOpcController.php +++ b/controllers/front/OrderOpcController.php @@ -426,7 +426,9 @@ class OrderOpcControllerCore extends ParentOrderController public function initContent() { // validate room types before payment by customer - $this->errors = HotelCartBookingData::validateCartBookings(); + if ($orderRestrictErr = HotelCartBookingData::validateCartBookings()) { + $this->errors = array_merge($this->errors, $orderRestrictErr); + } parent::initContent(); @@ -494,7 +496,7 @@ class OrderOpcControllerCore extends ParentOrderController // $objCurrency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); $this->context->smarty->assign( array( - 'orderRestrictErr' => count($this->errors) ? 1 : 0, + 'orderRestrictErr' => count($orderRestrictErr) ? 1 : 0, // 'allDemands' => $allDemands, // 'defaultcurrencySign' => $objCurrency->sign, 'THEME_DIR' => _THEME_DIR_, diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index 1028ae6e0..ac7a4b8a4 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -109,26 +109,18 @@ class ProductControllerCore extends FrontController // validate dates if available $dateFrom = Tools::getValue('date_from'); $dateTo = Tools::getValue('date_to'); - - $currentTimestamp = strtotime(date('Y-m-d')); - $dateFromTimestamp = strtotime($dateFrom); - $dateToTimestamp = strtotime($dateTo); - - if ($dateFrom != '' && ($dateFromTimestamp === false || ($dateFromTimestamp < $currentTimestamp))) { - Tools::redirect($this->context->link->getPageLink('pagenotfound')); - } - - if ($dateTo != '' && ($dateToTimestamp === false || ($dateToTimestamp < $currentTimestamp))) { - Tools::redirect($this->context->link->getPageLink('pagenotfound')); - } - parent::init(); if ($id_product = (int) Tools::getValue('id_product')) { $this->product = new Product($id_product, true, $this->context->language->id, $this->context->shop->id); } - if (!$this->product->booking_product || ($this->product->booking_product && !$this->product->show_at_front)) { + $objHotelRoomType = new HotelRoomType(); + $hotelRoomInfo = $objHotelRoomType->getRoomTypeInfoByIdProduct($this->product->id); + $idHotel = (int) $hotelRoomInfo['id_hotel']; + if (!HotelHelper::validateDateRangeForHotel($dateFrom, $dateTo, $idHotel)) { + Tools::redirect($this->context->link->getPageLink('pagenotfound')); + } else if (!$this->product->booking_product || ($this->product->booking_product && !$this->product->show_at_front)) { Tools::redirect($this->context->link->getPageLink('pagenotfound')); } @@ -341,6 +333,7 @@ class ProductControllerCore extends FrontController $date_from = Tools::getValue('date_from'); $date_to = Tools::getValue('date_to'); + $preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($hotel_id); if (!($date_from = Tools::getValue('date_from'))) { $date_from = date('Y-m-d'); // set date to according to los @@ -355,6 +348,17 @@ class ProductControllerCore extends FrontController $date_to = date('Y-m-d', strtotime('+'.$los['min_los'].' day', strtotime($date_from))); } + if ($preparationTime + && strtotime('+ '.$preparationTime.' day') >= strtotime($date_from) + ) { + $date_from = date('Y-m-d', strtotime('+ '.$preparationTime.' day')); + if (strtotime($date_from) >= strtotime($date_to)) { + $objHotelRoomTypeRestrictionDateRange = new HotelRoomTypeRestrictionDateRange(); + $los = $objHotelRoomTypeRestrictionDateRange->getRoomTypeLengthOfStay($this->product->id, $date_from); + $date_to = date('Y-m-d', strtotime('+'.$los['min_los'].' day', strtotime($date_from))); + } + } + $hotel_branch_obj = new HotelBranchInformation($hotel_id); /*Max date of ordering for order restrict*/ $order_date_restrict = false; @@ -368,9 +372,6 @@ class ProductControllerCore extends FrontController } } /*End*/ - // booking preparation time - $preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($hotel_id); - $objHotelImage = new HotelImage(); $hotelImageLink = null; if ($coverImage = HotelImage::getCover($hotel_id)) { diff --git a/docs/.htaccess b/docs/.htaccess index 8703119f9..3de9e4008 100644 --- a/docs/.htaccess +++ b/docs/.htaccess @@ -1 +1,10 @@ -Deny from ALL +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/docs/csv_import/.htaccess b/docs/csv_import/.htaccess index 18aba5838..041b7e558 100644 --- a/docs/csv_import/.htaccess +++ b/docs/csv_import/.htaccess @@ -1 +1,10 @@ -Allow from ALL \ No newline at end of file +# Apache 2.2 + + Order allow,deny + Allow from ALL + + +# Apache 2.4 + + Require all granted + diff --git a/download/.htaccess b/download/.htaccess index 93169e4eb..3de9e4008 100644 --- a/download/.htaccess +++ b/download/.htaccess @@ -1,2 +1,10 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/img/.htaccess b/img/.htaccess new file mode 100644 index 000000000..b892de715 --- /dev/null +++ b/img/.htaccess @@ -0,0 +1,16 @@ +# Apache 2.2 + + Order deny,allow + Deny from all + + Allow from all + + + +# Apache 2.4 + + Require all denied + + Require all granted + + \ No newline at end of file diff --git a/img/cms/.htaccess b/img/cms/.htaccess deleted file mode 100644 index 91920ed0a..000000000 --- a/img/cms/.htaccess +++ /dev/null @@ -1,8 +0,0 @@ - - php_flag engine off - -deny from all - - order deny,allow - allow from all - diff --git a/img/hotel_header_image.jpg b/img/hotel_header_image.jpg index ce7f91454..fbb6d003d 100644 Binary files a/img/hotel_header_image.jpg and b/img/hotel_header_image.jpg differ diff --git a/js/admin/customers.js b/js/admin/customers.js new file mode 100644 index 000000000..5eaa94c7d --- /dev/null +++ b/js/admin/customers.js @@ -0,0 +1,51 @@ +/* +* Copyright since 2010 Webkul. +* +* NOTICE OF LICENSE +* +* All right is reserved, +* Please go through this link for complete license : https://store.webkul.com/license.html +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade this module to newer +* versions in the future. If you wish to customize this module for your +* needs please refer to https://store.webkul.com/customisation-guidelines/ for more information. +* +* @author Webkul IN +* @copyright Since 2010 Webkul IN +* @license https://store.webkul.com/license.html +*/ + +$(document).ready(function() { + $(document).on('focusout', '#email', function() { + var email = $.trim($('#email').val()); + if (email != '') { + $('.customer_email_msg').hide(); + $.ajax({ + url: customer_controller_url, + method: 'POST', + dataType: 'json', + data: { + ajax : 1, + id_customer: id_customer, + email: email, + action: 'verifyCustomerEmail' + }, + success: function(response) { + if (!response.status) { + if ($('#email').closest('.input-group').parent().find('.customer_email_msg').length) { + $('.customer_email_msg').text(response.msg); + } else { + $('#email').closest('.input-group').parent().append('

'+ response.msg+'

'); + } + + $('.customer_email_msg').show(); + } else { + $('.customer_email_msg').hide(); + } + } + }); + } + }); +}); diff --git a/log/.htaccess b/log/.htaccess index 93169e4eb..7c2f481d2 100644 --- a/log/.htaccess +++ b/log/.htaccess @@ -1,2 +1,11 @@ -Order deny,allow -Deny from all +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + + diff --git a/mails/.htaccess b/mails/.htaccess index 45feba9cf..1bb323e41 100644 --- a/mails/.htaccess +++ b/mails/.htaccess @@ -1,5 +1,16 @@ -Order deny,allow -Deny from all - -Allow from all - +# Apache 2.2 + + Order deny,allow + Deny from all + + Allow from all + + + +# Apache 2.4 + + Require all denied + + Require all granted + + diff --git a/modules/.htaccess b/modules/.htaccess index d6fd8d12b..cd6d6b97f 100644 --- a/modules/.htaccess +++ b/modules/.htaccess @@ -1,3 +1,12 @@ - -Deny from all + + # Apache 2.2 + + Order deny,allow + Deny from all + + + # Apache 2.4 + + Require all denied + diff --git a/modules/blocknavigationmenu/blocknavigationmenu.php b/modules/blocknavigationmenu/blocknavigationmenu.php index b6d2437b5..224845228 100644 --- a/modules/blocknavigationmenu/blocknavigationmenu.php +++ b/modules/blocknavigationmenu/blocknavigationmenu.php @@ -103,6 +103,24 @@ class blocknavigationmenu extends Module } } + public function hookActionObjectCMSUpdateAfter($params) + { + $idCMS = $params['object']->id; + if (!$params['object']->active) { + $objCustomNavigationLink = new WkCustomNavigationLink(); + // Disabling depended Navigation link + $objCustomNavigationLink->disableNavigationLinksByIdCMS($idCMS); + } + } + + public function hookActionObjectCMSDeleteAfter($params) + { + $idCMS = $params['object']->id; + $objCustomNavigationLink = new WkCustomNavigationLink(); + // Deleting depended Navigation link + $objCustomNavigationLink->deleteNavigationLinksByIdCMS($idCMS); + } + public function install() { $objModuleDb = new WkBlockNavigationMenuDb(); @@ -125,6 +143,8 @@ class blocknavigationmenu extends Module array ( 'footer', 'actionObjectLanguageAddAfter', + 'actionObjectCMSUpdateAfter', + 'actionObjectCMSDeleteAfter', 'displayDefaultNavigationHook', 'displayNavigationHook', 'top', diff --git a/modules/blocknavigationmenu/classes/WkCustomNavigationLink.php b/modules/blocknavigationmenu/classes/WkCustomNavigationLink.php index b7e62b93e..d27a037f0 100644 --- a/modules/blocknavigationmenu/classes/WkCustomNavigationLink.php +++ b/modules/blocknavigationmenu/classes/WkCustomNavigationLink.php @@ -235,6 +235,39 @@ class WkCustomNavigationLink extends ObjectModel $objCustomNavigationLink->is_custom_link = 0; $objCustomNavigationLink->link = 'contact'; $objCustomNavigationLink->save(); + return true; } + + public function getNavigationLinksByIdCMS($idCMS) + { + return Db::getInstance()->executeS(' + SELECT * FROM `'._DB_PREFIX_.'htl_custom_navigation_link` + WHERE `id_cms`='.(int) $idCMS + ); + } + + public function disableNavigationLinksByIdCMS($idCMS) + { + $objCustomNavigationLink = new WkCustomNavigationLink(); + if ($navLinks = $objCustomNavigationLink->getNavigationLinksByIdCMS($idCMS)) { + foreach ($navLinks as $navLink) { + $objCustomNavigationLink = new WkCustomNavigationLink((int) $navLink['id_navigation_link']); + $objCustomNavigationLink->active = 0; + $objCustomNavigationLink->save(); + } + } + } + + public function deleteNavigationLinksByIdCMS($idCMS) + { + $objCustomNavigationLink = new WkCustomNavigationLink(); + if ($navLinks = $objCustomNavigationLink->getNavigationLinksByIdCMS($idCMS)) { + foreach ($navLinks as $navLink) { + $objCustomNavigationLink = new WkCustomNavigationLink((int) $navLink['id_navigation_link']); + $objCustomNavigationLink->delete(); + } + } + } + } diff --git a/modules/blocknavigationmenu/controllers/admin/AdminCustomNavigationLinkSettingController.php b/modules/blocknavigationmenu/controllers/admin/AdminCustomNavigationLinkSettingController.php index 6e1668b84..dd1b59fb4 100644 --- a/modules/blocknavigationmenu/controllers/admin/AdminCustomNavigationLinkSettingController.php +++ b/modules/blocknavigationmenu/controllers/admin/AdminCustomNavigationLinkSettingController.php @@ -179,6 +179,17 @@ class AdminCustomNavigationLinkSettingController extends ModuleAdminController if (Validate::isLoadedObject($objNavigationLink)) { $smartyVars['navigationLinkInfo'] = (array) $objNavigationLink; $smartyVars['edit'] = 1; + if ($objNavigationLink->id_cms + && Validate::isLoadedObject($objCMS = new CMS($objNavigationLink->id_cms)) + ) { + $smartyVars['id_cms_category'] = $objCMS->id_cms_category; + if (empty($this->errors) + && !$objCMS->active + ) { + $cmsEditLink = $this->context->link->getAdminLink('AdminCmsContent').'&updatecms&id_cms='.(int) $objCMS->id; + $this->warnings[] = $this->l('Please enable linked').' '.$this->l('CMS page').' '.$this->l('to enable this navigation link.'); + } + } } // send theme's front pages $themePages = array(); @@ -196,7 +207,29 @@ class AdminCustomNavigationLinkSettingController extends ModuleAdminController $smartyVars['themePages'] = $themePages; $smartyVars['languages'] = Language::getLanguages(false); $smartyVars['currentLang'] = Language::getLanguage((int) Configuration::get('PS_LANG_DEFAULT')); - $smartyVars['cmsPages'] = CMS::getCMSPages($smartyVars['currentLang'], 1); + $categoryWiseCmsPages = array(); + if ($cmsPages = CMS::getCMSPages($smartyVars['currentLang'], null, false)) { + foreach ($cmsPages as $page) { + $cmsPage['id_cms'] = $page['id_cms']; + $cmsPage['meta_title'] = $page['meta_title']; + $categoryWiseCmsPages[$page['id_cms_category']][] = $cmsPage; + } + } + + if ($cmsCategories = CMSCategory::getCategories($this->context->language->id, false, false)) { + if (!isset($smartyVars['id_cms_category'])) { + $smartyVars['id_cms_category'] = $cmsCategories[0]['id_cms_category']; + } + + foreach ($cmsCategories as $cmsCatKey => $cmsCategory) { + if (!isset($categoryWiseCmsPages[$cmsCategory['id_cms_category']])) { + unset($cmsCategories[$cmsCatKey]); + } + } + } + + $smartyVars['categoryWiseCmsPages'] = $categoryWiseCmsPages; + $smartyVars['categories'] = $cmsCategories; $this->context->smarty->assign($smartyVars); $this->fields_form = array( 'submit' => array( @@ -261,6 +294,10 @@ class AdminCustomNavigationLinkSettingController extends ModuleAdminController } if ($isCmsPage) { $objCustomNavigationLink->id_cms = $idCms; + $objCMS = new CMS((int) $idCms); + if (!$objCMS->active) { + $active = $objCMS->active; + } } else { $objCustomNavigationLink->id_cms = 0; foreach ($languages as $language) { @@ -365,7 +402,7 @@ class AdminCustomNavigationLinkSettingController extends ModuleAdminController if (isset($pos[2]) && (int) $pos[2] === $idNavigationLink) { if ($objFeatureBlock = new WkCustomNavigationLink((int) $pos[2])) { if (isset($position) - && $objFeatureBlock->updatePosition($way, $position, $idNavigationLink) + && $objFeatureBlock->updatePosition($way, $position) ) { echo 'ok position '.(int) $position.' for custom navigation link '.(int) $pos[1].'\r\n'; } else { @@ -381,9 +418,31 @@ class AdminCustomNavigationLinkSettingController extends ModuleAdminController } } + public function processStatus() + { + if (Validate::isLoadedObject($this->loadObject()) + && $this->object->id_cms + && Validate::isLoadedObject($objCMS = new CMS($this->object->id_cms)) + ) { + if (!$objCMS->active + && !$this->object->active + ) { + $this->errors[] = $this->l('Please activate the linked CMS page to enable this navigation link.'); + } + } + + if (empty($this->errors)) { + return parent::processStatus(); + } + + return $this->object; + } + public function setMedia() { parent::setMedia(); - $this->addJS(_MODULE_DIR_.$this->module->name.'/views/js/admin/wk_navigation_link.js'); + if ($this->display == 'edit' || $this->display == 'add') { + $this->addJS($this->module->getPathUri().'views/js/admin/wk_navigation_link.js'); + } } } diff --git a/modules/blocknavigationmenu/views/js/admin/wk_navigation_link.js b/modules/blocknavigationmenu/views/js/admin/wk_navigation_link.js index db7a3ff7e..48139765e 100644 --- a/modules/blocknavigationmenu/views/js/admin/wk_navigation_link.js +++ b/modules/blocknavigationmenu/views/js/admin/wk_navigation_link.js @@ -37,6 +37,12 @@ $(document).ready(function() { $(".custom_redirect_page_div").removeClass('hidden'); } }); + + $(document).on('change', '#id_cms_category', function(){ + var id_cat = parseInt($('#id_cms_category').val()); + $('.cms_pages_table').hide(); + $('#cms_pages_table_'+id_cat).show(); + }); }); function showNavigationLinkLangField(lang_iso_code, id_lang) @@ -45,4 +51,4 @@ function showNavigationLinkLangField(lang_iso_code, id_lang) $('.navigation_link_name_all').hide(); $('#navigation_link_name_'+id_lang).show(); -} \ No newline at end of file +} diff --git a/modules/blocknavigationmenu/views/templates/admin/custom_navigation_link_setting/helpers/form/form.tpl b/modules/blocknavigationmenu/views/templates/admin/custom_navigation_link_setting/helpers/form/form.tpl index fe9ceefc0..642b6fb39 100644 --- a/modules/blocknavigationmenu/views/templates/admin/custom_navigation_link_setting/helpers/form/form.tpl +++ b/modules/blocknavigationmenu/views/templates/admin/custom_navigation_link_setting/helpers/form/form.tpl @@ -52,8 +52,26 @@ {* Feilds of cms page *}
+
+
+ +
+ +
+
+
{*Display CMS Pages*} - {if isset($cmsPages)} + {if isset($categoryWiseCmsPages)}
-
- - - - - - - - - - {foreach $cmsPages as $cmsPage} + {foreach $categoryWiseCmsPages as $idCMSCategory => $cmsPages} +
+
- {l s='ID' mod='blocknavigationmenu'} - - {l s='CMS Page Name' mod='blocknavigationmenu'} - -
+ - - - + + + - {/foreach} - -
- {$cmsPage.id_cms|escape:'htmlall':'UTF-8'} + {l s='ID' mod='blocknavigationmenu'} + + {l s='CMS Page Name' mod='blocknavigationmenu'} + +
-
+ + + {foreach $cmsPages as $cmsPage} + + + + {$cmsPage.id_cms|escape:'htmlall':'UTF-8'} + + + {/foreach} + + +
+ {/foreach}
{/if} diff --git a/modules/dashactivity/dashactivity.php b/modules/dashactivity/dashactivity.php index 46fc8c72f..4f30c3beb 100644 --- a/modules/dashactivity/dashactivity.php +++ b/modules/dashactivity/dashactivity.php @@ -87,10 +87,13 @@ class Dashactivity extends Module public function hookDashboardZoneOne($params) { $this->context->smarty->assign($this->getConfigFieldsValues()); + $date_from = $this->context->employee->stats_date_from; + $date_to = $this->context->employee->stats_date_to; $this->context->smarty->assign( array( 'dashactivity_config_form' => $this->renderConfigForm(), - 'link' => $this->context->link + 'link' => $this->context->link, + 'new_customer_filter_link' => $this->context->link->getAdminLink('AdminCustomers').'&customerFilter_date_add[]='.$date_from.'&customerFilter_date_add[]='.$date_to ) ); diff --git a/modules/dashactivity/views/templates/hook/dashboard_zone_one.tpl b/modules/dashactivity/views/templates/hook/dashboard_zone_one.tpl index 900c3f64f..5ed29c94c 100644 --- a/modules/dashactivity/views/templates/hook/dashboard_zone_one.tpl +++ b/modules/dashactivity/views/templates/hook/dashboard_zone_one.tpl @@ -122,7 +122,7 @@