Merge branch 'develop' into gli-1768

This commit is contained in:
Sumit Panwar
2024-07-23 11:29:55 +05:30
93 changed files with 1211 additions and 428 deletions

1
.gitignore vendored
View File

@@ -53,6 +53,7 @@ composer.lock
img/**
!/img/404.gif
!/img/.htaccess
!/img/admin/
!/img/admin/*.gif
!/img/admin/*.png

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -29,31 +29,29 @@
{if $input.name == 'vat_number'}
<div id="vat_area" style="display: visible">
{/if}
{if $input.type == 'text_customer' && !isset($customer)}
<label class="control-label col-lg-3 required" for="email">{l s='Customer email'}</label>
{else}
{$smarty.block.parent}
{/if}
{$smarty.block.parent}
{/block}
{block name="field"}
{block name="input"}
{if $input.type == 'text_customer'}
{if isset($customer)}
<div class="col-lg-9">
<a class="btn btn-default" href="?tab=AdminCustomers&amp;id_customer={$customer->id|intval}&amp;viewcustomer&amp;token={$tokenCustomer}">
<i class="icon-eye-open"></i> {$customer->lastname} {$customer->firstname} ({$customer->email})
</a>
</div>
<a class="btn btn-default" href="?tab=AdminCustomers&amp;id_customer={$customer->id|intval}&amp;viewcustomer&amp;token={$tokenCustomer}">
<i class="icon-eye-open"></i> {$customer->lastname} {$customer->firstname} ({$customer->email})
</a>
<input type="hidden" name="id_customer" value="{$customer->id}" />
<input type="hidden" name="email" value="{$customer->email}" />
{else}
<script type="text/javascript">
$('input[name=email]').live('blur', function(e)
{/if}
{else if $input.type == 'select' && $input.name == 'id_customer'}
{$smarty.block.parent}
<input type="hidden" name="email" id="email" value="">
<script type="text/javascript">
$('#id_customer').on('change', function(e)
{
var email = $(this).val();
if (email.length > 5)
{
var id_customer = parseInt($(this).val());
$('#email').val('');
if (!isNaN(id_customer)) {
var email = $(this).find('[value="'+id_customer+'"]').text();
$('#email').val(email);
var data = {};
data.email = email;
data.token = "{$token|escape:'html':'UTF-8'}";
@@ -66,31 +64,29 @@
data: data,
dataType: 'json',
async : true,
success: function(msg)
{
if (msg)
{
success: function(msg) {
if (msg) {
var infos = msg.infos.replace("\\'", "'").split('_');
$('input[name=firstname]').val(infos[0]);
$('input[name=lastname]').val(infos[1]);
$('input[name=company]').val(infos[2]);
$('input[name=id_customer]').val(infos[3]);
} else {
resetCustomerRelatedAddressFields();
}
},
error: function(msg)
{
}
});
} else {
resetCustomerRelatedAddressFields();
}
});
</script>
<div class="col-lg-4">
<input type="hidden" name="id_customer" value="{$fields_value[$input.name]}" />
<input type="email" id="email" name="email" value="{$fields_value[$input.name]|escape:'html':'UTF-8'}"/>
</div>
{/if}
function resetCustomerRelatedAddressFields() {
$('input[name=firstname]').val('');
$('input[name=lastname]').val('');
$('input[name=company]').val('');
$('input[name=id_customer]').val('');
}
</script>
{else}
{$smarty.block.parent}
{/if}

View File

@@ -39,7 +39,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="robots" content="NOFOLLOW, NOINDEX">
<title>
{$shop_name} {if $meta_title != ''}{if isset($navigationPipe)}{$navigationPipe|escape:'html':'UTF-8'}{else}&gt;{/if} {$meta_title}{/if} (PrestaShop&trade;)
{$shop_name} {if $meta_title != ''}{if isset($navigationPipe)}{$navigationPipe|escape:'html':'UTF-8'}{else}&gt;{/if} {$meta_title}{/if} (QloApps&trade;)
</title>
{if isset($css_files)}
{foreach from=$css_files key=css_uri item=media}

View File

@@ -43,7 +43,7 @@
{l s='Price'}
</th>
<th>
{l s='Tax rate'}
{l s='Tax rule'}
</th>
<th class="fixed-width-lg text-center">
{l s='Per day price calculation'}

View File

@@ -27,7 +27,7 @@
<span>{l s='Price'}</span>
</th>
<th>
<span>{l s='Tax'}</span>
<span>{l s='Tax rule'}</span>
</th>
</tr>
</thead>

View File

@@ -138,6 +138,9 @@
</select>
{elseif isset($input.empty_message)}
{$input.empty_message}
{else}
<select class="form-control fixed-width-xxl {if isset($field['class'])}{$field['class']}{/if}" name="{$key}"{if isset($field['js'])} onchange="{$field['js']}"{/if} id="{$key}" {if isset($field['size'])} size="{$field['size']}"{/if}>
</select>
{/if}
</div>
{elseif $field['type'] == 'bool'}

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

31
classes/BoOrder.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
/**
* 2010-2022 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 <support@webkul.com>
* @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;
}
}

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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);
}
/**

View File

@@ -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;

View File

@@ -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);

View File

@@ -26,5 +26,6 @@ class WebserviceOrderCore extends PaymentModule
public function __construct()
{
$this->displayName = $this->l('Order from API');
$this->validateOrderAmount = false;
}
}

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -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()
*/

View File

@@ -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');
}
}
}

View File

@@ -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.');
}
}

View File

@@ -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
*/

View File

@@ -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('&nbsp;', 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();

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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),

View File

@@ -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;

View File

@@ -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');

View File

@@ -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,

View File

@@ -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
) {

View File

@@ -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
) {

View File

@@ -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_,

View File

@@ -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)) {

View File

@@ -1 +1,10 @@
Deny from ALL
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1 +1,10 @@
Allow from ALL
# Apache 2.2
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from ALL
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all granted
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

16
img/.htaccess Normal file
View File

@@ -0,0 +1,16 @@
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
<Files ~ "(?i)^.*\.(jpg|jpeg|gif|png|bmp|tiff|svg|pdf|mov|mpeg|mp4|avi|mpg|wma|flv|webm|ico|webp|avif)$">
Allow from all
</Files>
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
<Files ~ "(?i)^.*\.(jpg|jpeg|gif|png|bmp|tiff|svg|pdf|mov|mpeg|mp4|avi|mpg|wma|flv|webm|ico|webp|avif)$">
Require all granted
</Files>
</IfModule>

View File

@@ -1,8 +0,0 @@
<IfModule mod_php5.c>
php_flag engine off
</IfModule>
deny from all
<Files ~ "(?i)^.*\.(jpg|jpeg|gif|png|bmp|tiff|svg|pdf|mov|mpeg|mp4|avi|mpg|wma|flv|webm)$">
order deny,allow
allow from all
</Files>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 175 KiB

51
js/admin/customers.js Normal file
View File

@@ -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 <support@webkul.com>
* @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('<p class="text-danger customer_email_msg">'+ response.msg+'</p>');
}
$('.customer_email_msg').show();
} else {
$('.customer_email_msg').hide();
}
}
});
}
});
});

View File

@@ -1,2 +1,11 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,5 +1,16 @@
Order deny,allow
Deny from all
<FilesMatch "\.(html|txt)$">
Allow from all
</FilesMatch>
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
<FilesMatch "\.(html|txt)$">
Allow from all
</FilesMatch>
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
<FilesMatch "\.(html|txt)$">
Require all granted
</FilesMatch>
</IfModule>

View File

@@ -1,3 +1,12 @@
<FilesMatch "\.tpl$">
Deny from all
<FilesMatch "(\.tpl|config\.xml|config_([a-z]+)\.xml)$">
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>

View File

@@ -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',

View File

@@ -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();
}
}
}
}

View File

@@ -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').' <a href="'.$cmsEditLink.'" target="_blank">'.$this->l('CMS page').'</a> '.$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');
}
}
}

View File

@@ -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();
}
}

View File

@@ -52,8 +52,26 @@
</div>
{* Feilds of cms page *}
<div id="cms_block_content" class="{if isset($smarty.post.is_cms_block_link)}{if !$smarty.post.is_cms_block_link}hidden{/if}{elseif !isset($navigationLinkInfo['id_cms']) || !$navigationLinkInfo['id_cms']}hidden{/if}">
<div class="form-group">
<div id="selected_parent_category">
<label class="control-label col-lg-3">
<span title="" data-toggle="tooltip" class="label-tooltip" data-original-title="{l s='Select CMS category to display related CMS pages' mod='blocknavigationmenu'}" data-html="true">
{l s='Select CMS category' mod='blocknavigationmenu'}
</span>
</label>
<div class="col-lg-9">
<select class="form-control fixed-width-xxl " name="id_cms_category" id="id_cms_category">
{if isset($categories) && count($categories)}
{foreach $categories as $category}
<option value="{$category.id_cms_category}" {if isset($smarty.post.id_cms_category)}{if ($smarty.post.id_cms_category == $category.id_cms_category)}selected="selected"{/if}{else if isset($id_cms_category) && ($id_cms_category == $category.id_cms_category)}selected="selected"{/if}>{$category.name|escape:'htmlall':'UTF-8'}</option>
{/foreach}
{/if}
</select>
</div>
</div>
</div>
{*Display CMS Pages*}
{if isset($cmsPages)}
{if isset($categoryWiseCmsPages)}
<div class="form-group">
<label class="control-label col-lg-3">
<span class="label-tooltip" data-toggle="tooltip"
@@ -61,32 +79,34 @@
{l s='Select CMS Page' mod='blocknavigationmenu'}
</span>
</label>
<div class="col-lg-9">
<table class="table table-bordered" style="width:40%;">
<thead>
<tr>
<th class="fixed-width-xs">
</th>
<th class="fixed-width-xs"><span class="title_box">{l s='ID' mod='blocknavigationmenu'}</span></th>
<th>
<span class="title_box">
{l s='CMS Page Name' mod='blocknavigationmenu'}
</span>
</th>
</tr>
</thead>
<tbody>
{foreach $cmsPages as $cmsPage}
{foreach $categoryWiseCmsPages as $idCMSCategory => $cmsPages}
<div class="col-lg-9">
<table class="table table-bordered cms_pages_table" id="cms_pages_table_{$idCMSCategory}" style="width:40%; {if isset($smarty.post.id_cms_category) && $smarty.post.id_cms_category != $idCMSCategory}display:none;{else if isset($id_cms_category) && ($id_cms_category != $idCMSCategory)}display:none;{/if}">
<thead>
<tr>
<td><input type="radio" value="{$cmsPage.id_cms|escape:'htmlall':'UTF-8'}" name="id_cms" {if isset($navigationLinkInfo['id_cms']) && $navigationLinkInfo['id_cms'] == $cmsPage.id_cms}checked="checked"{/if}>
</td>
<td>{$cmsPage.id_cms|escape:'htmlall':'UTF-8'}</td>
<td><label for="groupBox_{$cmsPage.id_cms|escape:'htmlall':'UTF-8'}">{$cmsPage.meta_title}</label></td>
<th class="fixed-width-xs">
</th>
<th class="fixed-width-xs"><span class="title_box">{l s='ID' mod='blocknavigationmenu'}</span></th>
<th>
<span class="title_box">
{l s='CMS Page Name' mod='blocknavigationmenu'}
</span>
</th>
</tr>
{/foreach}
</tbody>
</table>
</div>
</thead>
<tbody>
{foreach $cmsPages as $cmsPage}
<tr>
<td><input type="radio" value="{$cmsPage.id_cms|escape:'htmlall':'UTF-8'}" name="id_cms" {if isset($navigationLinkInfo['id_cms']) && $navigationLinkInfo['id_cms'] == $cmsPage.id_cms}checked="checked"{/if}>
</td>
<td>{$cmsPage.id_cms|escape:'htmlall':'UTF-8'}</td>
<td><label for="groupBox_{$cmsPage.id_cms|escape:'htmlall':'UTF-8'}">{$cmsPage.meta_title}</label></td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{/foreach}
</div>
{/if}
</div>

View File

@@ -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
)
);

View File

@@ -122,7 +122,7 @@
<ul class="stats-list">
<li>
<span class="item-label">
<a href="{$link->getAdminLink("AdminCustomers")|escape:"html":"UTF-8"}" target="_blank">
<a href="{$new_customer_filter_link|escape:"html":"UTF-8"}" target="_blank">
<span>{l s="New Customers" mod='dashactivity'}</span>
</a>
</span>

View File

@@ -2253,10 +2253,14 @@ class HotelBookingDetail extends ObjectModel
*
* @return [boolean] [true if updated otherwise false]
*/
public function updateOrderRefundStatus($id_order, $date_from = false, $date_to = false, $id_rooms = array(), $is_refunded = 1, $is_cancelled = 0)
public function updateOrderRefundStatus($id_order, $date_from = false, $date_to = false, $id_rooms = array(), $is_refunded = 1, $is_cancelled = null)
{
$table = 'htl_booking_detail';
$data = array('is_refunded' => (int) $is_refunded, 'is_cancelled' => (int) $is_cancelled);
$data = array('is_refunded' => (int) $is_refunded);
if (!is_null($is_cancelled)) {
$data['is_cancelled'] = (int) $is_cancelled;
}
if ($id_rooms) {
foreach ($id_rooms as $key_rm => $val_rm) {

View File

@@ -1228,13 +1228,13 @@ class HotelBranchInformation extends ObjectModel
if (!$this->use_global_preparation_time) {
if ($this->preparation_time === '') {
$message = Tools::displayError('Preparation time is a required.');
$message = Tools::displayError('Minimum booking offset is a required.');
if ($die) {
throw new PrestaShopException($message);
}
return $error_return ? $message : false;
} elseif ($this->preparation_time !== '0' && !Validate::isUnsignedInt($this->preparation_time)) {
$message = Tools::displayError('Preparation time is invalid.');
$message = Tools::displayError('Minimum booking offset is invalid.');
if ($die) {
throw new PrestaShopException($message);
}

View File

@@ -225,7 +225,7 @@ class HotelHelper
Configuration::updateValue(
'MAX_GLOBAL_BOOKING_DATE',
date('d-m-Y', strtotime(date('Y-m-d', time()).' + 1 year'))
date('Y-m-d', strtotime(date('Y-m-d', time()).' + 1 year'))
);
Configuration::updateValue('GLOBAL_PREPARATION_TIME', 0);
@@ -931,4 +931,25 @@ class HotelHelper
return $daysDifference;
}
public static function validateDateRangeForHotel($dateFrom, $dateTo, $idHotel)
{
$validStartDateTimeStamp = strtotime(date('Y-m-d'));
if ($preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($idHotel)) {
$validStartDateTimeStamp = strtotime(date('Y-m-d', strtotime('+ '.$preparationTime.' day')));
}
$dateFromTimestamp = strtotime($dateFrom);
$dateToTimestamp = strtotime($dateTo);
$isValid = true;
if ($dateFrom != '' && ($dateFromTimestamp === false || ($dateFromTimestamp < $validStartDateTimeStamp))) {
$isValid = false;
} else if ($dateTo != '' && ($dateToTimestamp === false || ($dateToTimestamp < $validStartDateTimeStamp))) {
$isValid = false;
} else if ($dateTo != '' && $dateFrom != '' && $dateFromTimestamp >= $dateToTimestamp) {
$isValid = false;
}
return $isValid;
}
}

View File

@@ -107,6 +107,11 @@ class HotelRoomType extends ObjectModel
$objHotelRoomType->id_hotel = $idHotelNew;
$objHotelRoomType->adults = $roomType['adults'];
$objHotelRoomType->children = $roomType['children'];
$objHotelRoomType->max_adults = $roomType['max_adults'];
$objHotelRoomType->max_children = $roomType['max_children'];
$objHotelRoomType->max_guests = $roomType['max_guests'];
$objHotelRoomType->min_los = $roomType['min_los'];
$objHotelRoomType->max_los = $roomType['max_los'];
if ($objHotelRoomType->save()) {
$objHotelRoomType->updateCategories();
return $returnId ? $objHotelRoomType->id : true;

View File

@@ -180,6 +180,7 @@ class HotelRoomTypeFeaturePricing extends ObjectModel
$id_product,
$date_from,
$date_to,
$groups,
$type = 'date_range',
$current_Special_days = false,
$id_feature_price = 0
@@ -188,20 +189,26 @@ class HotelRoomTypeFeaturePricing extends ObjectModel
$date_to = date('Y-m-d', strtotime($date_to));
if ($type == 'specific_date') {
return Db::getInstance()->getRow(
'SELECT * FROM `'._DB_PREFIX_.'htl_room_type_feature_pricing`
WHERE `id_product`='.(int) $id_product.' AND `active`=1
AND `date_selection_type` = '.(int) self::DATE_SELECTION_TYPE_SPECIFIC.'
AND `date_from` = \''.pSQL($date_from).'\'
AND `id_feature_price`!='.(int) $id_feature_price
'SELECT * FROM `'._DB_PREFIX_.'htl_room_type_feature_pricing` rtfp
INNER JOIN `'._DB_PREFIX_.'htl_room_type_feature_pricing_group` rtfpg
ON (rtfp.`id_feature_price` = rtfpg.`id_feature_price`)
WHERE rtfp.`id_product`='.(int) $id_product.' AND rtfp.`active`=1
AND rtfp.`date_selection_type` = '.(int) self::DATE_SELECTION_TYPE_SPECIFIC.'
AND rtfp.`date_from` = \''.pSQL($date_from).'\'
AND rtfp.`id_feature_price`!='.(int) $id_feature_price.'
AND rtfpg.`id_group` IN ('.pSQL(implode(', ',$groups)).')'
);
} elseif ($type == 'special_day') {
$featurePrices = Db::getInstance()->executeS(
'SELECT * FROM `'._DB_PREFIX_.'htl_room_type_feature_pricing`
WHERE `id_product`='.(int) $id_product.'
AND `is_special_days_exists`=1 AND `active`=1
AND `date_from` < \''.pSQL($date_to).'\'
AND `date_to` > \''.pSQL($date_from).'\'
AND `id_feature_price`!='.(int) $id_feature_price
'SELECT * FROM `'._DB_PREFIX_.'htl_room_type_feature_pricing` rtfp
INNER JOIN `'._DB_PREFIX_.'htl_room_type_feature_pricing_group` rtfpg
ON (rtfp.`id_feature_price` = rtfpg.`id_feature_price`)
WHERE rtfp.`id_product`='.(int) $id_product.'
AND rtfp.`is_special_days_exists`=1 AND `active`=1
AND rtfp.`date_from` < \''.pSQL($date_to).'\'
AND rtfp.`date_to` > \''.pSQL($date_from).'\'
AND rtfp.`id_feature_price`!='.(int) $id_feature_price.'
AND rtfpg.`id_group` IN ('.pSQL(implode(', ',$groups)).')'
);
if ($featurePrices) {
foreach ($featurePrices as $featurePrice) {
@@ -216,13 +223,16 @@ class HotelRoomTypeFeaturePricing extends ObjectModel
return false;
} elseif ($type == 'date_range') {
return Db::getInstance()->getRow(
'SELECT * FROM `'._DB_PREFIX_.'htl_room_type_feature_pricing`
WHERE `id_product`='.(int) $id_product.' AND `active`=1
AND `date_selection_type` = '.(int) self::DATE_SELECTION_TYPE_RANGE.'
AND `is_special_days_exists`=0
AND `date_from` <= \''.pSQL($date_to).'\'
AND `date_to` >= \''.pSQL($date_from).'\'
AND `id_feature_price`!='.(int) $id_feature_price
'SELECT * FROM `'._DB_PREFIX_.'htl_room_type_feature_pricing` rtfp
INNER JOIN `'._DB_PREFIX_.'htl_room_type_feature_pricing_group` rtfpg
ON (rtfp.`id_feature_price` = rtfpg.`id_feature_price`)
WHERE rtfp.`id_product`='.(int) $id_product.' AND rtfp.`active`=1
AND rtfp.`date_selection_type` = '.(int) self::DATE_SELECTION_TYPE_RANGE.'
AND rtfp.`is_special_days_exists`=0
AND rtfp.`date_from` <= \''.pSQL($date_to).'\'
AND rtfp.`date_to` >= \''.pSQL($date_from).'\'
AND rtfp.`id_feature_price`!='.(int) $id_feature_price.'
AND rtfpg.`id_group` IN ('.pSQL(implode(', ',$groups)).')'
);
}
return false;

View File

@@ -183,6 +183,8 @@ class AdminAddHotelController extends ModuleAdminController
$smartyVars['state_var'] = $stateOptions;
$smartyVars['enabledDisplayMap'] = Configuration::get('PS_API_KEY') && Configuration::get('WK_GOOGLE_ACTIVE_MAP');
$smartyVars['ps_img_dir'] = _PS_IMG_.'l/';
$smartyVars['MAX_GLOBAL_BOOKING_DATE'] = (Configuration::get('MAX_GLOBAL_BOOKING_DATE'));
$smartyVars['GLOBAL_PREPARATION_TIME'] = Configuration::get('GLOBAL_PREPARATION_TIME');
$this->context->smarty->assign($smartyVars);
@@ -343,9 +345,9 @@ class AdminAddHotelController extends ModuleAdminController
if (!$enableUseGlobalPreparationTime) {
if ($preparationTime === '') {
$this->errors[] = $this->l('Preparation time is a required field.');
$this->errors[] = $this->l('Minimum booking offset is a required field.');
} elseif ($preparationTime !== '0' && !Validate::isUnsignedInt($preparationTime)) {
$this->errors[] = $this->l('Preparation time is invalid.');
$this->errors[] = $this->l('Minimum booking offset is invalid.');
}
}
}
@@ -469,7 +471,7 @@ class AdminAddHotelController extends ModuleAdminController
}
// getHotel address
if ($idHotelAddress = $objHotelBranch->getHotelIdAddress()) {
$objAddress = new Address($idHotelAddress);
$objAddress = new Address($idHotelAddress);
} else {
$objAddress = new Address();
}

View File

@@ -182,6 +182,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$objFeaturePricing->id_product,
$objFeaturePricing->date_from,
$objFeaturePricing->date_to,
$objFeaturePricing->getGroups($objFeaturePricing->id),
$objFeaturePricing->id,
$objFeaturePricing->is_special_days_exists,
$objFeaturePricing->special_days
@@ -283,6 +284,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$roomTypeId,
$dateFrom,
$dateTo,
$group,
$idFeaturePrice,
$isSpecialDaysExists = false,
$jsonSpecialDays = "false"
@@ -293,6 +295,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$roomTypeId,
$dateFrom,
$dateTo,
$group,
'specific_date',
false,
$idFeaturePrice
@@ -302,6 +305,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$roomTypeId,
$dateFrom,
$dateTo,
$group,
'special_day',
$jsonSpecialDays,
$idFeaturePrice
@@ -311,6 +315,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$roomTypeId,
$dateFrom,
$dateTo,
$group,
'date_range',
false,
$idFeaturePrice
@@ -335,6 +340,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$impactValue = Tools::getValue('impact_value');
$dateSelectionType = Tools::getValue('date_selection_type');
$specificDate = date('Y-m-d', strtotime(Tools::getValue('specific_date')));
$groups = Tools::getValue('groupBox');
$jsonSpecialDays = json_encode($specialDays);
$defaultLangId = Configuration::get('PS_LANG_DEFAULT');
@@ -361,6 +367,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$roomTypeId,
$dateFrom,
$dateTo,
$groups,
$idFeaturePrice,
$isSpecialDaysExists,
$jsonSpecialDays
@@ -435,7 +442,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
}
}
if (!(bool)Tools::getValue('groupBox')) {
if (!(bool)$groups) {
$this->errors[] = $this->l('Please select at least one group for the group access');
}
@@ -467,7 +474,7 @@ class AdminHotelFeaturePricesSettingsController extends ModuleAdminController
$objFeaturePricing->active = $enableFeaturePrice;
// set the values of the groups for this feature price
$objFeaturePricing->groupBox = Tools::getValue('groupBox');
$objFeaturePricing->groupBox = $groups;
if ($objFeaturePricing->save()) {
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) {

View File

@@ -159,7 +159,7 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController
'type' => 'file',
'image' => $imgExist ? $image : false,
'hint' => $this->l('This image appears as header background image on home page.'),
'name' => 'htl_header_image',
'name' => 'WK_HOTEL_HEADER_IMAGE',
'url' => _PS_IMG_,
),
),
@@ -307,7 +307,7 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController
'value' => 0,
),
),
'hint' => $this->l('If set to No, Google Maps will not be displayed for hotel location. You need to set hotels location from edit hotel page to display location on the map at contact-us page.'),
'hint' => $this->l('Enable to display Google Maps for hotel locations. If disabled, Google Maps will not be shown.'),
),
'WK_MAP_HOTEL_ACTIVE_ONLY' => array(
'title' => $this->l('Display Active Hotels Only'),
@@ -392,8 +392,8 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController
}
}
}
if ($_FILES['htl_header_image']['name']) {
if ($error = ImageManager::validateUpload($_FILES['htl_header_image'], Tools::getMaxUploadSize())) {
if ($_FILES['WK_HOTEL_HEADER_IMAGE']['name']) {
if ($error = ImageManager::validateUpload($_FILES['WK_HOTEL_HEADER_IMAGE'], Tools::getMaxUploadSize())) {
$this->errors[] = $error;
}
@@ -401,8 +401,10 @@ class AdminHotelGeneralSettingsController extends ModuleAdminController
$file_name = 'hotel_header_image_'.time().'.jpg';
$img_path = _PS_IMG_DIR_.$file_name;
if (ImageManager::resize($_FILES['htl_header_image']['tmp_name'], $img_path)) {
if (ImageManager::resize($_FILES['WK_HOTEL_HEADER_IMAGE']['tmp_name'], $img_path)) {
$olderHeaderImg = _PS_IMG_DIR_.Configuration::get('WK_HOTEL_HEADER_IMAGE');
Configuration::updateValue('WK_HOTEL_HEADER_IMAGE', $file_name);
Tools::deleteFile($olderHeaderImg);
} else {
$this->errors[] = $this->l('Some error occured while uoploading image.Please try again.');
}

View File

@@ -245,7 +245,8 @@ class AdminOrderRefundRequestsController extends ModuleAdminController
'isRefundCompleted' => $objOrderReturn->hasBeenCompleted(),
'paymentMethods' => $paymentMethods,
'name_controller' => Tools::getValue('controller'),
'info_icon_path' => $this->context->link->getMediaLink(_MODULE_DIR_.'hotelreservationsystem/views/img/Slices/icon-info.svg')
'info_icon_path' => $this->context->link->getMediaLink(_MODULE_DIR_.'hotelreservationsystem/views/img/Slices/icon-info.svg'),
'expiry_date' => time() + (3600 * 24 * 365.25)
)
);
@@ -325,6 +326,14 @@ class AdminOrderRefundRequestsController extends ModuleAdminController
} else {
$this->errors[] = $this->l('Invalid refund state.');
}
if (Tools::isSubmit('generateDiscount')) {
if (!$voucher_expiry_date = Tools::getValue('voucher_expiry_date')) {
$this->errors[] = $this->l('Voucher expiry date is required.');
} elseif (!Validate::isDate($voucher_expiry_date)) {
$this->errors[] = $this->l('Invalid voucher expiry date.');
}
}
} else {
$this->errors[] = $this->l('Invalid refund information found.');
}
@@ -480,7 +489,12 @@ class AdminOrderRefundRequestsController extends ModuleAdminController
$cartrule->id_customer = $objOrder->id_customer;
$now = time();
$cartrule->date_from = date('Y-m-d H:i:s', $now);
$cartrule->date_to = date('Y-m-d H:i:s', $now + (3600 * 24 * 365.25)); /* 1 year */
// generateDiscount
if ($voucher_expiry_date) {
$cartrule->date_to = date('Y-m-d H:i:s', strtotime($voucher_expiry_date));
} else {
$cartrule->date_to = date('Y-m-d H:i:s', $now + (3600 * 24 * 365.25)); /* 1 year */
}
$cartrule->active = 1;
$cartrule->highlight = 1;
$cartrule->reduction_amount = $totalRefundedAmount;
@@ -560,6 +574,8 @@ class AdminOrderRefundRequestsController extends ModuleAdminController
if ($this->display == 'view') {
$this->addJqueryUI('ui.tooltip', 'base', true);
$this->removeJS(Media::getJqueryUIPath('effects.core', 'base', false), false);
$this->addJs(_MODULE_DIR_.$this->module->name.'/views/js/admin/wk_refund_request.js');
$this->addCSS(_MODULE_DIR_.$this->module->name.'/views/css/admin/wk_refund_request.css');
}

View File

@@ -1 +1,10 @@
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -70,7 +70,7 @@ class HotelReservationSystem extends Module
) {
Configuration::updateValue(
'MAX_GLOBAL_BOOKING_DATE',
date('d-m-Y', strtotime(date('Y-m-d', time()).' + 1 year'))
date('Y-m-d', strtotime(date('Y-m-d', time()).' + 1 year'))
);
}
if (!Configuration::get('PS_CATALOG_MODE')) {
@@ -293,7 +293,9 @@ class HotelReservationSystem extends Module
public function hookDisplayLeftColumn()
{
if (Tools::getValue('controller') == 'category') {
if ($apiKey = Configuration::get('PS_API_KEY')) {
if (($apiKey = Configuration::get('PS_API_KEY'))
&& Configuration::get('WK_GOOGLE_ACTIVE_MAP')
) {
$idCategory = Tools::getValue('id_category');
$idHotel = HotelBranchInformation::getHotelIdByIdCategory($idCategory);
$objHotel = new HotelBranchInformation($idHotel, $this->context->language->id);
@@ -484,7 +486,8 @@ class HotelReservationSystem extends Module
// Make rooms available for booking if order status is cancelled, refunded or error
if (in_array($params['newOrderStatus']->id, $objHtlBkDtl->getOrderStatusToFreeBookedRoom())) {
$isCancelled = 0;
// do not change is_cancelled if room is not getting cancelled
$isCancelled = null;
if ($params['newOrderStatus']->id == Configuration::get('PS_OS_CANCELED')) {
$isCancelled = 1;
}

View File

@@ -531,6 +531,10 @@ $(document).ready(function() {
});
/* ---- HotelConfigurationSettingController Admin ---- */
toggleGoogleMapsFields();
$('#WK_GOOGLE_ACTIVE_MAP_on').parent().on('click', function(e) {
toggleGoogleMapsFields();
});
if ($('#WK_SHOW_MSG_ON_BO_on').prop('checked') === true) {
$("#conf_id_WK_BO_MESSAGE").show();
@@ -826,7 +830,14 @@ $(document).ready(function() {
initGoogleMaps();
});
function toggleGoogleMapsFields()
{
if ($('#WK_GOOGLE_ACTIVE_MAP_on').attr('checked') == 'checked') {
$('#conf_id_WK_MAP_HOTEL_ACTIVE_ONLY').parent().show();
} else {
$('#conf_id_WK_MAP_HOTEL_ACTIVE_ONLY').parent().hide();
}
}
function showFeaturePriceRuleLangField(lang_iso_code, id_lang)

View File

@@ -23,6 +23,21 @@ $(document).ready(function() {
manageRefundOptions();
}
$('#order_return_form').on('submit', function() {
if ($("#id_refund_state option:selected").attr('refunded') == 1) {
if ($('#generateDiscount:checked').length) {
if ($('#voucher_expiry').val() == '') {
$('#voucher_expiry').parent().addClass('has-error');
return false;
}
}
}
});
$('#voucher_expiry').on('focus', function() {
$('#voucher_expiry').parent().removeClass('has-error');
});
// initialize tootip for room price
if ($('#rooms_refund_info .price_info').length) {
$('#rooms_refund_info .price_info').each(function (i, element) {
@@ -70,6 +85,21 @@ $(document).ready(function() {
}
});
$('#voucher_expiry').datepicker({
dateFormat: 'dd-mm-yy',
altFormat: 'yy-mm-dd',
altField: '#voucher_expiry_date',
minDate: 0,
});
$(document).on('change', '#generateDiscount', function() {
if ($(this).is(':checked')) {
$(".generate_discount_fields").show(200);
} else {
$(".generate_discount_fields").hide(200);
}
});
$('#id_refund_state').on('change', function() {
if ($("#id_refund_state option:selected").attr('refunded') == 1) {
$(".refunded_state_fields").show(200);

View File

@@ -357,17 +357,18 @@
<label for="enable_use_global_max_order_date_off">{l s='No' mod='hotelreservationsystem'}</label>
<a class="slide-button btn"></a>
</span>
<div class="help-block">{l s='Global max order date:' mod='hotelreservationsystem'} {dateFormat date=$MAX_GLOBAL_BOOKING_DATE}</div>
</div>
</div>
<div class="form-group" {if isset($smarty.post.enable_use_global_max_order_date)}{if !$smarty.post.enable_use_global_max_order_date}style="display:block;"{else}style="display:none;"{/if}{elseif isset($order_restrict_date_info.use_global_max_order_date) && !$order_restrict_date_info.use_global_max_order_date}style="display:block;" {else} style="display:none;" {/if}>
<label class="control-label col-sm-3 required" for="maximum_booking_date">{l s='Maximum Check-out Date to book a room :' mod='hotelreservationsystem'}</label>
<div class="col-sm-2">
<input type="text" class="form-control" id="maximum_booking_date" name="maximum_booking_date" value="{if isset($smarty.post.maximum_booking_date)}{$smarty.post.maximum_booking_date|escape:'html':'UTF-8'}{elseif isset($edit) && isset($order_restrict_date_info.max_order_date)}{$order_restrict_date_info.max_order_date|escape:'htmlall':'UTF-8'}{/if}" />
<input type="text" class="form-control" id="maximum_booking_date" name="maximum_booking_date" value="{if isset($order_restrict_date_info.max_order_date)}{$order_restrict_date_info.max_order_date|escape:'htmlall':'UTF-8'}{/if}" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-3">
<span>{l s='Use Global preparation time :' mod='hotelreservationsystem'}</span>
<span>{l s='Use Global minimum booking offset :' mod='hotelreservationsystem'}</span>
</label>
<div class="col-lg-6">
<span class="switch prestashop-switch fixed-width-lg">
@@ -377,10 +378,11 @@
<label for="enable_use_global_preparation_time_off">{l s='No' mod='hotelreservationsystem'}</label>
<a class="slide-button btn"></a>
</span>
<div class="help-block">{l s='Global preparation time :' mod='hotelreservationsystem'} {$GLOBAL_PREPARATION_TIME}</div>
</div>
</div>
<div class="form-group" {if isset($smarty.post.enable_use_global_preparation_time)}{if !$smarty.post.enable_use_global_preparation_time}style="display:block;"{else}style="display:none;"{/if}{elseif isset($order_restrict_date_info.use_global_preparation_time) && !$order_restrict_date_info.use_global_preparation_time}style="display:block;" {else} style="display:none;" {/if}>
<label class="control-label col-sm-3 required" for="preparation_time">{l s='Preparation time :' mod='hotelreservationsystem'}</label>
<label class="control-label col-sm-3 required" for="preparation_time">{l s='Minimum booking offset :' mod='hotelreservationsystem'}</label>
<div class="col-sm-2">
<input type="text" class="form-control" id="preparation_time" name="preparation_time" value="{if isset($smarty.post.preparation_time)}{$smarty.post.preparation_time|escape:'html':'UTF-8'}{elseif isset($edit) && isset($order_restrict_date_info.preparation_time)}{$order_restrict_date_info.preparation_time|escape:'htmlall':'UTF-8'}{/if}" />
</div>

View File

@@ -5,7 +5,7 @@
<i class="icon-info-circle"></i> &nbsp;{l s='Order Cancellation Request Information' mod='hotelreservationsystem'}
</div>
<br>
<form id="{$table|escape:'htmlall':'UTF-8'}_form" class="defaultForm {$name_controller|escape:'htmlall':'UTF-8'} form-horizontal" action="{$current|escape:'htmlall':'UTF-8'}&{if !empty($submit_action)}{$submit_action|escape:'htmlall':'UTF-8'}{/if}&token={$token|escape:'htmlall':'UTF-8'}" method="post" enctype="multipart/form-data" {if isset($style)}style="{$style|escape:'htmlall':'UTF-8'}"{/if}>
<form id="{$table|escape:'htmlall':'UTF-8'}_form" class="defaultForm {$name_controller|escape:'htmlall':'UTF-8'} form-horizontal" action="{$link->getAdminLink('AdminOrderRefundRequests')|escape:'html':'UTF-8'}&amp;vieworder_return&amp;id_order_return={$orderReturnInfo['id']|escape:'html':'UTF-8'|intval}" method="post" enctype="multipart/form-data" {if isset($style)}style="{$style|escape:'htmlall':'UTF-8'}"{/if}>
<div class="panel">
{if isset($customer_name)}
<div class="row">
@@ -369,6 +369,22 @@
</div>
</div>
</div>
<div class="generate_discount_fields" style="display:none;">
<div class="form-group">
<div class="col-sm-3">
<label for="voucher_expiry" class="control-label required">
<span title="" data-toggle="tooltip" class="label-tooltip" data-original-title="{l s='Please select the date until which the voucher can be used.' mod='hotelreservationsystem'}">{l s='Voucher expiry date' mod='hotelreservationsystem'}</span> :
</label>
</div>
<div class="col-sm-3">
<div class="input-group">
<input type="text" id="voucher_expiry" value="{$expiry_date|date_format:"%d-%m-%Y"}">
<div class="input-group-addon"><i class="icon-calendar"></i></div>
<input type="hidden" name="voucher_expiry_date" id="voucher_expiry_date" value="{$expiry_date|date_format:"%Y-%m-%d"}">
</div>
</div>
</div>
</div>
</div>
{/if}
{/if}

View File

@@ -140,11 +140,31 @@ class WkRoomSearchHelper
if (!$dateTo = Tools::getValue('date_to')) {
$dateTo = date('Y-m-d', strtotime('+1 day', strtotime($dateFrom)));
}
$smartyVars['date_from'] = $dateFrom;
$smartyVars['date_to'] = $dateTo;
$idHotel = HotelBranchInformation::getHotelIdByIdCategory($idHotelCategory);
$htlCategoryInfo = $objHotelInfo->getCategoryDataByIdCategory((int) $objCategory->id_parent);
$searchedData['htl_dtl'] = $objHotelInfo->hotelBranchesInfo(0, 1, 1, $idHotel);
$preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($idHotel);
if ($preparationTime
&& strtotime('+ '.$preparationTime.' day') >= strtotime($dateFrom)
) {
$dateFrom = date('Y-m-d', strtotime('+ '.$preparationTime.' day'));
if (strtotime($dateFrom) >= strtotime($dateTo)) {
$controller = Tools::getValue('controller');
if ($controller == 'product'
&& ($idProduct = Tools::getValue('id_product'))
) {
$objHotelRoomTypeRestrictionDateRange = new HotelRoomTypeRestrictionDateRange();
$los = $objHotelRoomTypeRestrictionDateRange->getRoomTypeLengthOfStay($idProduct, $dateFrom);
$dateTo = date('Y-m-d', strtotime('+'.$los['min_los'].' day', strtotime($dateFrom)));
} else {
$dateTo = date('Y-m-d', strtotime('+1 day', strtotime($dateFrom)));
}
}
}
$smartyVars['date_from'] = $dateFrom;
$smartyVars['date_to'] = $dateTo;
$objBookingDetail = new HotelBookingDetail();
$searchedData['num_days'] = $objBookingDetail->getNumberOfDays($dateFrom, $dateTo);
@@ -152,7 +172,6 @@ class WkRoomSearchHelper
$searchedData['parent_data'] = $htlCategoryInfo;
$searchedData['date_from'] = $dateFrom;
$searchedData['date_to'] = $dateTo;
$searchedData['htl_dtl'] = $objHotelInfo->hotelBranchesInfo(0, 1, 1, $idHotel);
if ($locationCategoryId) {
$objLocationCategory = new Category($locationCategoryId, $context->language->id);

View File

@@ -47,12 +47,13 @@ class WkRoomSearchBlockAutoCompleteSearchModuleFrontController extends ModuleFro
if ($hotelInfo = $obj_htl_info->hotelBranchInfoByCategoryId($category['id_category'])) {
$maxOrderDate = HotelOrderRestrictDate::getMaxOrderDate($hotelInfo['id']);
$maxOrderDate = date('Y-m-d', strtotime($maxOrderDate));
$preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($hotelInfo['id']);
$hotelsInfo[] = array(
'id_hotel' => $hotelInfo['id'],
'id_category' => $hotelInfo['id_category'],
'hotel_name' => $hotelInfo['hotel_name'],
'max_order_date' => $maxOrderDate,
'preparation_time' => $preparationTime
);
}
}

View File

@@ -138,7 +138,11 @@ const BookingSearchManager = {
$('#hotel_cat_id').val('');
$('#id_hotel_button').html(result.html_hotel_options);
$('#id_hotel_button').trigger('chosen:updated');
// Resetting the data from previously selected hotel
$('#preparation_time').val(0);
var max_order_date = $('#max_order_date').val();
var preparation_time = 0;
createDateRangePicker(max_order_date, preparation_time, $('#check_in_time').val(), $('#check_out_time').val());
if (search_auto_focus_next_field) {
BookingSearchManager.activateStep('hotel');
}
@@ -380,6 +384,14 @@ $(document).ready(function() {
if (preparation_time) {
start_date.setDate(start_date.getDate() + parseInt(preparation_time));
start_date.setHours(0, 0, 0, 0);
let selectedDateFrom = new Date(Date.parse(dateFrom));
let selectedDateTo = new Date(Date.parse(dateTo));
if (selectedDateFrom < start_date
|| selectedDateTo < start_date
) {
$('#check_in_time').val('');
$('#check_out_time').val('');
}
}
if (max_order_date) {
@@ -987,4 +999,4 @@ function setBookingSearchPositions() {
$(inputFieldsAndDropdowns).each(function (i, inputFieldAndDropdown) {
inputFieldAndDropdown.dropdown.removeClass('top bottom').addClass(positionClass);
});
}
}

View File

@@ -20,7 +20,7 @@
<option value=""></option>
{if isset($hotels_info) && is_array($hotels_info)}
{foreach from=$hotels_info item=hotel_info}
<option class="search_result_li" data-id-hotel="{$hotel_info.id_hotel}" data-hotel-cat-id="{$hotel_info.id_category}" data-max_order_date="{$hotel_info.max_order_date}" tabindex="-1">
<option class="search_result_li" data-id-hotel="{$hotel_info.id_hotel}" data-hotel-cat-id="{$hotel_info.id_category}" data-max_order_date="{$hotel_info.max_order_date}" data-preparation_time="{$hotel_info.preparation_time}" tabindex="-1">
{$hotel_info.hotel_name}
</option>
{/foreach}

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,3 +1,14 @@
<FilesMatch "\.tpl$">
Deny from all
</FilesMatch>
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
<FilesMatch "\.tpl$">
Deny from all
</FilesMatch>
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
<FilesMatch "\.tpl$">
Require all denied
</FilesMatch>
</IfModule>

View File

@@ -1,3 +1,14 @@
<FilesMatch "\.tpl$">
Deny from all
</FilesMatch>
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
<FilesMatch "\.tpl$">
Deny from all
</FilesMatch>
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
<FilesMatch "\.tpl$">
Require all denied
</FilesMatch>
</IfModule>

View File

@@ -164,7 +164,7 @@
<div class="col-xs-8">
<p class="hotel-name"><span>{$hotel['hotel_name']}</span></p>
<p class="hotel-branch-info-value">{$hotel['address']}, {$hotel['city']}, {if {$hotel['state_name']}}{$hotel['state_name']},{/if} {$hotel['country_name']}, {$hotel['postcode']}</p>
{if $hotel['latitude'] != 0 || $hotel['longitude'] != 0}
{if $hotel['latitude'] != 0 || $hotel['longitude'] != 0 && $viewOnMap}
<p class="hotel-branch-info-value">
<a class="btn htl-map-direction-btn" href="http://maps.google.com/maps?daddr=({$hotel['latitude']},{$hotel['longitude']})" target="_blank">
<span class="">{l s='View on map'}</span>

View File

@@ -392,11 +392,11 @@
margin-bottom: 10px;
}
.add-order-message form #submitMessage {
#order_detail_container #submitMessage {
padding: 6px 20px;
}
.add-order-message form #submitMessage span {
#order_detail_container #submitMessage span {
font-size: 14px;
font-weight: bold;
}
@@ -529,20 +529,20 @@
border-radius: 4px;
}
.button.button-medium {
#order_detail_container .button.button-medium {
padding: 8px 15px;
background-color: #379bf0;
background-image: none;
border-radius: 2px;
}
.button.button-medium span {
#order_detail_container .button.button-medium span {
padding: 0;
}
.button.button-medium:hover,
.button.button-medium:focus,
.button.button-medium:active {
#order_detail_container .button.button-medium:hover,
#order_detail_container .button.button-medium:focus,
#order_detail_container .button.button-medium:active {
opacity: 0.8;
}

View File

@@ -547,6 +547,7 @@ $(document).ready(function()
});
$(document).on('click', '.open_rooms_extra_services_panel', function() {
var idProduct = $(this).data('id_product');
var idOrder = $(this).data('id_order');
var dateFrom = $(this).data('date_from');
var dateTo = $(this).data('date_to');

View File

@@ -59,7 +59,7 @@
{$HOOK_ORDERDETAILDISPLAYED}
<div class="row">
<div class="row" id="order_detail_container">
<div class="col-md-8">
{hook h='displayOrderDetailTopLeft' id_order=$order->id}
@@ -155,7 +155,7 @@
<div class="card-text">{l s='Hotel location not available.'}</div>
{/if}
{if ($obj_hotel_branch_information->latitude|floatval != 0 && $obj_hotel_branch_information->longitude|floatval != 0)}
{if ($obj_hotel_branch_information->latitude|floatval != 0 && $obj_hotel_branch_information->longitude|floatval != 0) && $view_on_map}
<div class="hotel-location-map">
<div class="booking-hotel-map-container"></div>
</div>
@@ -542,7 +542,7 @@
<div class="card-text">{l s='Hotel location not available.'}</div>
{/if}
{if ($obj_hotel_branch_information->latitude|floatval != 0 && $obj_hotel_branch_information->longitude|floatval != 0)}
{if ($obj_hotel_branch_information->latitude|floatval != 0 && $obj_hotel_branch_information->longitude|floatval != 0) && $view_on_map}
<div class="hotel-location-map">
<div class="booking-hotel-map-container"></div>
</div>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,2 +1,10 @@
Order deny,allow
Deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1 +1,10 @@
deny from all
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>

View File

@@ -1,7 +1,16 @@
<IfModule mod_mime.c>
RemoveHandler .php .phtml .php3 .php4 .php5
RemoveType .php .phtml .php3 .php4 .php5
</IfModule>
<IfModule mod_php5.c>
php_flag engine off
RemoveHandler .php .phtml .php3 .php4 .php5 .php7 .php8
RemoveType .php .phtml .php3 .php4 .php5 .php7 .php8
</IfModule>
<IfModule !mod_rewrite.c>
# Apache 2.2
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</IfModule>