Merge branch 'develop' into gli-1466
This commit is contained in:
@@ -58,6 +58,8 @@ if ($excludeIds && $excludeIds != 'NaN') {
|
||||
$excludeVirtuals = (bool)Tools::getValue('excludeVirtuals', true);
|
||||
$exclude_packs = (bool)Tools::getValue('exclude_packs', true);
|
||||
|
||||
$bookingProduct = (int) Tools::getValue('booking_product');
|
||||
|
||||
$context = Context::getContext();
|
||||
|
||||
$sql = 'SELECT p.`id_product`, pl.`link_rewrite`, p.`reference`, pl.`name`, image_shop.`id_image` id_image, il.`legend`, p.`cache_default_attribute`
|
||||
@@ -72,6 +74,7 @@ $sql = 'SELECT p.`id_product`, pl.`link_rewrite`, p.`reference`, pl.`name`, imag
|
||||
(!empty($excludePackItself) ? ' AND p.id_product <> '.$excludePackItself.' ' : ' ').
|
||||
($excludeVirtuals ? 'AND NOT EXISTS (SELECT 1 FROM `'._DB_PREFIX_.'product_download` pd WHERE (pd.id_product = p.id_product))' : '').
|
||||
($exclude_packs ? 'AND (p.cache_is_pack IS NULL OR p.cache_is_pack = 0)' : '').
|
||||
($bookingProduct ? 'AND p.`booking_product` = '.(int) $bookingProduct : '').
|
||||
' GROUP BY p.id_product';
|
||||
|
||||
$items = Db::getInstance()->executeS($sql);
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<?php
|
||||
/*
|
||||
* 2010-2022 Webkul.
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* All right is reserved,
|
||||
* Please go through LICENSE.txt file inside our module
|
||||
*
|
||||
* 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 CustomizationPolicy.txt file inside our module for more information.
|
||||
*
|
||||
* @author Webkul IN
|
||||
* @copyright 2010-2022 Webkul IN
|
||||
* @license LICENSE.txt
|
||||
*/
|
||||
|
||||
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
||||
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
||||
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
|
||||
header('Location: ../../');
|
||||
exit;
|
||||
<?php
|
||||
/**
|
||||
* 2010-2023 Webkul.
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* All right is reserved,
|
||||
* Please go through this link for complete license : https://store.webkul.com/license.html
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade this module to newer
|
||||
* versions in the future. If you wish to customize this module for your
|
||||
* needs please refer to https://store.webkul.com/customisation-guidelines/ for more information.
|
||||
*
|
||||
* @author Webkul IN <support@webkul.com>
|
||||
* @copyright 2010-2023 Webkul IN
|
||||
* @license https://store.webkul.com/license.html
|
||||
*/
|
||||
|
||||
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
||||
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
||||
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
|
||||
header('Location: ../../../');
|
||||
exit;
|
||||
1
admin/themes/default/css/partials/ndv3.css
Normal file
1
admin/themes/default/css/partials/ndv3.css
Normal file
@@ -0,0 +1 @@
|
||||
.dashboard-chart-tooltip{background-color:#333;padding:0px 10px 10px 10px;color:#fff;min-width:100px}.dashboard-chart-tooltip label{display:flex;align-items:baseline;gap:5px;font-weight:bold;padding-top:10px}.dashboard-chart-tooltip .tooltip-content{margin-top:5px}.dashboard-chart-tooltip .tooltip-content p{display:flex;align-items:baseline;gap:5px;text-align:left;padding-left:5px}.dashboard-chart-tooltip .tooltip-data-color{display:flex;flex-direction:column;align-items:baseline;padding:5px;max-width:2px}.dashboard-chart-tooltip .text-danger{color:#FF655C}.dashboard-chart-tooltip .text-success{color:#56CE56}
|
||||
1396
admin/themes/default/css/vendor/nv.d3.css
vendored
1396
admin/themes/default/css/vendor/nv.d3.css
vendored
File diff suppressed because it is too large
Load Diff
17
admin/themes/default/js/vendor/nv.d3.min.js
vendored
17
admin/themes/default/js/vendor/nv.d3.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -106,6 +106,7 @@
|
||||
@import "partials/ladda"
|
||||
@import "partials/date-picker"
|
||||
@import "partials/select2"
|
||||
@import "partials/ndv3"
|
||||
|
||||
//Backward compatibility
|
||||
@import "partials/backward"
|
||||
|
||||
@@ -132,6 +132,12 @@
|
||||
.data_value
|
||||
display: block
|
||||
text-align: center
|
||||
.nv-axis.nv-x .tick line, .nv-axis.nv-y .tick line, .nv-interactive .nv-interactiveGuideLine line
|
||||
display: none
|
||||
.nvd3.nv-pie path
|
||||
fill-opacity: 1
|
||||
.nv-label text
|
||||
fill: #FFF!important
|
||||
|
||||
#dashgoals
|
||||
svg
|
||||
|
||||
@@ -4,10 +4,20 @@
|
||||
#customization_list
|
||||
border: 0px
|
||||
|
||||
.booking_occupancy_edit, .booking_occupancy
|
||||
.occupancy-info-separator
|
||||
margin-top: 0px
|
||||
margin-bottom: 10px
|
||||
.close_occupancy
|
||||
text-decoration: underline
|
||||
|
||||
.booking_occupancy
|
||||
.booking_occupancy_wrapper
|
||||
max-height: 250px
|
||||
overflow-x: auto
|
||||
label.room_num_wrapper
|
||||
text-decoration: underline
|
||||
margin-bottom: 10px
|
||||
|
||||
#booking-documents-modal
|
||||
.documents-list
|
||||
@@ -16,3 +26,23 @@
|
||||
img
|
||||
max-height: 55px
|
||||
max-width: 55px
|
||||
.loading_overlay
|
||||
display: none
|
||||
position: fixed
|
||||
left: 0
|
||||
top: 0
|
||||
height: 100%
|
||||
width: 100%
|
||||
background-color: rgba(0, 0, 0, 0.5)
|
||||
z-index: 100000
|
||||
.loading-img
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 0
|
||||
right: 0
|
||||
margin: 0 auto
|
||||
|
||||
|
||||
.room_status_info_form
|
||||
.room_status
|
||||
white-space: normal
|
||||
|
||||
@@ -64,7 +64,7 @@ $sidebar-menu-hover-color: white !default
|
||||
$sidebar-menu-bg-hover-color: #282b30
|
||||
|
||||
// Toolbar
|
||||
$toolbar-buttons-color: #2eacce
|
||||
$toolbar-buttons-color: #00aff0
|
||||
$toolbar-buttons-hover-color: #40c9ed
|
||||
|
||||
// Scaffolding
|
||||
|
||||
@@ -200,6 +200,8 @@ $chosen-sprite-path: '../img/chosen-sprite.png'
|
||||
input
|
||||
position: absolute
|
||||
@include left(-9000px)
|
||||
&:before
|
||||
visibility: hidden
|
||||
|
||||
.chosen-container-multi
|
||||
.chosen-choices
|
||||
@@ -227,6 +229,7 @@ $chosen-sprite-path: '../img/chosen-sprite.png'
|
||||
border: 0 !important
|
||||
color: $gray
|
||||
height: $chosen-multi-height - 8px
|
||||
width: 100% !important
|
||||
margin: 0
|
||||
padding: 4px
|
||||
outline: 0
|
||||
@@ -295,6 +298,15 @@ $chosen-sprite-path: '../img/chosen-sprite.png'
|
||||
.search-field input
|
||||
color: #111 !important
|
||||
|
||||
.chosen-container-multi.chosen-options-horizontal .chosen-choices
|
||||
max-height: 55px !important
|
||||
white-space: nowrap
|
||||
overflow-x: auto
|
||||
|
||||
.chosen-container-multi.chosen-options-horizontal .chosen-choices li
|
||||
float: none
|
||||
display: inline-block
|
||||
|
||||
.chosen-disabled
|
||||
cursor: default
|
||||
opacity: 0.5 !important
|
||||
@@ -341,4 +353,7 @@ $chosen-sprite-path: '../img/chosen-sprite.png'
|
||||
.chosen-search input
|
||||
background: url($chosen-sprite-path) no-repeat -28px -20px, $chosen-background
|
||||
direction: rtl
|
||||
padding: 4px 5px 4px 20px
|
||||
padding: 4px 5px 4px 20px
|
||||
|
||||
#list_filters_panel .chosen-container
|
||||
width: 100% !important
|
||||
@@ -16,7 +16,7 @@ body
|
||||
@include float(left)
|
||||
|
||||
#content.bootstrap
|
||||
padding: 120px 10px 0
|
||||
padding: 90px 10px 0
|
||||
@include transition-property(margin)
|
||||
@include transition-duration(0.4s)
|
||||
@include transition-timing-function(ease-out)
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
@extend .icon-cogs
|
||||
.icon-AdminAdmin
|
||||
@extend .icon-cog
|
||||
.icon-AdminParentStats
|
||||
.icon-AdminStats
|
||||
@extend .icon-bar-chart
|
||||
.icon-AdminStock
|
||||
@extend .icon-archive
|
||||
@@ -362,7 +362,7 @@
|
||||
@extend .icon-edit
|
||||
.process-icon-newAttributes, .process-icon-new, .process-icon-new-url
|
||||
@extend .icon-plus-sign
|
||||
.process-icon-modules-list
|
||||
.process-icon-modules-list, .process-icon-puzzle-piece
|
||||
@extend .icon-puzzle-piece
|
||||
.process-icon-save-date
|
||||
@extend .icon-download
|
||||
|
||||
@@ -268,6 +268,11 @@ $min-height: 850px
|
||||
width: 200px
|
||||
@include margin-right(5px)
|
||||
@include float(right)
|
||||
.clear_search
|
||||
position: absolute
|
||||
top: 6px
|
||||
z-index: 10
|
||||
@include right(8px)
|
||||
li.maintab, li.subtab
|
||||
height: 28px
|
||||
padding: 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.page-head
|
||||
width: 100%
|
||||
height: 100px
|
||||
height: 78px
|
||||
padding: 0
|
||||
margin: 0
|
||||
position: fixed
|
||||
@@ -14,10 +14,11 @@
|
||||
@include float(left)
|
||||
position: relative
|
||||
margin: 0
|
||||
font: 20pt $font-family-sans-serif
|
||||
font: 14pt $font-family-sans-serif
|
||||
font-weight: bold
|
||||
color: #363A41
|
||||
white-space: nowrap
|
||||
@include padding(26px, 0, 0, ($widthSidebarNav+20px))
|
||||
@include padding(31px, 0, 0, ($widthSidebarNav+20px))
|
||||
@media (max-width: $screen-tablet)
|
||||
@include padding(26px, 0, 0, 70px)
|
||||
a
|
||||
@@ -40,6 +41,7 @@
|
||||
position: absolute
|
||||
background-color: transparent!important
|
||||
@include right(0)
|
||||
top: 18px
|
||||
@media (max-width: $screen-sm)
|
||||
#toolbar-nav
|
||||
border: none
|
||||
@@ -48,37 +50,54 @@
|
||||
@include padding(3px, 0, 0, 0)
|
||||
.toolbar_btn
|
||||
position: relative
|
||||
padding: 20px 5px !important
|
||||
padding: 10px 10px !important
|
||||
font-size: 12px
|
||||
line-height: 8px
|
||||
color: $main-color
|
||||
color: $toolbar-buttons-color
|
||||
text-align: center
|
||||
text-shadow: none
|
||||
white-space: nowrap
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
border: 1px solid $toolbar-buttons-color
|
||||
border-radius: 2px
|
||||
@include margin(0, 3px, 2px, 0)
|
||||
@media (max-width: $screen-desktop)
|
||||
width: 46px
|
||||
font-size: 11px
|
||||
div
|
||||
color: #363A41
|
||||
i
|
||||
color: $toolbar-buttons-color
|
||||
display: inline
|
||||
font-size: 18px
|
||||
&:hover
|
||||
color: $toolbar-buttons-hover-color
|
||||
div
|
||||
padding-top: 10px
|
||||
span
|
||||
position: relative
|
||||
top: -2px
|
||||
left: 2px
|
||||
color: #363A41
|
||||
font-weight: 400
|
||||
.dropdown-toolbar
|
||||
display: none
|
||||
@include float(right)
|
||||
@include border-radius(3px)
|
||||
@media (max-width: $screen-sm)
|
||||
display: block
|
||||
padding: 6px 10px !important
|
||||
margin-right: 10px
|
||||
@media (max-width: $screen-xs)
|
||||
margin-right: 5px
|
||||
|
||||
#toolbar-nav
|
||||
li + li
|
||||
margin-left: 8px
|
||||
ul.page-breadcrumb
|
||||
position: absolute
|
||||
list-style: none
|
||||
margin: 0
|
||||
padding: 0
|
||||
top: 4px
|
||||
top: 9px
|
||||
height: 20px
|
||||
line-height: 20px
|
||||
color: black
|
||||
|
||||
29
admin/themes/default/sass/partials/ndv3.sass
Normal file
29
admin/themes/default/sass/partials/ndv3.sass
Normal file
@@ -0,0 +1,29 @@
|
||||
.dashboard-chart-tooltip
|
||||
background-color: #333
|
||||
padding: 0px 10px 10px 10px
|
||||
color: #fff
|
||||
min-width: 100px
|
||||
label
|
||||
display: flex
|
||||
align-items: baseline
|
||||
gap: 5px
|
||||
font-weight: bold
|
||||
padding-top: 10px
|
||||
.tooltip-content
|
||||
margin-top: 5px
|
||||
.tooltip-content p
|
||||
display: flex
|
||||
align-items: baseline
|
||||
gap: 5px
|
||||
text-align: left
|
||||
padding-left: 5px
|
||||
.tooltip-data-color
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: baseline
|
||||
padding: 5px
|
||||
max-width: 2px
|
||||
.text-danger
|
||||
color: #FF655C
|
||||
.text-success
|
||||
color: #56CE56
|
||||
@@ -84,7 +84,7 @@
|
||||
<i class="icon-info"></i>
|
||||
{l s='Server information'}
|
||||
</h3>
|
||||
{if count($uname)}
|
||||
{if Tools::strlen($uname) > 0}
|
||||
<p>
|
||||
<strong>{l s='Server information:'}</strong> {$uname|escape:'html':'UTF-8'}
|
||||
</p>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<div class="panel">
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 col-sm-12 col-xs-12">
|
||||
<img class="img-responsive" alt="PrestaShop Addons" src="themes/default/img/prestashop-addons-logo.png">
|
||||
<img class="img-responsive" alt="QloApps Addons" src="themes/default/img/prestashop-addons-logo.png">
|
||||
</div>
|
||||
<div class="col-lg-4 col-lg-offset-1 col-md-4 col-sm-7 col-xs-12 addons-style-search-bar">
|
||||
<form id="addons-search-form" method="get" action="http://addons.prestashop.com/{$iso_code}/search" class="float">
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
<div class="form-wrapper">
|
||||
<div class="form-group">
|
||||
<p>{l s='To add a new module, simply connect to your PrestaShop Addons account and all your purchases will be automatically imported.'}</p>
|
||||
<p>{l s='To add a new module, simply connect to your QloApps Addons account and all your purchases will be automatically imported.'}</p>
|
||||
</div>
|
||||
</div><!-- /.form-wrapper -->
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
<div class="alert alert-info">
|
||||
<h4>{l s='Can I add my own modules?'}</h4>
|
||||
<p>{l s='Please note that for security reasons, you can only add modules that are being distributed on PrestaShop Addons, the official marketplace.'}</p>
|
||||
<p>{l s='Please note that for security reasons, you can only add modules that are being distributed on QloApps Addons, the official marketplace.'}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<li>
|
||||
<a id="desc-module-update-all" class="toolbar_btn" href="{$currentIndex|escape:'html':'UTF-8'}&token={$token|escape:'html':'UTF-8'}&updateAll=1" title="{l s='Update all'}">
|
||||
<i class="process-icon-refresh"></i>
|
||||
<div>{l s='Update all'}</div>
|
||||
<span>{l s='Update all'}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
@@ -57,30 +57,32 @@
|
||||
<li>
|
||||
<a id="desc-module-check-and-update-all" class="toolbar_btn" href="{$currentIndex|escape:'html':'UTF-8'}&token={$token|escape:'html':'UTF-8'}&check=1" title="{l s='Check for update'}">
|
||||
<i class="process-icon-refresh"></i>
|
||||
<div>{l s='Check for update'}</div>
|
||||
<span>{l s='Check for update'}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
<li>
|
||||
<a id="desc-module-catalog" class="toolbar_btn anchor" href="{$link->getAdminLink('AdminModulesCatalog')}" title="{l s='Recommended Modules and Services'}">
|
||||
<i class="process-icon-modules-list"></i>
|
||||
<div>{l s='Recommended Modules and Services'}</div>
|
||||
</a>
|
||||
</li>
|
||||
{if $add_permission eq '1' && ($context_mode != Context::MODE_HOST)}
|
||||
<li>
|
||||
<a id="desc-module-new" class="toolbar_btn anchor" href="#" onclick="$('#module_install').slideToggle();" title="{l s='Add a new module'}">
|
||||
<i class="process-icon-new"></i>
|
||||
<div>{l s='Add a new module'}</div>
|
||||
</a>
|
||||
</li>
|
||||
{else}
|
||||
<li>
|
||||
<a id="desc-module-new" class="toolbar_btn" href="{$link->getAdminLink('AdminModules')}&addnewmodule" title="{l s='Add a new module'}">
|
||||
<i class="process-icon-new"></i>
|
||||
<div>{l s='Add a new module'}</div>
|
||||
<span>{l s='Recommended Modules and Services'}</span>
|
||||
</a>
|
||||
</li>
|
||||
{if $add_permission eq '1'}
|
||||
{if $context_mode != Context::MODE_HOST}
|
||||
<li>
|
||||
<a id="desc-module-new" class="toolbar_btn anchor" href="#" onclick="$('#module_install').slideToggle();" title="{l s='Add a new module'}">
|
||||
<i class="process-icon-new"></i>
|
||||
<span>{l s='Add a new module'}</span>
|
||||
</a>
|
||||
</li>
|
||||
{else}
|
||||
<li>
|
||||
<a id="desc-module-new" class="toolbar_btn" href="{$link->getAdminLink('AdminModules')}&addnewmodule" title="{l s='Add a new module'}">
|
||||
<i class="process-icon-new"></i>
|
||||
<span>{l s='Add a new module'}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
{/if}
|
||||
{if isset($help_link)}
|
||||
{* <li>
|
||||
|
||||
@@ -391,7 +391,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="allow_multiple_quantity_container" {if (!$product->available_for_order && $product->isAssociatedToShop()) || $product->auto_add_to_cart}style="display:none;"{/if}>
|
||||
<div id="allow_multiple_quantity_container" {if $product->auto_add_to_cart && $product->isAssociatedToShop()}style="display:none;"{/if}>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">
|
||||
<span class="label-tooltip" data-toggle="tooltip" title="{l s='When enabled, customer can order multiple quantity of product otherwise only one quantity can be purchased by customer per room/hotel'}">
|
||||
@@ -412,7 +412,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="max_quantity_container" class="form-group" {if (!$product->available_for_order && $product->isAssociatedToShop()) || $product->auto_add_to_cart || !$product->allow_multiple_quantity}style="display:none;"{/if}>
|
||||
<div id="max_quantity_container" class="form-group" {if ($product->auto_add_to_cart && $product->isAssociatedToShop()) || !$product->allow_multiple_quantity}style="display:none;"{/if}>
|
||||
<label class="control-label col-lg-3" for="max_quantity">
|
||||
<span class="label-tooltip" data-toggle="tooltip"
|
||||
title="{l s='Enter max allowed quantity per room, enter 0 for unlimited.'}">
|
||||
|
||||
@@ -395,7 +395,7 @@ $(document).ready(function () {
|
||||
<div class="col-lg-9">
|
||||
<div class="row">
|
||||
{if !$multi_shop}
|
||||
<input type="hidden" name="sp_id_shop" value="0" />
|
||||
<input type="hidden" name="sp_id_shop" value="1" />
|
||||
{else}
|
||||
<div class="col-lg-3">
|
||||
<select name="sp_id_shop" id="sp_id_shop">
|
||||
|
||||
@@ -134,7 +134,10 @@
|
||||
<p>{$product['name']|escape:'html':'UTF-8'}</p>
|
||||
{if $product.allow_multiple_quantity}
|
||||
<div class="qty_container">
|
||||
<input type="number" class="form-control room_type_service_product_qty qty" id="qty_{$product.id_product}" name="service_product_qty_{$product.id_product}" data-id-product="{$product.id_product}" min="1" value="{if isset($selectedRoomServiceProduct['selected_service']) && $selectedRoomServiceProduct['selected_service'] && ($product['id_product']|array_key_exists:$selectedRoomServiceProduct['selected_service'])}{$selectedRoomServiceProduct['selected_service'][$product['id_product']]['quantity']}{else}1{/if}">
|
||||
<input type="number" class="form-control room_type_service_product_qty qty" id="qty_{$product.id_product}" name="service_product_qty_{$product.id_product}" data-id-product="{$product.id_product}" min="1" data-max-quantity="{$product.max_quantity}" value="{if isset($selectedRoomServiceProduct['selected_service']) && $selectedRoomServiceProduct['selected_service'] && ($product['id_product']|array_key_exists:$selectedRoomServiceProduct['selected_service'])}{$selectedRoomServiceProduct['selected_service'][$product['id_product']]['quantity']}{else}1{/if}">
|
||||
<p style="display:{if isset($selectedRoomServiceProduct['selected_service']) && $selectedRoomServiceProduct['selected_service'] && ($product['id_product']|array_key_exists:$selectedRoomServiceProduct['selected_service']) && $selectedRoomServiceProduct['selected_service'][$product['id_product']]['quantity'] > $product.max_quantity}block{else}none{/if}; margin-top: 4px;">
|
||||
<span class="label label-warning">{l s='Maximum allowed quantity: %s' sprintf=$product.max_quantity}</span>
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
{assign var=curr_id value=$cart->id_currency|intval}
|
||||
{foreach from=$cart_detail_data item=data}
|
||||
<tr data-id-booking-data="{$data.id}" data-id-product="{$data.id_product}" data-id-room="{$data.id_room}" data-date-from="{$data.date_from}" data-date-to="{$data.date_to}" >
|
||||
<td>{$data.room_num|escape:'html':'UTF-8'}</td>
|
||||
<td>{$data.room_num|escape:'html':'UTF-8'} {hook h='displayRoomNumAfter' data=$data type='adminOrder'}</td>
|
||||
<td><img src="{$data.image_link|escape:'html':'UTF-8'}" title="Room image" /></td>
|
||||
<td>
|
||||
<p>{$data.room_type|escape:'html':'UTF-8'}</p>
|
||||
|
||||
@@ -43,97 +43,70 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$order->getDocuments() item=document}
|
||||
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if isset($document->is_delivery)}
|
||||
<tr id="delivery_{$document->id}">
|
||||
{else}
|
||||
<tr id="invoice_{$document->id}">
|
||||
{/if}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
<tr id="orderslip_{$document->id}">
|
||||
{/if}
|
||||
|
||||
<td>{dateFormat date=$document->date_add}</td>
|
||||
<td>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if isset($document->is_delivery)}
|
||||
{l s='Delivery slip'}
|
||||
{else}
|
||||
{l s='Invoice'}
|
||||
{/if}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
{l s='Credit Slip'}
|
||||
{/if}
|
||||
</td>
|
||||
<td>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if isset($document->is_delivery)}
|
||||
<a class="_blank" title="{l s='See the document'}" href="{$link->getAdminLink('AdminPdf')|escape:'html':'UTF-8'}&submitAction=generateDeliverySlipPDF&id_order_invoice={$document->id}">
|
||||
{else}
|
||||
<a class="_blank" title="{l s='See the document'}" href="{$link->getAdminLink('AdminPdf')|escape:'html':'UTF-8'}&submitAction=generateInvoicePDF&id_order_invoice={$document->id}">
|
||||
{/if}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
<a class="_blank" title="{l s='See the document'}" href="{$link->getAdminLink('AdminPdf')|escape:'html':'UTF-8'}&submitAction=generateOrderSlipPDF&id_order_slip={$document->id}">
|
||||
{/if}
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if isset($document->is_delivery)}
|
||||
{Configuration::get('PS_DELIVERY_PREFIX', $current_id_lang, null, $order->id_shop)}{'%06d'|sprintf:$document->delivery_number}
|
||||
{else}
|
||||
{$document->getInvoiceNumberFormatted($current_id_lang, $order->id_shop)}
|
||||
{/if}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
{Configuration::get('PS_CREDIT_SLIP_PREFIX', $current_id_lang)}{'%06d'|sprintf:$document->id}
|
||||
{/if}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<td>{dateFormat date=$document->date_add}</td>
|
||||
<td>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if isset($document->is_delivery)}
|
||||
--
|
||||
{else}
|
||||
{displayPrice price=$document->total_paid_tax_incl currency=$currency->id}
|
||||
{if $document->getTotalPaid()}
|
||||
<span>
|
||||
{if $document->getRestPaid() > 0}
|
||||
({displayPrice price=$document->getRestPaid() currency=$currency->id} {l s='not paid'})
|
||||
{elseif $document->getRestPaid() < 0}
|
||||
({displayPrice price=-$document->getRestPaid() currency=$currency->id} {l s='overpaid'})
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
{l s='Invoice'}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
{displayPrice price=$document->total_products_tax_incl+$document->total_shipping_tax_incl currency=$currency->id}
|
||||
{l s='Credit Slip'}
|
||||
{/if}
|
||||
</td>
|
||||
<td class="text-right document_action">
|
||||
</td>
|
||||
<td>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if !isset($document->is_delivery)}
|
||||
|
||||
{if $document->getRestPaid()}
|
||||
<a href="#form_add_payment_panel" class="js-set-payment btn btn-default anchor" data-amount="{$document->getRestPaid()}" data-id-invoice="{$document->id}" title="{l s='Set payment form'}">
|
||||
<i class="icon-money"></i>
|
||||
{l s='Enter payment'}
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
<a href="#" class="btn btn-default" onclick="$('#invoiceNote{$document->id}').show(); return false;" title="{if $document->note eq ''}{l s='Add note'}{else}{l s='Edit note'}{/if}">
|
||||
{if $document->note eq ''}
|
||||
<i class="icon-plus-sign-alt"></i>
|
||||
{l s='Add note'}
|
||||
{else}
|
||||
<i class="icon-pencil"></i>
|
||||
{l s='Edit note'}
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
{/if}
|
||||
<a class="_blank" title="{l s='See the document'}" href="{$link->getAdminLink('AdminPdf')|escape:'html':'UTF-8'}&submitAction=generateInvoicePDF&id_order_invoice={$document->id}">
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
<a class="_blank" title="{l s='See the document'}" href="{$link->getAdminLink('AdminPdf')|escape:'html':'UTF-8'}&submitAction=generateOrderSlipPDF&id_order_slip={$document->id}">
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{$document->getInvoiceNumberFormatted($current_id_lang, $order->id_shop)}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
{Configuration::get('PS_CREDIT_SLIP_PREFIX', $current_id_lang)}{'%06d'|sprintf:$document->id}
|
||||
{/if}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{displayPrice price=$document->total_paid_tax_incl currency=$currency->id}
|
||||
{if $document->getTotalPaid()}
|
||||
<span>
|
||||
{if $document->getRestPaid() > 0}
|
||||
({displayPrice price=$document->getRestPaid() currency=$currency->id} {l s='not paid'})
|
||||
{elseif $document->getRestPaid() < 0}
|
||||
({displayPrice price=-$document->getRestPaid() currency=$currency->id} {l s='overpaid'})
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
{elseif get_class($document) eq 'OrderSlip'}
|
||||
{displayPrice price=$document->total_products_tax_incl+$document->total_shipping_tax_incl currency=$currency->id}
|
||||
{/if}
|
||||
</td>
|
||||
<td class="text-right document_action">
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if $document->getRestPaid()}
|
||||
<a href="#form_add_payment_panel" class="js-set-payment btn btn-default anchor" data-amount="{$document->getRestPaid()}" data-id-invoice="{$document->id}" title="{l s='Set payment form'}">
|
||||
<i class="icon-money"></i>
|
||||
{l s='Enter payment'}
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
<a href="#" class="btn btn-default" onclick="$('#invoiceNote{$document->id}').show(); return false;" title="{if $document->note eq ''}{l s='Add note'}{else}{l s='Edit note'}{/if}">
|
||||
{if $document->note eq ''}
|
||||
<i class="icon-plus-sign-alt"></i>
|
||||
{l s='Add note'}
|
||||
{else}
|
||||
<i class="icon-pencil"></i>
|
||||
{l s='Edit note'}
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{if get_class($document) eq 'OrderInvoice'}
|
||||
{if !isset($document->is_delivery)}
|
||||
<tr id="invoiceNote{$document->id}" style="display:none">
|
||||
<td colspan="5">
|
||||
<form action="{$current_index}&viewOrder&id_order={$order->id}{if isset($smarty.get.token)}&token={$smarty.get.token|escape:'html':'UTF-8'}{/if}" method="post">
|
||||
@@ -155,7 +128,6 @@
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{/if}
|
||||
{foreachelse}
|
||||
<tr>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{**
|
||||
* 2010-2024 Webkul.
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* All right is reserved,
|
||||
* Please go through LICENSE.txt file inside our module
|
||||
*
|
||||
* 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 CustomizationPolicy.txt file inside our module for more information.
|
||||
*
|
||||
* @author Webkul IN
|
||||
* @copyright 2010-2024 Webkul IN
|
||||
* @license LICENSE.txt
|
||||
*}
|
||||
|
||||
{if is_array($hotel_rooms_info) && count($hotel_rooms_info)}
|
||||
<option value="" selected="selected">-</option>
|
||||
{foreach from=$hotel_rooms_info item=hotel_room}
|
||||
<option value="{$hotel_room.id}">{$hotel_room.room_num}, {$hotel_room.room_type_name}, {$hotel_room.hotel_name}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
@@ -0,0 +1,25 @@
|
||||
{**
|
||||
* 2010-2024 Webkul.
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* All right is reserved,
|
||||
* Please go through LICENSE.txt file inside our module
|
||||
*
|
||||
* 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 CustomizationPolicy.txt file inside our module for more information.
|
||||
*
|
||||
* @author Webkul IN
|
||||
* @copyright 2010-2024 Webkul IN
|
||||
* @license LICENSE.txt
|
||||
*}
|
||||
|
||||
{if is_array($room_types_info) && count($room_types_info)}
|
||||
<option value="" selected="selected">-</option>
|
||||
{foreach from=$room_types_info item=room_type}
|
||||
<option value="{$room_type.id_product}">{$room_type.room_type}, {$room_type.hotel_name}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
@@ -74,9 +74,6 @@
|
||||
<input type="hidden" class="max_avail_type_qty" value="">
|
||||
<div class="dropdown-menu booking_occupancy_wrapper fixed-width-xxl well well-sm">
|
||||
<div class="booking_occupancy_inner">
|
||||
<input type="hidden" class="max_adults" value="">
|
||||
<input type="hidden" class="max_children" value="">
|
||||
<input type="hidden" class="max_guests" value="">
|
||||
<div class="occupancy_info_block col-sm-12" occ_block_index="0">
|
||||
<div class="occupancy_info_head col-sm-12"><label class="room_num_wrapper">{l s='Room - 1'}</label></div>
|
||||
<div class="col-sm-12">
|
||||
@@ -87,7 +84,7 @@
|
||||
</div>
|
||||
<div class="form-group col-xs-6 occupancy_count_block">
|
||||
<label>{l s='Child'} <span class="label-desc-txt"></span></label>
|
||||
<input type="number" class="form-control num_occupancy num_children" name="occupancy[0][children]" value="0" min="0" {if $max_child_in_room}max="{$max_child_in_room}"{/if}>
|
||||
<input type="number" class="form-control num_occupancy num_children" name="occupancy[0][children]" value="0" min="0">
|
||||
({l s='Below'} {$max_child_age|escape:'htmlall':'UTF-8'} {l s='years'})
|
||||
</div>
|
||||
</div>
|
||||
@@ -101,12 +98,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="occupancy-info-separator col-sm-12">
|
||||
</div>
|
||||
</div>
|
||||
<div class="add_occupancy_block">
|
||||
<a class="add_new_occupancy_btn" href="#"><i class="icon-plus"></i> <span>{l s='Add Room'}</span></a>
|
||||
</div>
|
||||
<hr class="occupancy-info-separator col-sm-12">
|
||||
<div class="add_occupancy_block col-sm-12">
|
||||
<a class="add_new_occupancy_btn" href="#"><i class="icon-plus"></i> <span>{l s='Add Room'}</span></a>
|
||||
<a class="pull-right close_occupancy_link" href="#">{l s='close'} <i class="icon-remove"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
</a>
|
||||
{/if}
|
||||
{* Generate HTML code for printing Delivery Icon with link *}
|
||||
{if $order->delivery_number}
|
||||
{* {if $order->delivery_number}
|
||||
<a class="btn btn-default _blank" href="{$link->getAdminLink('AdminPdf')|escape:'html':'UTF-8'}&submitAction=generateDeliverySlipPDF&id_order={$order->id}">
|
||||
<i class="icon-truck"></i>
|
||||
</a>
|
||||
{/if}
|
||||
{/if} *}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*}
|
||||
|
||||
<tr class="product-line-row" data-id_room="{$data.id_room}" data-id_product="{$data.id_product}" data-id_hotel="{$data.id_hotel}" data-date_from="{$data.date_from}" data-date_to="{$data.date_to}" data-product_price="{$data.unit_amt_tax_incl}" data-id_order_detail="{$data.id_order_detail}">
|
||||
<tr class="product-line-row" data-id_htl_booking="{$data.id|escape:'html':'UTF-8'}" data-id_room="{$data.id_room}" data-id_product="{$data.id_product}" data-id_hotel="{$data.id_hotel}" data-date_from="{$data.date_from}" data-date_to="{$data.date_to}" data-product_price="{$data.unit_amt_tax_incl}" data-id_order_detail="{$data.id_order_detail}">
|
||||
{if $refund_allowed}
|
||||
<td class="standard_refund_fields" style="display:none">
|
||||
<input type="checkbox" name="id_htl_booking[]" value="{$data.id|escape:'html':'UTF-8'}" {if isset($refundReqBookings) && ($data.id|in_array:$refundReqBookings)}disabled{/if}/>
|
||||
<input type="checkbox" name="id_htl_booking[]" value="{$data.id|escape:'html':'UTF-8'}" {if (isset($refundReqBookings) && ($data.id|in_array:$refundReqBookings)) || $data.is_refunded}disabled{/if}/>
|
||||
</td>
|
||||
{/if}
|
||||
<td class="text-center">
|
||||
@@ -79,7 +79,7 @@
|
||||
{/if}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{if $order->with_occupancy && $data['children']}
|
||||
{if $data['children']}
|
||||
<div class="dropdown booking_occupancy_show">
|
||||
<button class="btn btn-default btn-left btn-block" data-toggle="dropdown" type="button">
|
||||
<span>{if $data['adults']}{$data['adults']}{/if} {if $data['adults'] > 1}{l s='Adults'}{else}{l s='Adult'}{/if}{if {$data['children']}}, {$data['children']} {if $data['children'] > 1}{l s='Children'}{else}{l s='Child'}{/if}{/if}</span>
|
||||
@@ -98,67 +98,63 @@
|
||||
{else}
|
||||
<span class="booking_occupancy_show">{if $data['adults']}{$data['adults']}{/if} {if $data['adults'] > 1}{l s='Adults'}{else}{l s='Adult'}{/if}{if {$data['children']}}, {$data['children']} {if $data['children'] > 1}{l s='Children'}{else}{l s='Child'}{/if}{/if}</span>
|
||||
{/if}
|
||||
{if $order->with_occupancy}
|
||||
<div class="booking_occupancy_edit" style="display:none;">
|
||||
<div class="dropdown">
|
||||
<button class="booking_guest_occupancy btn btn-default btn-left btn-block input-occupancy" type="button">
|
||||
<span>
|
||||
{if $data['adults']}{$data['adults']}{/if} {if $data['adults'] > 1}{l s='Adults'}{else}{l s='Adult'}{/if}{if {$data['children']}}, {$data['children']} {if $data['children'] > 1}{l s='Children'}{else}{l s='Child'}{/if}{/if}
|
||||
</span>
|
||||
</button>
|
||||
<div class="dropdown-menu booking_occupancy_wrapper fixed-width-xxl well well-sm">
|
||||
<div class="booking_occupancy_inner">
|
||||
<input type="hidden" class="max_adults" value="{if isset($data['room_type_info'])}{$data['room_type_info']['max_adults']|escape:'html':'UTF-8'}{/if}">
|
||||
<input type="hidden" class="max_children" value="{if isset($data['room_type_info'])}{$data['room_type_info']['max_children']|escape:'html':'UTF-8'}{/if}">
|
||||
<input type="hidden" class="max_guests" value="{if isset($data['room_type_info'])}{$data['room_type_info']['max_guests']|escape:'html':'UTF-8'}{/if}">
|
||||
<div class="occupancy_info_block" occ_block_index="0">
|
||||
<div class="occupancy_info_head col-sm-12"><span class="room_num_wrapper">{l s='Room - 1'}</span></div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 occupancy_count_block">
|
||||
<div class="col-sm-12">
|
||||
<label>{l s='Adults'}</label>
|
||||
<input type="number" class="form-control num_occupancy num_adults" name="occupancy[0][adults]" value="{$data['adults']}" min="1" max="{$data['room_type_info']['max_adults']|escape:'html':'UTF-8'}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6 occupancy_count_block">
|
||||
<div class="col-sm-12">
|
||||
<label>{l s='Child'} <span class="label-desc-txt"></span></label>
|
||||
<input type="number" class="form-control num_occupancy num_children" name="occupancy[0][children]" value="{$data['children']}" min="0" max="{$data['room_type_info']['max_children']|escape:'html':'UTF-8'}">
|
||||
({l s='Below'} {$max_child_age|escape:'htmlall':'UTF-8'} {l s='years'})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row children_age_info_block" {if !isset($data['child_ages']) || !$data['child_ages']}style="display:none"{/if}>
|
||||
<div class="col-sm-12">
|
||||
<label class="col-sm-12">{l s='All Children'}</label>
|
||||
<div class="col-sm-12">
|
||||
<div class="row children_ages">
|
||||
{if isset($data['child_ages']) && $data['child_ages']}
|
||||
{foreach $data['child_ages'] as $childAge}
|
||||
<p class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
|
||||
<select class="guest_child_age room_occupancies" name="occupancy[0][child_ages][]">
|
||||
<option value="-1" {if $childAge == -1}selected{/if}>{l s='Select 1'}</option>
|
||||
<option value="0" {if $childAge == 0}selected{/if}>{l s='Under 1'}</option>
|
||||
{for $age=1 to ($max_child_age-1)}
|
||||
<option value="{$age|escape:'htmlall':'UTF-8'}" {if $childAge == $age}selected{/if}>{$age|escape:'htmlall':'UTF-8'}</option>
|
||||
{/for}
|
||||
</select>
|
||||
</p>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="occupancy-info-separator">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<span class="booking_occupancy_edit" style="display:none;">{if $data['adults']}{$data['adults']}{/if} {if $data['adults'] > 1}{l s='Adults'}{else}{l s='Adult'}{/if}{if {$data['children']}}, {$data['children']} {if $data['children'] > 1}{l s='Children'}{else}{l s='Child'}{/if}{/if}</span>
|
||||
{/if}
|
||||
|
||||
<div class="booking_occupancy_edit" style="display:none;">
|
||||
<div class="dropdown">
|
||||
<button class="booking_guest_occupancy btn btn-default btn-left btn-block input-occupancy" type="button">
|
||||
<span>
|
||||
{if $data['adults']}{$data['adults']}{/if} {if $data['adults'] > 1}{l s='Adults'}{else}{l s='Adult'}{/if}{if {$data['children']}}, {$data['children']} {if $data['children'] > 1}{l s='Children'}{else}{l s='Child'}{/if}{/if}
|
||||
</span>
|
||||
</button>
|
||||
<div class="dropdown-menu booking_occupancy_wrapper fixed-width-xxl well well-sm">
|
||||
<div class="booking_occupancy_inner row">
|
||||
<div class="occupancy_info_block col-sm-12" occ_block_index="0">
|
||||
<div class="row">
|
||||
<div class="col-xs-6 form-group occupancy_count_block">
|
||||
<div class="col-sm-12">
|
||||
<label>{l s='Adults'}</label>
|
||||
<input type="number" class="form-control num_occupancy num_adults" name="occupancy[0][adults]" value="{$data['adults']}" min="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6 form-group occupancy_count_block">
|
||||
<div class="col-sm-12">
|
||||
<label>{l s='Child'} <span class="label-desc-txt"></span></label>
|
||||
<input type="number" class="form-control num_occupancy num_children" name="occupancy[0][children]" value="{$data['children']}" min="0">
|
||||
({l s='Below'} {$max_child_age|escape:'htmlall':'UTF-8'} {l s='years'})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row children_age_info_block" {if !isset($data['child_ages']) || !$data['child_ages']}style="display:none"{/if}>
|
||||
<div class="col-sm-12 form-group">
|
||||
<label class="col-sm-12">{l s='All Children'}</label>
|
||||
<div class="col-sm-12">
|
||||
<div class="row children_ages">
|
||||
{if isset($data['child_ages']) && $data['child_ages']}
|
||||
{foreach $data['child_ages'] as $childAge}
|
||||
<p class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
|
||||
<select class="guest_child_age room_occupancies" name="occupancy[0][child_ages][]">
|
||||
<option value="-1" {if $childAge == -1}selected{/if}>{l s='Select 1'}</option>
|
||||
<option value="0" {if $childAge == 0}selected{/if}>{l s='Under 1'}</option>
|
||||
{for $age=1 to ($max_child_age-1)}
|
||||
<option value="{$age|escape:'htmlall':'UTF-8'}" {if $childAge == $age}selected{/if}>{$age|escape:'htmlall':'UTF-8'}</option>
|
||||
{/for}
|
||||
</select>
|
||||
</p>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="occupancy-info-separator col-sm-12">
|
||||
<div class="col-sm-12">
|
||||
<a class="pull-right close_occupancy_link" href="#">{l s='close'} <i class="icon-remove"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="room_unit_price_show">
|
||||
@@ -182,7 +178,7 @@
|
||||
<td class="text-center">
|
||||
<span class="extra_service_show">
|
||||
{convertPriceWithCurrency price=($data['extra_demands_price_te'] + $data['additional_services_price_te'] + $data['convenience_fee_te'] + $data['additional_services_price_auto_add_te']) currency=$currency->id}
|
||||
{if ($data['extra_demands_price_te'] + $data['additional_services_price_te'] + $data['convenience_fee_te'] + $data['additional_services_price_auto_add_te']) > 0}
|
||||
{if $data['extra_demands']|count || $data['additional_services']|count}
|
||||
<a href="#" data-toggle="modal" data-target="#rooms_type_extra_demands" date_from="{$data['date_from']}" date_to="{$data['date_to']}" id_product="{$data['id_product']}" id_room="{$data['id_room']}" id_order="{$order->id}" class="open_room_extra_services" id_htl_booking="{$data['id']}">
|
||||
<i class="icon icon-lg icon-info-circle"></i>
|
||||
</a>
|
||||
@@ -263,9 +259,9 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<a href="#" data-toggle="modal" data-target="#mySwappigModal" data-id_order="{$order->id}" data-room_num='{$data.room_num}' data-date_from='{$data.date_from}' data-date_to='{$data.date_to}' data-id_room='{$data.id_room}' data-cust_name='{$data.alloted_cust_name}' data-cust_email='{$data.alloted_cust_email}' data-avail_rm_swap='{$data.avail_rooms_to_swap|@json_encode}' data-avail_rm_realloc='{$data.avail_rooms_to_realloc|@json_encode}'>
|
||||
<a href="#" id="reallocate_room_{$data['id']}" data-room_type_name="{$data['room_type_name']}" data-toggle="modal" data-target="#mySwappigModal" data-id_htl_booking="{$data['id']}" data-room_num='{$data.room_num}' data-id_room_type='{$data.id_product}' data-cust_name='{$data.alloted_cust_name}' data-cust_email='{$data.alloted_cust_email}' data-avail_rm_swap='{$data.avail_rooms_to_swap|@json_encode}' data-avail_realloc_room_types='{$data.avail_room_types_to_realloc|@json_encode}'>
|
||||
<i class="icon-refresh"></i>
|
||||
{l s='Reallocate Room'}
|
||||
{l s='Reallocate/Swap Room'}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
@@ -287,4 +283,4 @@
|
||||
</button>
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
</tr>
|
||||
|
||||
@@ -53,10 +53,13 @@
|
||||
<span class="badge badge-info label">{l s='Convenience fee'}</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td>
|
||||
<td class="col-sm-4">
|
||||
{if $service['allow_multiple_quantity']}
|
||||
<div class="qty_container">
|
||||
<input type="number" class="form-control qty" min="1" data-id_room_type_service_product_order_detail="{$service['id_room_type_service_product_order_detail']}" data-id_product="{$service['id_product']|escape:'html':'UTF-8'}" value="{$service['quantity']|escape:'html':'UTF-8'}">
|
||||
<input type="number" class="form-control qty" min="1" data-max-quantity="{$service['max_quantity']}" data-id_room_type_service_product_order_detail="{$service['id_room_type_service_product_order_detail']}" data-id_product="{$service['id_product']|escape:'html':'UTF-8'}" value="{$service['quantity']|escape:'html':'UTF-8'}">
|
||||
<p style="display:{if $service['quantity'] > $service['max_quantity']}block{else}none{/if}; margin-top: 4px;">
|
||||
<span class="label label-warning">{l s='Maximum allowed quantity: %s' sprintf=$service['max_quantity']}</span>
|
||||
</p>
|
||||
</div>
|
||||
{else}
|
||||
--
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<th class="text-center"><span class="title_box">{l s='Refunded amount'}</span></th>
|
||||
{/if}
|
||||
{if ($can_edit && !$order->hasBeenDelivered())}
|
||||
<th class="text-center fixed-width-lg"><span class="title_box">{l s='Edit Order'}</th>
|
||||
<th class="text-center fixed-width-lg"><span class="title_box">{l s='Edit Order'}</th>
|
||||
{/if}
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -32,9 +32,14 @@
|
||||
{include file='controllers/orders/_product_line.tpl'}
|
||||
{/foreach}
|
||||
{else}
|
||||
{* <tr>
|
||||
<td>{l s='No Data Found.'}</td>
|
||||
</tr> *}
|
||||
<tr>
|
||||
<td class="list-empty" colspan="14">
|
||||
<div class="list-empty-msg">
|
||||
<i class="icon-warning-sign list-empty-icon"></i>
|
||||
{l s='No rooms found'}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{* Include product line partial *}
|
||||
{include file='controllers/orders/_new_product.tpl'}
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
selectFirst: false,
|
||||
scroll: false,
|
||||
dataType: "json",
|
||||
cacheLength: 0,
|
||||
formatItem: function(data, i, max, value, term) {
|
||||
return value;
|
||||
},
|
||||
@@ -115,7 +116,8 @@
|
||||
ajax: "1",
|
||||
token: "{getAdminToken tab='AdminCartRules'}",
|
||||
tab: "AdminCartRules",
|
||||
action: "searchCartRuleVouchers"
|
||||
action: "searchCartRuleVouchers",
|
||||
id_customer: function () { return window.id_customer },
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -808,7 +810,9 @@
|
||||
ajax: "1",
|
||||
tab: "AdminCustomers",
|
||||
action: "searchCustomers",
|
||||
customer_search: $('#customer').val()},
|
||||
customer_search: $('#customer').val(),
|
||||
skip_deleted: "1",
|
||||
},
|
||||
success : function(res)
|
||||
{
|
||||
if(res.found)
|
||||
@@ -1579,6 +1583,17 @@
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', '.room_type_service_product_qty', function(e) {
|
||||
let quantityInputField = this;
|
||||
let maximumQuantity = parseInt($(quantityInputField).attr('data-max-quantity'));
|
||||
let currentQuantity = parseInt($(quantityInputField).val());
|
||||
if (currentQuantity > maximumQuantity) {
|
||||
$(quantityInputField).siblings('p').show();
|
||||
} else {
|
||||
$(quantityInputField).siblings('p').hide();
|
||||
}
|
||||
});
|
||||
|
||||
function updateServiceProducts(element)
|
||||
{
|
||||
var operator = $(element).is(':checked') ? 'up' : 'down';
|
||||
|
||||
@@ -122,25 +122,37 @@
|
||||
{if ($params.type == 'date' || $params.type == 'datetime' || $params.type == 'range') && $params.value|is_array}
|
||||
{assign var="filter_value" value=''}
|
||||
{foreach $params.value as $value}
|
||||
{if ($value|is_string && !empty($value))}
|
||||
{if empty($filter_value)}
|
||||
{if (isset($value) && ($value !== '' || $value === 0))}
|
||||
{if !(isset($filter_value) && ($filter_value !== '' || $filter_value === 0))}
|
||||
{assign var="filter_value" value=$value}
|
||||
{else}
|
||||
{assign var="filter_value" value="`$filter_value` - `$value`"}
|
||||
{/if}
|
||||
{/if}
|
||||
{/foreach}
|
||||
{if !empty($filter_value)}
|
||||
{if (isset($filter_value) && ($filter_value !== '' || $filter_value === 0))}
|
||||
<span data-filter_key="{if isset($params.name_date)}{$params.name_date}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$filter_value|escape:'html':'UTF-8'}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{else if $params.type == 'select'}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$params['list'][$params['value']]|escape:'html':'UTF-8'}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{elseif $params.type == 'select'}
|
||||
{if isset($params.multiple) && $params.multiple}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}" data-multiple="{$params.multiple|intval}" data-operator="{$params.operator}">
|
||||
{$params['title']|escape:'html':'UTF-8'}:
|
||||
<span class="filter_value">
|
||||
{foreach from=$params.value item=option name=foreachInfo}
|
||||
{$params.list[$option]}{if !$smarty.foreach.foreachInfo.last}{if $params.operator == 'or'} | {else}, {/if}{/if}
|
||||
{/foreach}
|
||||
</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{else}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$params['list'][$params['value']]|replace: ' ' : ''}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{else}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$params['value']|escape:'html':'UTF-8'}</span>
|
||||
@@ -166,7 +178,7 @@
|
||||
<input type="text" class="filter form-control" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}[0]" placeholder="{l s='From'}" value="{if isset($params.value.0)}{$params.value.0}{/if}">
|
||||
<input type="text" class="filter form-control" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}[1]" placeholder="{l s='To'}" value="{if isset($params.value.1)}{$params.value.1}{/if}">
|
||||
</div>
|
||||
{else if $params.type == 'bool'}
|
||||
{elseif $params.type == 'bool'}
|
||||
<select id="filter_input_{$key}" class="filter fixed-width-sm center" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}">
|
||||
<option value="">-</option>
|
||||
<option value="1" {if $params.value == 1} selected="selected" {/if}>{l s='Yes'}</option>
|
||||
@@ -205,21 +217,13 @@
|
||||
prevText: '',
|
||||
nextText: '',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
beforeShow: function() {
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
if (typeof dateTo != 'undefined' && dateTo != '') {
|
||||
let objDateToMax = $.datepicker.parseDate('yy-mm-dd', dateTo);
|
||||
objDateToMax.setDate(objDateToMax.getDate() - 1);
|
||||
$('#local_{$params.id_date}_0').datepicker('option', 'maxDate', objDateToMax);
|
||||
}
|
||||
},
|
||||
onClose: function() {
|
||||
let dateFrom = $('#local_{$params.id_date}_0').val().trim();
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
|
||||
if (dateFrom >= dateTo) {
|
||||
if ((dateFrom && dateTo) && (dateFrom >= dateTo)) {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
objDateToMin.setDate(objDateToMin.getDate());
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
@@ -235,7 +239,7 @@
|
||||
|
||||
if (typeof dateFrom != 'undefined' && dateFrom != '') {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
objDateToMin.setDate(objDateToMin.getDate());
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
@@ -245,18 +249,28 @@
|
||||
</script>
|
||||
</div>
|
||||
{elseif $params.type == 'select'}
|
||||
{if isset($params.filter_key)}
|
||||
<select id="filter_input_{$key}" class="filter{if isset($params.align) && $params.align == 'center'}center{/if}" onchange="$('#submitFilterButton{$list_id}').focus();$('#submitFilterButton{$list_id}').click();" name="{$list_id}Filter_{$params.filter_key}" {if isset($params.width)} style="width:{$params.width}px"{/if}>
|
||||
<option value="" {if $params.value == ''} selected="selected" {/if}>-</option>
|
||||
{if isset($params.multiple) && $params.multiple}
|
||||
<select id="filter_input_{$key}" class="filter{if isset($params.align) && $params.align == 'center'}center{/if} select_multiple_{$params.operator} chosen chosen-options-horizontal" multiple name="{$list_id}Filter_{$params.filter_key}[]" {if isset($params.width)} style="width:{$params.width}px"{/if}>
|
||||
{if isset($params.list) && is_array($params.list)}
|
||||
{foreach $params.list AS $option_value => $option_display}
|
||||
<option value="{$option_value}" {if (string)$option_display === (string)$params.value || (string)$option_value === (string)$params.value} selected="selected"{/if}>{$option_display}</option>
|
||||
<option value="{$option_value}" {if isset($params.value) && $params.value}{if in_array($option_value, $params.value)} selected="selected"{/if}{/if}>{$option_display}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</select>
|
||||
{else}
|
||||
{if isset($params.filter_key)}
|
||||
<select id="filter_input_{$key}" class="filter{if isset($params.align) && $params.align == 'center'}center{/if} {if isset($params.class)}{$params.class}{/if}" {if !isset($params.remove_onchange) || !$params.remove_onchange}onchange="$('#submitFilterButton{$list_id}').focus();$('#submitFilterButton{$list_id}').click();"{/if} name="{$list_id}Filter_{$params.filter_key}" {if isset($params.width)} style="width:{$params.width}px"{/if}>
|
||||
<option value="" {if $params.value == ''} selected="selected" {/if}>-</option>
|
||||
{if isset($params.list) && is_array($params.list)}
|
||||
{foreach $params.list AS $option_value => $option_display}
|
||||
<option value="{$option_value}" {if (string)$option_display === (string)$params.value || (string)$option_value === (string)$params.value} selected="selected"{/if}>{$option_display}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</select>
|
||||
{/if}
|
||||
{/if}
|
||||
{else}
|
||||
<input type="text" class="filter" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" value="{$params.value|escape:'html':'UTF-8'}" {if isset($params.width) && $params.width != 'auto'} style="width:{$params.width}px"{/if} />
|
||||
<input type="text" id="filter_input_{$key}" class="filter" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" value="{$params.value|escape:'html':'UTF-8'}" {if isset($params.width) && $params.width != 'auto'} style="width:{$params.width}px"{/if} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -297,12 +311,112 @@
|
||||
} else if (type == 'range') {
|
||||
$('#list_filters_panel').find('[name*="orderFilter_'+$(this).parent().data('filter_key')+'"]').val('');
|
||||
} else if (type == 'select') {
|
||||
$('#list_filters_panel').find('select[name="orderFilter_'+$(this).parent().data('filter_key')+'"] option:selected').prop("selected", false);
|
||||
$('#list_filters_panel').find('select[name*="orderFilter_'+$(this).parent().data('filter_key')+'"] option:selected').prop('selected', false);
|
||||
} else {
|
||||
$('#list_filters_panel').find('input[name="orderFilter_'+$(this).parent().data('filter_key')+'"]').val('');
|
||||
}
|
||||
|
||||
// set post data for empty multi-select filters
|
||||
$(form).find('select[multiple]').each(function (i, selectElement) {
|
||||
if ($(selectElement).find('option:selected').length == 0) {
|
||||
$(form).append('<input type="hidden" name="' + $(selectElement).attr('name').slice(0, -2) + '" value="">');
|
||||
}
|
||||
});
|
||||
|
||||
form.submit();
|
||||
});
|
||||
|
||||
$('#form-order').submit(function () {
|
||||
let form = $(this);
|
||||
$(form).find('select[multiple]').each(function (i, selectElement) {
|
||||
if ($(selectElement).val() == null) {
|
||||
$(form).append('<input type="hidden" name="' + $(selectElement).attr('name').slice(0, -2) + '" value="">');
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
function updateRoomTypeFilter() {
|
||||
let filterInputHotelName = $('#filter_input_hotel_name');
|
||||
let filterInputRoomTypeName = $('#filter_input_room_type_name');
|
||||
|
||||
let idHotel = parseInt($(filterInputHotelName).val() || '0');
|
||||
|
||||
$.ajax({
|
||||
url: currentIndex + '&token=' + token,
|
||||
data: {
|
||||
ajax: true,
|
||||
action: 'GetHotelRoomTypes',
|
||||
id_hotel: idHotel,
|
||||
},
|
||||
type: 'POST',
|
||||
dataType: 'JSON',
|
||||
success: function(response) {
|
||||
if (response.status) {
|
||||
if (response.has_room_types) {
|
||||
$(filterInputRoomTypeName).html(response.html_room_types);
|
||||
} else {
|
||||
$(filterInputRoomTypeName).find('option').not(':first').remove();
|
||||
}
|
||||
|
||||
// destroy current chosen and re-initialize
|
||||
$(filterInputRoomTypeName).chosen('destroy');
|
||||
$(filterInputRoomTypeName).chosen({
|
||||
disable_search_threshold: 5,
|
||||
search_contains: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function updateHotelRoomsFilter(useRoomType = true) {
|
||||
let filterInputHotelName = $('#filter_input_hotel_name');
|
||||
let filterInputRoomTypeName = $('#filter_input_room_type_name');
|
||||
let filterInputRoomNumber = $('#filter_input_id_room_information');
|
||||
|
||||
let idHotel = parseInt($(filterInputHotelName).val() || '0');
|
||||
let idProduct = parseInt($(filterInputRoomTypeName).val() || '0');
|
||||
|
||||
$.ajax({
|
||||
url: currentIndex + '&token=' + token,
|
||||
data: {
|
||||
ajax: true,
|
||||
action: 'GetHotelRooms',
|
||||
id_hotel: idHotel,
|
||||
id_product: useRoomType ? idProduct : 0,
|
||||
},
|
||||
type: 'POST',
|
||||
dataType: 'JSON',
|
||||
success: function(response) {
|
||||
if (response.status) {
|
||||
if (response.has_hotel_rooms) {
|
||||
$(filterInputRoomNumber).html(response.html_hotel_rooms);
|
||||
} else {
|
||||
$(filterInputRoomNumber).find('option').not(':first').remove();
|
||||
}
|
||||
|
||||
// destroy current chosen and re-initialize
|
||||
$(filterInputRoomNumber).chosen('destroy');
|
||||
$(filterInputRoomNumber).chosen({
|
||||
disable_search_threshold: 5,
|
||||
search_contains: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// manage Hotel and Room type filter inputs
|
||||
$(document).on('change', '#filter_input_hotel_name', function () {
|
||||
updateRoomTypeFilter();
|
||||
updateHotelRoomsFilter(false);
|
||||
});
|
||||
|
||||
$(document).on('change', '#filter_input_room_type_name', function () {
|
||||
updateHotelRoomsFilter();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
@@ -354,7 +468,7 @@
|
||||
.list_filters {
|
||||
padding: 0 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));;
|
||||
gap: 8px 40px;}
|
||||
.list_filters > .row {
|
||||
display: flex;
|
||||
|
||||
@@ -157,7 +157,8 @@
|
||||
{/if} -->
|
||||
<!-- End -->
|
||||
|
||||
{if $refund_allowed && !$hasCompletelyRefunded}
|
||||
<!-- Check if refund is allowed and all bookings are not requested for refund -->
|
||||
{if $refund_allowed && !$completeRefundRequestOrCancel}
|
||||
<a id="desc-order-standard_refund" class="btn btn-default" href="#refundForm">
|
||||
<i class="icon-exchange"></i>
|
||||
{if $order->getTotalPaid()|floatval}
|
||||
@@ -232,23 +233,26 @@
|
||||
</table>
|
||||
</div>
|
||||
<!-- Change status form -->
|
||||
<form action="{$currentIndex|escape:'html':'UTF-8'}&vieworder&token={$smarty.get.token}" method="post" class="form-horizontal well hidden-print">
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<select id="id_order_state" class="chosen form-control" name="id_order_state">
|
||||
{foreach from=$states item=state}
|
||||
<option value="{$state['id_order_state']|intval}"{if isset($currentState) && $state['id_order_state'] == $currentState->id} selected="selected" disabled="disabled"{/if}>{$state['name']|escape}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
<input type="hidden" name="id_order" value="{$order->id}" />
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<button type="submit" name="submitState" class="btn btn-primary">
|
||||
{l s='Update status'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{* If current state is refunded or cancelled the further order status changes are not allowed *}
|
||||
{if !isset($currentState) || (isset($currentState) && ($currentState->id != Configuration::get('PS_OS_REFUND') && $currentState->id != Configuration::get('PS_OS_CANCELED')))}
|
||||
<form action="{$currentIndex|escape:'html':'UTF-8'}&vieworder&id_order={$order->id|intval}&token={$smarty.get.token}" method="post" class="form-horizontal well hidden-print">
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<select id="id_order_state" class="chosen form-control" name="id_order_state">
|
||||
{foreach from=$states item=state}
|
||||
<option value="{$state['id_order_state']|intval}"{if isset($currentState) && $state['id_order_state'] == $currentState->id} selected="selected" disabled="disabled"{elseif ($state['id_order_state'] == Configuration::get('PS_OS_REFUND') && !$allBookingsRefunded)} disabled="disabled"{elseif ($state['id_order_state'] == Configuration::get('PS_OS_CANCELED') && !$allBookingsCancelled)} disabled="disabled"{elseif ($state['id_order_state'] == Configuration::get('PS_OS_OVERBOOKING_PAID') || $state['id_order_state'] == Configuration::get('PS_OS_OVERBOOKING_UNPAID') || $state['id_order_state'] == Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID')) && (!isset($orderOverBookings) || !$orderOverBookings)} disabled="disabled"{/if}>{$state['name']|escape}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
<input type="hidden" name="id_order" value="{$order->id}" />
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<button type="submit" name="submitState" class="btn btn-primary">
|
||||
{l s='Update status'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- Tab documents -->
|
||||
<div class="tab-pane" id="documents">
|
||||
@@ -277,61 +281,69 @@
|
||||
<th>{l s='Hotel Name'}</th>
|
||||
<th>{l s='Duration'}</th>
|
||||
<th>{l s='Documents'}</th>
|
||||
<th>{l s='Order Status'}</th>
|
||||
<th>{l s='Room Status'}</th>
|
||||
</tr>
|
||||
{if isset($htl_booking_order_data) && $htl_booking_order_data}
|
||||
{foreach from=$htl_booking_order_data item=data}
|
||||
{if !$data.is_refunded}
|
||||
<tr>
|
||||
<td>
|
||||
{$data['room_num']}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{$link->getAdminLink('AdminAddHotel')}&id={$data['id_hotel']}&updatehtl_branch_info" target="_blank">
|
||||
<span>{$data['hotel_name']}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{dateFormat date=$data['date_from']} - {dateFormat date=$data['date_to']}
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-default" onclick="BookingDocumentsModal.init({$data.id|intval}, this); return false;">
|
||||
<i class="icon icon-file-text"></i>
|
||||
{l s='Documents'} <span class="badge badge-info count-documents">{$data.num_checkin_documents}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<form action="" method="post" class="form-horizontal row room_status_info_form">
|
||||
<div class="col-sm-7">
|
||||
<select name="booking_order_status" class="form-control booking_order_status margin-bottom-5">
|
||||
{foreach from=$hotel_order_status item=state}
|
||||
<option value="{$state['id_status']|intval}" {if isset($data.id_status) && $state.id_status == $data.id_status} selected="selected" disabled="disabled"{/if}>{$state.name|escape}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
<tr>
|
||||
<td>
|
||||
{$data['room_num']}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{$link->getAdminLink('AdminAddHotel')}&id={$data['id_hotel']}&updatehtl_branch_info" target="_blank">
|
||||
<span>{$data['hotel_name']}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{dateFormat date=$data['date_from']} - {dateFormat date=$data['date_to']}
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-default" onclick="BookingDocumentsModal.init({$data.id|intval}, this); return false;">
|
||||
<i class="icon icon-file-text"></i>
|
||||
{l s='Documents'} <span class="badge badge-info count-documents">{$data.num_checkin_documents}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<form action="" method="post" class="form-horizontal row room_status_info_form">
|
||||
<div class="col-sm-7">
|
||||
{if $data.is_refunded || $data.is_cancelled}
|
||||
{if $data['id_status'] == $hotel_order_status['STATUS_ALLOTED']['id_status']}
|
||||
<p><span class="room_status badge badge-infomation">{l s='Room alloted'}</span></p>
|
||||
{/if}
|
||||
{else}
|
||||
<select name="booking_order_status" class="form-control booking_order_status margin-bottom-5">
|
||||
{foreach from=$hotel_order_status item=state}
|
||||
<option value="{$state['id_status']|intval}" {if isset($data.id_status) && $state.id_status == $data.id_status} selected="selected" disabled="disabled"{/if}>{$state.name|escape}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
{/if}
|
||||
|
||||
{if $data['id_status'] == $hotel_order_status['STATUS_CHECKED_IN']['id_status']}
|
||||
<p class="text-center"><span class="badge badge-success margin-bottom-5">{l s='Checked in on'} {dateFormat date=$data['check_in']}</span></p>
|
||||
{elseif $data['id_status'] == $hotel_order_status['STATUS_CHECKED_OUT']['id_status']}
|
||||
<p class="text-center"><span class="badge badge-success margin-bottom-5">{l s='Checked out on'} {dateFormat date=$data['check_out']}</span></p>
|
||||
{/if}
|
||||
{if $data['id_status'] == $hotel_order_status['STATUS_CHECKED_IN']['id_status']}
|
||||
<p><span class="room_status badge badge-success">{l s='Checked in on'} {dateFormat date=$data['check_in']}</span></p>
|
||||
{elseif $data['id_status'] == $hotel_order_status['STATUS_CHECKED_OUT']['id_status']}
|
||||
<p><span class="room_status badge badge-success">{l s='Checked out on'} {dateFormat date=$data['check_out']}</span></p>
|
||||
{/if}
|
||||
|
||||
{* field for the current date *}
|
||||
<input class="room_status_date wk-input-date" type="text" name="status_date" value="{if $data['id_status'] == $hotel_order_status['STATUS_CHECKED_IN']['id_status']}{$data['date_to']|date_format:"%d-%m-%Y"}{else}{$data['date_from']|date_format:"%d-%m-%Y"}{/if}" readonly/>
|
||||
{* field for the current date *}
|
||||
<input class="room_status_date wk-input-date" type="text" name="status_date" value="{if $data['id_status'] == $hotel_order_status['STATUS_CHECKED_IN']['id_status']}{$data['date_to']|date_format:"%d-%m-%Y"}{else}{$data['date_from']|date_format:"%d-%m-%Y"}{/if}" readonly/>
|
||||
|
||||
<input type="hidden" name="date_from" value="{$data['date_from']|date_format:"%Y-%m-%d"}" />
|
||||
<input type="hidden" name="date_to" value="{$data['date_to']|date_format:"%Y-%m-%d"}" />
|
||||
<input type="hidden" name="id_room" value="{$data['id_room']}" />
|
||||
<input type="hidden" name="id_order" value="{$order->id}" />
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<button type="submit" name="submitbookingOrderStatus" class="btn btn-primary">
|
||||
{l s='Update Status'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
<input type="hidden" name="date_from" value="{$data['date_from']|date_format:"%Y-%m-%d"}" />
|
||||
<input type="hidden" name="date_to" value="{$data['date_to']|date_format:"%Y-%m-%d"}" />
|
||||
<input type="hidden" name="id_room" value="{$data['id_room']}" />
|
||||
<input type="hidden" name="id_order" value="{$order->id}" />
|
||||
</div>
|
||||
<div class="col-sm-5 text-right">
|
||||
{if $data.is_refunded || $data.is_cancelled}
|
||||
<span class="badge badge-danger">{if $data.is_cancelled}{l s='Cancelled'}{else}{l s='Refunded'}{/if}</span>
|
||||
{else}
|
||||
<button type="submit" name="submitbookingOrderStatus" class="btn btn-primary">
|
||||
{l s='Update Status'}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
{else}
|
||||
<tr>
|
||||
@@ -352,121 +364,123 @@
|
||||
</script>
|
||||
<hr />
|
||||
<!-- Tab nav -->
|
||||
<ul class="nav nav-tabs" id="myTab" style="display:none"><!-- by webkul -->
|
||||
{$HOOK_TAB_SHIP}
|
||||
<li class="active">
|
||||
<a href="#shipping">
|
||||
<i class="icon-truck "></i>
|
||||
{l s='Shipping'} <span class="badge">{$order->getShipping()|@count}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#returns">
|
||||
<i class="icon-undo"></i>
|
||||
{l s='Merchandise Returns'} <span class="badge">{$order->getReturn()|@count}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab content -->
|
||||
<div class="tab-content panel" style="display:none"><!-- by webkul -->
|
||||
{$HOOK_CONTENT_SHIP}
|
||||
<!-- Tab shipping -->
|
||||
<div class="tab-pane active" id="shipping">
|
||||
<h4 class="visible-print">{l s='Shipping'} <span class="badge">({$order->getShipping()|@count})</span></h4>
|
||||
<!-- Shipping block -->
|
||||
{if !$order->isVirtual()}
|
||||
<div class="form-horizontal">
|
||||
{if $order->gift_message}
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='Message'}</label>
|
||||
<div class="col-lg-9">
|
||||
<p class="form-control-static">{$order->gift_message|nl2br}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{include file='controllers/orders/_shipping.tpl'}
|
||||
{if $carrierModuleCall}
|
||||
{$carrierModuleCall}
|
||||
{/if}
|
||||
<hr />
|
||||
{if $order->recyclable}
|
||||
<span class="label label-success"><i class="icon-check"></i> {l s='Recycled packaging'}</span>
|
||||
{else}
|
||||
<span class="label label-inactive"><i class="icon-remove"></i> {l s='Recycled packaging'}</span>
|
||||
{/if}
|
||||
{* <!-- commented by qlo -->
|
||||
<ul class="nav nav-tabs" id="myTab" style="display:none">
|
||||
{$HOOK_TAB_SHIP}
|
||||
<li class="active">
|
||||
<a href="#shipping">
|
||||
<i class="icon-truck "></i>
|
||||
{l s='Shipping'} <span class="badge">{$order->getShipping()|@count}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#returns">
|
||||
<i class="icon-undo"></i>
|
||||
{l s='Merchandise Returns'} <span class="badge">{$order->getReturn()|@count}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab content -->
|
||||
<div class="tab-content panel" style="display:none">
|
||||
{$HOOK_CONTENT_SHIP}
|
||||
<!-- Tab shipping -->
|
||||
<div class="tab-pane active" id="shipping">
|
||||
<h4 class="visible-print">{l s='Shipping'} <span class="badge">({$order->getShipping()|@count})</span></h4>
|
||||
<!-- Shipping block -->
|
||||
{if !$order->isVirtual()}
|
||||
<div class="form-horizontal">
|
||||
{if $order->gift_message}
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3">{l s='Message'}</label>
|
||||
<div class="col-lg-9">
|
||||
<p class="form-control-static">{$order->gift_message|nl2br}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{include file='controllers/orders/_shipping.tpl'}
|
||||
{if $carrierModuleCall}
|
||||
{$carrierModuleCall}
|
||||
{/if}
|
||||
<hr />
|
||||
{if $order->recyclable}
|
||||
<span class="label label-success"><i class="icon-check"></i> {l s='Recycled packaging'}</span>
|
||||
{else}
|
||||
<span class="label label-inactive"><i class="icon-remove"></i> {l s='Recycled packaging'}</span>
|
||||
{/if}
|
||||
|
||||
{if $order->gift}
|
||||
<span class="label label-success"><i class="icon-check"></i> {l s='Gift wrapping'}</span>
|
||||
{else}
|
||||
<span class="label label-inactive"><i class="icon-remove"></i> {l s='Gift wrapping'}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- Tab returns -->
|
||||
<div class="tab-pane" id="returns">
|
||||
<h4 class="visible-print">{l s='Merchandise Returns'} <span class="badge">({$order->getReturn()|@count})</span></h4>
|
||||
{if !$order->isVirtual()}
|
||||
<!-- Return block -->
|
||||
{if $order->getReturn()|count > 0}
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span class="title_box ">{l s='Date'}</span></th>
|
||||
<th><span class="title_box ">{l s='Type'}</span></th>
|
||||
<th><span class="title_box ">{l s='Carrier'}</span></th>
|
||||
<th><span class="title_box ">{l s='Tracking number'}</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$order->getReturn() item=line}
|
||||
<tr>
|
||||
<td>{$line.date_add}</td>
|
||||
<td>{l s=$line.type}</td>
|
||||
<td>{$line.state_name}</td>
|
||||
<td class="actions">
|
||||
<span class="shipping_number_show">{if isset($line.url) && isset($line.tracking_number)}<a href="{$line.url|replace:'@':$line.tracking_number|escape:'html':'UTF-8'}">{$line.tracking_number}</a>{elseif isset($line.tracking_number)}{$line.tracking_number}{/if}</span>
|
||||
{if $line.can_edit}
|
||||
<form method="post" action="{$link->getAdminLink('AdminOrders')|escape:'html':'UTF-8'}&vieworder&id_order={$order->id|intval}&id_order_invoice={if $line.id_order_invoice}{$line.id_order_invoice|intval}{else}0{/if}&id_carrier={if $line.id_carrier}{$line.id_carrier|escape:'html':'UTF-8'}{else}0{/if}">
|
||||
<span class="shipping_number_edit" style="display:none;">
|
||||
<button type="button" name="tracking_number">
|
||||
{$line.tracking_number|htmlentities}
|
||||
</button>
|
||||
<button type="submit" class="btn btn-default" name="submitShippingNumber">
|
||||
{l s='Update'}
|
||||
</button>
|
||||
</span>
|
||||
<button href="#" class="edit_shipping_number_link">
|
||||
<i class="icon-pencil"></i>
|
||||
{l s='Edit'}
|
||||
</button>
|
||||
<button href="#" class="cancel_shipping_number_link" style="display: none;">
|
||||
<i class="icon-remove"></i>
|
||||
{l s='Cancel'}
|
||||
</button>
|
||||
</form>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{else}
|
||||
<div class="list-empty hidden-print">
|
||||
<div class="list-empty-msg">
|
||||
<i class="icon-warning-sign list-empty-icon"></i>
|
||||
{l s='No merchandise returned yet'}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $carrierModuleCall}
|
||||
{$carrierModuleCall}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{if $order->gift}
|
||||
<span class="label label-success"><i class="icon-check"></i> {l s='Gift wrapping'}</span>
|
||||
{else}
|
||||
<span class="label label-inactive"><i class="icon-remove"></i> {l s='Gift wrapping'}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- Tab returns -->
|
||||
<div class="tab-pane" id="returns">
|
||||
<h4 class="visible-print">{l s='Merchandise Returns'} <span class="badge">({$order->getReturn()|@count})</span></h4>
|
||||
{if !$order->isVirtual()}
|
||||
<!-- Return block -->
|
||||
{if $order->getReturn()|count > 0}
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span class="title_box ">{l s='Date'}</span></th>
|
||||
<th><span class="title_box ">{l s='Type'}</span></th>
|
||||
<th><span class="title_box ">{l s='Carrier'}</span></th>
|
||||
<th><span class="title_box ">{l s='Tracking number'}</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$order->getReturn() item=line}
|
||||
<tr>
|
||||
<td>{$line.date_add}</td>
|
||||
<td>{l s=$line.type}</td>
|
||||
<td>{$line.state_name}</td>
|
||||
<td class="actions">
|
||||
<span class="shipping_number_show">{if isset($line.url) && isset($line.tracking_number)}<a href="{$line.url|replace:'@':$line.tracking_number|escape:'html':'UTF-8'}">{$line.tracking_number}</a>{elseif isset($line.tracking_number)}{$line.tracking_number}{/if}</span>
|
||||
{if $line.can_edit}
|
||||
<form method="post" action="{$link->getAdminLink('AdminOrders')|escape:'html':'UTF-8'}&vieworder&id_order={$order->id|intval}&id_order_invoice={if $line.id_order_invoice}{$line.id_order_invoice|intval}{else}0{/if}&id_carrier={if $line.id_carrier}{$line.id_carrier|escape:'html':'UTF-8'}{else}0{/if}">
|
||||
<span class="shipping_number_edit" style="display:none;">
|
||||
<button type="button" name="tracking_number">
|
||||
{$line.tracking_number|htmlentities}
|
||||
</button>
|
||||
<button type="submit" class="btn btn-default" name="submitShippingNumber">
|
||||
{l s='Update'}
|
||||
</button>
|
||||
</span>
|
||||
<button href="#" class="edit_shipping_number_link">
|
||||
<i class="icon-pencil"></i>
|
||||
{l s='Edit'}
|
||||
</button>
|
||||
<button href="#" class="cancel_shipping_number_link" style="display: none;">
|
||||
<i class="icon-remove"></i>
|
||||
{l s='Cancel'}
|
||||
</button>
|
||||
</form>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{else}
|
||||
<div class="list-empty hidden-print">
|
||||
<div class="list-empty-msg">
|
||||
<i class="icon-warning-sign list-empty-icon"></i>
|
||||
{l s='No merchandise returned yet'}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $carrierModuleCall}
|
||||
{$carrierModuleCall}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
*}
|
||||
<script>
|
||||
$('#myTab a').click(function (e) {
|
||||
e.preventDefault()
|
||||
@@ -1163,7 +1177,7 @@
|
||||
<div class="panel" id="refundForm">
|
||||
<div class="panel-heading">
|
||||
<i class="icon-shopping-cart"></i>
|
||||
{l s='Order Detail'} <span class="badge">{$order_detail_data|@count}</span>
|
||||
{l s='Rooms Detail'} <span class="badge">{$order_detail_data|@count}</span>
|
||||
{* by webkul products changes as rooms *}
|
||||
</div>
|
||||
{* by webkul this code is added for showing rooms information on the order detail page *}
|
||||
@@ -1185,9 +1199,11 @@
|
||||
<input type="hidden" name="TaxMethod" value="1">
|
||||
{/if}
|
||||
{if $can_edit}
|
||||
<div class="row-margin-bottom row-margin-top standard_refund_fields" style="display: none;">
|
||||
<textarea class="cancellation_reason" name="cancellation_reason" placeholder="{l s='Enter reason to cancel bookings'}"></textarea>
|
||||
</div>
|
||||
{if $refund_allowed && !$completeRefundRequestOrCancel}
|
||||
<div class="row-margin-bottom row-margin-top standard_refund_fields" style="display: none;">
|
||||
<textarea class="cancellation_reason" name="cancellation_reason" placeholder="{l s='Enter reason to cancel bookings'}"></textarea>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="row-margin-bottom row-margin-top order_action">
|
||||
{if !$order->hasBeenDelivered()}
|
||||
{* <button type="button" id="add_product" class="btn btn-default">
|
||||
@@ -1204,7 +1220,7 @@
|
||||
{l s='Add a new discount'}
|
||||
</button>
|
||||
|
||||
{if $refund_allowed && !$hasCompletelyRefunded}
|
||||
{if $refund_allowed && !$completeRefundRequestOrCancel}
|
||||
<div class="pull-right">
|
||||
<button style="display: none;" type="button" class="btn btn-default standard_refund_fields" id="cancelRefund">
|
||||
{l s='Cancel'}
|
||||
@@ -1228,7 +1244,7 @@
|
||||
</div>
|
||||
<div class="col-xs-6 pull-right">
|
||||
<div class="panel panel-vouchers" style="{if !sizeof($discounts)}display:none;{/if}">
|
||||
{if (sizeof($discounts) || $can_edit)}
|
||||
{if sizeof($discounts)}
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
@@ -1259,9 +1275,9 @@
|
||||
{displayPrice price=$discount['value'] currency=$currency->id}
|
||||
</td>
|
||||
{if $can_edit}
|
||||
<td>
|
||||
<a href="{$current_index}&submitDeleteVoucher&id_order_cart_rule={$discount['id_order_cart_rule']}&id_order={$order->id}&token={$smarty.get.token|escape:'html':'UTF-8'}">
|
||||
<i class="icon-minus-sign"></i>
|
||||
<td class="text-center">
|
||||
<a class="btn btn-default" href="{$current_index}&submitDeleteVoucher&id_order_cart_rule={$discount['id_order_cart_rule']}&id_order={$order->id}&token={$smarty.get.token|escape:'html':'UTF-8'}">
|
||||
<i class="icon-trash"></i>
|
||||
{l s='Delete voucher'}
|
||||
</a>
|
||||
</td>
|
||||
@@ -1271,6 +1287,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
{if $can_edit}
|
||||
<div class="current-edit" id="voucher_form" style="display:none;">
|
||||
{include file='controllers/orders/_discount_form.tpl'}
|
||||
</div>
|
||||
@@ -1392,16 +1410,14 @@
|
||||
</tr>
|
||||
{/if}
|
||||
|
||||
{if $order->total_paid_tax_incl > $order->total_paid_real}
|
||||
<tr>
|
||||
<td class="text-right"><strong>{l s='Due Amount'}</strong></td>
|
||||
<td class="amount text-right nowrap">
|
||||
<strong>
|
||||
{displayPrice currency=$order->id_currency price=($order->total_paid_tax_incl - $order->total_paid_real)}
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
<tr>
|
||||
<td class="text-right"><strong>{l s='Due Amount'}</strong></td>
|
||||
<td class="amount text-right nowrap">
|
||||
<strong>
|
||||
{displayPrice currency=$order->id_currency price=($order->total_paid_tax_incl - $order->total_paid_real)}
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1493,7 +1509,7 @@
|
||||
<li role="presentation" class="active"><a href="#reallocate_room_tab" aria-controls="reallocate" role="tab" data-toggle="tab">{l s='Room Reallocation'}</a></li>
|
||||
<li role="presentation"><a href="#swap_room_tab" aria-controls="swap" role="tab" data-toggle="tab">{l s='Swap Room'}</a></li>
|
||||
</ul>
|
||||
<div class="tab-content panel active">
|
||||
<div class="tab-content active">
|
||||
<div role="tabpanel" class="tab-pane active" id="reallocate_room_tab">
|
||||
<form method="post" action="{$link->getAdminLink('AdminOrders')|escape:'html':'UTF-8'}&vieworder&id_order={$order->id|intval}">
|
||||
<div class="modal-header">
|
||||
@@ -1501,31 +1517,63 @@
|
||||
<h4 class="modal-title" id="realloc_myModalLabel">{l s='Reallocate Rooms'}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="curr_room_num" class="control-label model-label">{l s='Current Room Number:'}</label>
|
||||
<input type="text" class="form-control modal_curr_room_num" name="modal_curr_room_num" readonly="true">
|
||||
<input type="hidden" class="form-control modal_date_from" name="modal_date_from">
|
||||
<input type="hidden" class="form-control modal_date_to" name="modal_date_to">
|
||||
<input type="hidden" class="form-control modal_id_room" name="modal_id_room">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="realloc_avail_rooms" class="control-label model-label">{l s='Available Rooms To Reallocate:'}</label>
|
||||
<div class="realloc_avail_rooms_container" style="width: 195px;">
|
||||
<select class="form-control" name="realloc_avail_rooms" id="realloc_avail_rooms">
|
||||
<option value="0" selected="selected">{l s='Select Rooms'}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="error_text" id="realloc_sel_rm_err_p"></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label style="text-decoration:underline;margin-top:5px;" for="message-text" class="col-sm-12 control-label model-label"><i class="icon-info-circle"></i> {l s='Currently Alloted Customer Information:'}</label>
|
||||
<dl class="well list-detail">
|
||||
<dt>{l s='Name'}</dt>
|
||||
<dd class="cust_name"></dd><br>
|
||||
<dt>{l s='Email'}</dt>
|
||||
<dd class="cust_email"></dd><br>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6">
|
||||
<label for="curr_room_num" class="control-label model-label">{l s='Current Room Number:'}</label>
|
||||
<input type="text" class="form-control modal_curr_room_num" name="modal_curr_room_num" readonly="true">
|
||||
<input type="hidden" class="form-control modal_id_htl_booking" name="id_htl_booking">
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="panel-heading"><i class="icon-user"></i> {l s='Currently Alloted Customer'}</div>
|
||||
<div class="panel-content">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label model-label">{l s='Name'} :</label>
|
||||
<div class="dol-sm-9 cust_name"></div>
|
||||
</div>
|
||||
<div class="">
|
||||
<label class="col-sm-3 control-label model-label">{l s='Email'} :</label>
|
||||
<div class="dol-sm-9 cust_email"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6">
|
||||
<label for="realloc_avail_room_type" class="control-label model-label">{l s='Room Type To Reallocate:'}</label>
|
||||
<div class="realloc_avail_room_type_container">
|
||||
<select class="form-control" name="realloc_avail_room_type" id="realloc_avail_room_type">
|
||||
<option value="0" selected="selected">{l s='Select Room Type'}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="error_text" id="realloc_sel_rm_type_err_p"></p>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label for="realloc_avail_rooms" class="control-label model-label">{l s='Room To Reallocate:'}</label>
|
||||
<div class="realloc_avail_rooms_container">
|
||||
<select class="form-control" name="realloc_avail_rooms" id="realloc_avail_rooms">
|
||||
<option value="0" selected="selected">{l s='Select Rooms'}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="error_text" id="realloc_sel_rm_err_p"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="reallocation_price_diff_block" style="display:none;">
|
||||
<div class="form-group col-sm-6">
|
||||
<label for="reallocation_price_diff" class="control-label model-label alert-warning">{l s='Price Difference'} *</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">{$currency->prefix}{$currency->suffix}</span>
|
||||
<input type="text" name="reallocation_price_diff" id="reallocation_price_diff" value="0" />
|
||||
<span class="input-group-addon">{l s='Tax excl.'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="alert alert-warning col-sm-12 realloc_roomtype_change_message" style="display:none">
|
||||
<p>{l s="If room type is changed while room reallocation then all additional facilities and services will be assigned to the selected room of new room type."}</p>
|
||||
<p>{l s="If you want to change additional facilities or services, you can update by editing the room after reallocation."}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{l s="Close" mod="hotelreservationsyatem"}</button>
|
||||
@@ -1540,29 +1588,35 @@
|
||||
<h4 class="modal-title" id="swap_myModalLabel">{l s='Swap Rooms'}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="swap_curr_room_num" class="control-label model-label">{l s='Current Room Number:'}</label>
|
||||
<input type="text" class="form-control modal_curr_room_num" name="modal_curr_room_num" readonly="true">
|
||||
<input type="hidden" class="form-control modal_date_from" name="modal_date_from">
|
||||
<input type="hidden" class="form-control modal_date_to" name="modal_date_to">
|
||||
<input type="hidden" class="form-control modal_id_room" name="modal_id_room">
|
||||
<input type="hidden" class="form-control modal_id_order" name="modal_id_order">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6">
|
||||
<label for="swap_curr_room_num" class="control-label model-label">{l s='Current Room Number:'}</label>
|
||||
<input type="text" class="form-control modal_curr_room_num" name="modal_curr_room_num" readonly="true">
|
||||
<input type="hidden" class="form-control modal_id_htl_booking" name="id_htl_booking">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="swap_avail_rooms" class="control-label model-label">{l s='Available Rooms To Swap:'}</label>
|
||||
<div class="swap_avail_rooms_container"></div>
|
||||
<p class="error_text" id="swap_sel_rm_err_p"></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label style="text-decoration:underline;margin-top:5px;" for="message-text" class="col-sm-12 control-label model-label"><i class="icon-info-circle"></i> {l s='Currently Alloted Customer Information:'}</label>
|
||||
<dl class="well list-detail">
|
||||
<dt>{l s='Name'}</dt>
|
||||
<dd class="cust_name"></dd><br>
|
||||
<dt>{l s='Email'}</dt>
|
||||
<dd class="cust_email"></dd><br>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="panel-heading"><i class="icon-user"></i> {l s='Currently Alloted Customer'}</div>
|
||||
<div class="panel-content">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label model-label">{l s='Name'} :</label>
|
||||
<div class="dol-sm-9 cust_name"></div>
|
||||
</div>
|
||||
<div class="">
|
||||
<label class="col-sm-3 control-label model-label">{l s='Email'} :</label>
|
||||
<div class="dol-sm-9 cust_email"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6">
|
||||
<label for="swap_avail_rooms" class="control-label model-label">{l s='Rooms To Swap:'}</label>
|
||||
<div class="swap_avail_rooms_container"></div>
|
||||
<p class="error_text" id="swap_sel_rm_err_p"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{l s="Close" mod="hotelreservationsyatem"}</button>
|
||||
<input type="submit" id="swap_allocated_rooms" name="swap_allocated_rooms" class="btn btn-primary" value="Swap">
|
||||
@@ -1571,6 +1625,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* loader before loading data *}
|
||||
<div class="loading_overlay">
|
||||
<img src='{$link->getMediaLink("`$img_dir`admin/ajax-loader.gif")}' class="loading-img"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1604,7 +1663,11 @@
|
||||
|
||||
|
||||
{strip}
|
||||
{addJsDefL name=no_rm_avail_txt}{l s='No rooms available.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=no_rm_avail_txt}{l s='No room available.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=no_realloc_rm_avail_txt}{l s='No room available for reallocation.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=no_realloc_rm_type_avail_txt}{l s='No room type available for reallocation.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=no_swap_rm_avail_txt}{l s='No room available for swap.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=slct_rm_type_err}{l s='Please select a room type first.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=slct_rm_err}{l s='Please select a room first.' js=1}{/addJsDefL}
|
||||
{addJsDefL name=txtExtraDemandSucc}{l s='Updated Successfully' js=1}{/addJsDefL}
|
||||
{addJsDefL name=atleastSelectTxt}{l s='Select at least one facility to update.' js=1}{/addJsDefL}
|
||||
@@ -1625,8 +1688,10 @@
|
||||
{addJsDefL name='years_txt'}{l s='years' js=1}{/addJsDefL}
|
||||
{addJsDefL name='all_children_txt'}{l s='All Children' js=1}{/addJsDefL}
|
||||
{addJsDefL name='invalid_occupancy_txt'}{l s='Invalid occupancy(adults/children) found.' js=1}{/addJsDefL}
|
||||
{addJsDefL name='select_room_txt'}{l s='Select room' js=1}{/addJsDefL}
|
||||
{addJsDef max_child_age=$max_child_age|escape:'quotes':'UTF-8'}
|
||||
{addJsDef max_child_in_room=$max_child_in_room|escape:'quotes':'UTF-8'}
|
||||
{addJsDefL name='undo_cancellation_success'}{l s='Booking cancellation undo process is done successfully.' js=1}{/addJsDefL}
|
||||
{/strip}
|
||||
|
||||
{* Apply javascript for the page *}
|
||||
@@ -1653,12 +1718,10 @@
|
||||
{* open date picker for the date input of check-in checkout dates *}
|
||||
$(document).on('focus', '.room_status_date', function() {
|
||||
var dateFrom = $(this).closest('.room_status_info_form').find('[name="date_from"]').val();
|
||||
dateFrom = dateFrom.split("-");
|
||||
minDate = new Date($.datepicker.formatDate('yy-mm-dd', new Date(dateFrom[0], dateFrom[1] - 1, dateFrom[2])));
|
||||
minDate = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
|
||||
var dateTo = $(this).closest('.room_status_info_form').find('[name="date_to"]').val();
|
||||
dateTo = dateTo.split("-");
|
||||
maxDate = new Date($.datepicker.formatDate('yy-mm-dd', new Date(dateTo[0], dateTo[1] - 1, dateTo[2])));
|
||||
maxDate = $.datepicker.parseDate('yy-mm-dd', dateTo);
|
||||
|
||||
$(this).datepicker({
|
||||
dateFormat: 'dd-mm-yy',
|
||||
@@ -1751,6 +1814,17 @@
|
||||
$('#room_extra_demand_content #back_to_service_btn').hide();
|
||||
});
|
||||
|
||||
$(document).on('change', '#rooms_type_extra_demands .room_ordered_services .qty', function(e) {
|
||||
let quantityInputField = this;
|
||||
let maximumQuantity = parseInt($(quantityInputField).attr('data-max-quantity'));
|
||||
let currentQuantity = parseInt($(quantityInputField).val());
|
||||
if (currentQuantity > maximumQuantity) {
|
||||
$(quantityInputField).siblings('p').show();
|
||||
} else {
|
||||
$(quantityInputField).siblings('p').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('focusout', '#rooms_type_extra_demands .room_ordered_services .qty', function(e) {
|
||||
var qty_wntd = $(this).val();
|
||||
if (qty_wntd == '' || !$.isNumeric(qty_wntd) || qty_wntd < 1) {
|
||||
@@ -1766,41 +1840,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
function updateAdditionalServices(element)
|
||||
{
|
||||
var id_room_type_service_product_order_detail = $(element).data('id_room_type_service_product_order_detail');
|
||||
var qty = $(element).val();
|
||||
if ($.isNumeric(qty)) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
"cache-control": "no-cache"
|
||||
},
|
||||
url: "{$link->getAdminLink('AdminOrders')|addslashes}",
|
||||
dataType: 'JSON',
|
||||
cache: false,
|
||||
data: {
|
||||
id_room_type_service_product_order_detail: id_room_type_service_product_order_detail,
|
||||
qty: qty,
|
||||
action: 'updateRoomAdditionalServices',
|
||||
ajax: true
|
||||
},
|
||||
success: function(jsonData) {
|
||||
if (!jsonData.hasError) {
|
||||
if (jsonData.service_panel) {
|
||||
$('#room_type_service_product_desc').replaceWith(jsonData.service_panel);
|
||||
}
|
||||
showSuccessMessage(txtExtraDemandSucc);
|
||||
} else {
|
||||
showErrorMessage(jsonData.errors);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$(document).on('submit', '#add_room_services_form', function(e) {
|
||||
e.preventDefault();
|
||||
var form_data = new FormData(this);
|
||||
@@ -1964,65 +2003,153 @@
|
||||
|
||||
$('#mySwappigModal').on('hidden.bs.modal', function (e)
|
||||
{
|
||||
$(".modal_id_order").val('');
|
||||
$(".modal_date_from").val('');
|
||||
$(".modal_date_to").val('');
|
||||
$(".modal_id_room").val('');
|
||||
$(".modal_id_htl_booking").val('');
|
||||
$(".modal_curr_room_num").val('');
|
||||
$(".cust_name").text('');
|
||||
$(".cust_email").text('');
|
||||
$(".swp_rm_opts").remove();
|
||||
$(".realloc_rm_type_opts").remove();
|
||||
$(".realloc_rm_opts").remove();
|
||||
});
|
||||
|
||||
$('#mySwappigModal').on('shown.bs.modal', function (e)
|
||||
{
|
||||
$(".modal_id_order").val(e.relatedTarget.dataset.id_order);
|
||||
$(".modal_date_from").val(e.relatedTarget.dataset.date_from);
|
||||
$(".modal_date_to").val(e.relatedTarget.dataset.date_to);
|
||||
$(".modal_id_room").val(e.relatedTarget.dataset.id_room);
|
||||
$(".modal_curr_room_num").val(e.relatedTarget.dataset.room_num);
|
||||
$(".loading_overlay").show();
|
||||
|
||||
$(".modal_id_htl_booking").val(e.relatedTarget.dataset.id_htl_booking);
|
||||
$(".modal_curr_room_num").val(e.relatedTarget.dataset.room_num + ', ' + e.relatedTarget.dataset.room_type_name);
|
||||
$(".cust_name").text(e.relatedTarget.dataset.cust_name);
|
||||
$(".cust_email").text(e.relatedTarget.dataset.cust_email);
|
||||
|
||||
// For Rooms Swapping
|
||||
if (e.relatedTarget.dataset.avail_rm_swap != 'false') {
|
||||
var json_arr_rm_swp = JSON.parse(e.relatedTarget.dataset.avail_rm_swap);
|
||||
// reset price difference fields
|
||||
$("#reallocation_price_diff").val(0);
|
||||
$("#reallocation_price_diff_block").hide();
|
||||
$(".realloc_roomtype_change_message").hide();
|
||||
|
||||
html = '<select class="form-control" name="swap_avail_rooms" id="swap_avail_rooms" style="width:195px;">';
|
||||
// For Rooms Swapping
|
||||
var json_arr_rm_swp = JSON.parse(e.relatedTarget.dataset.avail_rm_swap);
|
||||
if (e.relatedTarget.dataset.avail_rm_swap != 'false' && json_arr_rm_swp.length != 0) {
|
||||
html = '<select class="form-control" name="swap_avail_rooms" id="swap_avail_rooms">';
|
||||
$.each(json_arr_rm_swp, function(key,val) {
|
||||
html += '<option class="swp_rm_opts" value="'+val.id_room+'" >'+val.room_num+'</option>';
|
||||
html += '<option class="swp_rm_opts" value="'+val.id_hotel_booking+'" >'+val.room_num+'</option>';
|
||||
});
|
||||
html += '</select>';
|
||||
|
||||
$("#swap_allocated_rooms").removeAttr('disabled');
|
||||
$(".swap_avail_rooms_container").empty().append(html);
|
||||
} else {
|
||||
$(".swap_avail_rooms_container").empty().text(no_rm_avail_txt);
|
||||
$(".swap_avail_rooms_container").empty().text(no_swap_rm_avail_txt).addClass('text-danger');
|
||||
$("#swap_allocated_rooms").attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
// For Rooms Reallocation
|
||||
if (e.relatedTarget.dataset.avail_rm_realloc != 'false') {
|
||||
var json_arr_rm_realloc = JSON.parse(e.relatedTarget.dataset.avail_rm_realloc);
|
||||
|
||||
html = '<select class="form-control" name="realloc_avail_rooms" id="realloc_avail_rooms" style="width:195px;">';
|
||||
$.each(json_arr_rm_realloc, function(key,val) {
|
||||
html += '<option class="realloc_rm_opts" value="'+val.id_room+'" >'+val.room_num+'</option>';
|
||||
var json_arr_realloc_room_types = JSON.parse(e.relatedTarget.dataset.avail_realloc_room_types);
|
||||
if (e.relatedTarget.dataset.avail_realloc_room_types != 'false' && json_arr_realloc_room_types.length != 0) {
|
||||
var idCurrentRoomType = e.relatedTarget.dataset.id_room_type;
|
||||
var roomsTypesHtml = '<select data-id_htl_booking="' + e.relatedTarget.dataset.id_htl_booking + '" class="form-control" name="realloc_avail_room_type" id="realloc_avail_room_type">';
|
||||
$.each(json_arr_realloc_room_types, function(key, room_type) {
|
||||
roomsTypesHtml += "<option rooms_available='" + JSON.stringify(room_type.rooms) + "' class='realloc_rm_type_opts' value='" + room_type.id_product + "'";
|
||||
if (idCurrentRoomType == room_type.id_product) {
|
||||
roomsTypesHtml += ' selected="selected"';
|
||||
}
|
||||
roomsTypesHtml += '>' + room_type.room_type_name + '</option>';
|
||||
});
|
||||
html += '</select>';
|
||||
$(".realloc_avail_rooms_container").empty().append(html);
|
||||
roomsTypesHtml += '</select>';
|
||||
|
||||
setRoomsForReallocation(json_arr_realloc_room_types[idCurrentRoomType]['rooms']);
|
||||
|
||||
$("#realloc_allocated_rooms").removeAttr('disabled');
|
||||
$(".realloc_avail_room_type_container").empty().append(roomsTypesHtml);
|
||||
} else {
|
||||
$(".realloc_avail_rooms_container").empty().text(no_rm_avail_txt);
|
||||
$(".realloc_avail_rooms_container").empty().text(no_realloc_rm_avail_txt).addClass('text-danger');
|
||||
$(".realloc_avail_room_type_container").empty().text(no_realloc_rm_type_avail_txt).addClass('text-danger');
|
||||
$("#realloc_allocated_rooms").attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
$(".loading_overlay").hide();
|
||||
});
|
||||
|
||||
// change room type for reallocation
|
||||
$(document).on("change", "#realloc_avail_room_type", function(e) {
|
||||
$(".loading_overlay").show();
|
||||
|
||||
var idHotelBooking = $(this).data('id_htl_booking');
|
||||
$("#reallocation_price_diff").val(0);
|
||||
$("#reallocation_price_diff_block").hide();
|
||||
if (parseInt(idHotelBooking) > 0) {
|
||||
var optionSelected = $(this).find('option:selected');
|
||||
var roomsAvailable = JSON.parse(optionSelected.attr('rooms_available'));
|
||||
|
||||
// set the rooms of the selceted room type
|
||||
setRoomsForReallocation(roomsAvailable);
|
||||
|
||||
// send an ajax for fetching if price has changes in the new room type seleceted
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
"cache-control": "no-cache"
|
||||
},
|
||||
url: "{$link->getAdminLink('AdminOrders')|addslashes}",
|
||||
dataType: 'JSON',
|
||||
cache: false,
|
||||
data: {
|
||||
id_htl_booking: idHotelBooking,
|
||||
id_new_room_type: $(this).val(),
|
||||
action: 'changeRoomTypeToReallocate',
|
||||
ajax: true
|
||||
},
|
||||
success: function(result) {
|
||||
if (result.success == 1) {
|
||||
// has room type changed for reallocation
|
||||
if (result.has_room_type_change == 1) {
|
||||
$(".realloc_roomtype_change_message").show();
|
||||
// has room type price changed for reallocation
|
||||
if (result.has_price_changes == 1) {
|
||||
$("#reallocation_price_diff").val(result.price_diff);
|
||||
$("#reallocation_price_diff_block").show();
|
||||
}
|
||||
} else {
|
||||
$(".realloc_roomtype_change_message").hide();
|
||||
}
|
||||
$('#room_type_change_info').empty();
|
||||
if (result.is_changes_present == 1) {
|
||||
}
|
||||
} else if (typeof(result.error) != 'undefinded' && result.error) {
|
||||
showErrorMessage(result.error);
|
||||
} else {
|
||||
showErrorMessage(txtSomeErr);
|
||||
}
|
||||
|
||||
$(".loading_overlay").hide();
|
||||
},
|
||||
error: function(XMLHttpRequest, textStatus, errorThrown) {
|
||||
$(".loading_overlay").hide();
|
||||
showErrorMessage(txtSomeErr);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$(".loading_overlay").hide();
|
||||
showErrorMessage(txtSomeErr);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/*For reallocating rooms in the modal*/
|
||||
$("#realloc_allocated_rooms").on('click', function(e){
|
||||
$(".error_text").text('');
|
||||
var room_to_reallocate = $('#realloc_avail_rooms').val();
|
||||
var room_type_to_reallocate = $('#realloc_avail_room_type').val();
|
||||
|
||||
if (typeof room_type_to_reallocate == 'undefined' || room_type_to_reallocate == 0) {
|
||||
$("#realloc_sel_rm_type_err_p").text(slct_rm_type_err);
|
||||
return false;
|
||||
}
|
||||
if (typeof room_to_reallocate == 'undefined' || room_to_reallocate == 0) {
|
||||
$("#realloc_sel_rm_err_p").text(slct_rm_err);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/*For swaping rooms in the modal*/
|
||||
$("#swap_allocated_rooms").on('click', function(e){
|
||||
$(".error_text").text('');
|
||||
@@ -2033,8 +2160,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
/*END*/
|
||||
|
||||
// for updating customer guest details
|
||||
$('#edit_guest_details').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
@@ -2098,9 +2223,61 @@
|
||||
$('.datepicker').datetimepicker({
|
||||
prevText: '',
|
||||
nextText: '',
|
||||
dateFormat: 'yy-mm-dd ' + hours + ':' + mins + ':' + secs
|
||||
dateFormat: 'yy-mm-dd',
|
||||
timeFormat: 'hh:mm:ss',
|
||||
});
|
||||
});
|
||||
|
||||
function updateAdditionalServices(element)
|
||||
{
|
||||
var id_room_type_service_product_order_detail = $(element).data('id_room_type_service_product_order_detail');
|
||||
var qty = $(element).val();
|
||||
if ($.isNumeric(qty)) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
"cache-control": "no-cache"
|
||||
},
|
||||
url: "{$link->getAdminLink('AdminOrders')|addslashes}",
|
||||
dataType: 'JSON',
|
||||
cache: false,
|
||||
data: {
|
||||
id_room_type_service_product_order_detail: id_room_type_service_product_order_detail,
|
||||
qty: qty,
|
||||
action: 'updateRoomAdditionalServices',
|
||||
ajax: true
|
||||
},
|
||||
success: function(jsonData) {
|
||||
if (!jsonData.hasError) {
|
||||
if (jsonData.service_panel) {
|
||||
$('#room_type_service_product_desc').replaceWith(jsonData.service_panel);
|
||||
}
|
||||
showSuccessMessage(txtExtraDemandSucc);
|
||||
} else {
|
||||
showErrorMessage(jsonData.errors);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function setRoomsForReallocation(roomsAvailable)
|
||||
{
|
||||
if (typeof(roomsAvailable) != 'undefined' && roomsAvailable.length) {
|
||||
var roomsHtml = '<select class="form-control" name="realloc_avail_rooms" id="realloc_avail_rooms">';
|
||||
roomsHtml += '<option class="realloc_rm_opts" value="0">---- ' + select_room_txt + ' ----</option>';
|
||||
$.each(roomsAvailable, function(key, roomInfo) {
|
||||
roomsHtml += '<option class="realloc_rm_opts" value="' + roomInfo.id_room + '">' + roomInfo.room_num + '</option>';
|
||||
});
|
||||
roomsHtml += '</select>';
|
||||
|
||||
$(".realloc_avail_rooms_container").empty().append(roomsHtml);
|
||||
} else {
|
||||
$(".realloc_avail_rooms_container").empty().text(no_realloc_rm_avail_txt);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
{/block}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{if isset($product->id)}
|
||||
<div id="product-configuration" class="panel product-tab">
|
||||
<input type="hidden" name="submitted_tabs[]" value="Configuration" />
|
||||
<h3 class="tab"> <i class="icon-AdminAdmin"></i> {l s='Configuration'}</h3>
|
||||
<h3 class="tab"> <i class="icon-AdminAdmin"></i> {l s='Rooms'}</h3>
|
||||
|
||||
<input type="hidden" id="checkConfSubmit" value="0" name="checkConfSubmit">
|
||||
|
||||
@@ -101,6 +101,8 @@
|
||||
</td>
|
||||
<td class="col-sm-1 center">
|
||||
{if isset($room_info['id'])}
|
||||
<input type="hidden" class="booked-dates" name="{$var_name_room_info|cat:'[booked_dates]'}" value="{$room_info['booked_dates']|escape:'html':'UTF-8'}">
|
||||
<a href="#" class="view_htl_room btn btn-default" data-toggle="modal" data-target="#room-dates-modal" data-id-room="{$room_info['id']}"><i class="icon-info"></i></a>
|
||||
<a href="#" class="rm_htl_room btn btn-default" data-id-htl-info="{$room_info['id']}"><i class="icon-trash"></i></a>
|
||||
<input type="hidden" name="{$var_name_room_info|cat:'[id]'}" value="{$room_info['id']}">
|
||||
{else}
|
||||
@@ -224,6 +226,36 @@
|
||||
</div>
|
||||
{*END*}
|
||||
|
||||
<div class="modal fade" id="room-dates-modal" tabindex="-1" role="dialog" aria-labelledby="">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close margin-right-10" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title"><i class="icon-calendar"></i> {l s='Upcoming bookings'}</h4>
|
||||
</div>
|
||||
<div class="room-booked-dates-table modal-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span>{l s='Order'}</span></th>
|
||||
<th><span>{l s='Date From'}</span></th>
|
||||
<th><span>{l s='Date To'}</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" aria-label="Close">{l s='Done'}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.deactiveDatesModal {
|
||||
cursor: pointer;
|
||||
@@ -400,6 +432,30 @@
|
||||
});
|
||||
});
|
||||
|
||||
{literal}
|
||||
$('#room-dates-modal').on('show.bs.modal', function(e) {
|
||||
const triggerRoom = $(e.relatedTarget);
|
||||
$('#room-dates-modal tbody').html('');
|
||||
var bookedDates = JSON.parse($(triggerRoom).closest('tr').find('.booked-dates').val());
|
||||
if (bookedDates.length) {
|
||||
if (bookedDates.length) {
|
||||
$('#room-dates-modal .room-booked-dates-table').show();
|
||||
$(bookedDates).each(function() {
|
||||
$('#room-dates-modal .room-booked-dates-table tbody').append(`<tr>
|
||||
<td><a href="{/literal}{$link->getAdminLink('AdminOrders')|escape:'html':'UTF-8'}{literal}&vieworder&id_order=${this.id_order}" target="_blank">#${this.id_order}</a></td>
|
||||
<td>${this.date_from_formatted}</td>
|
||||
<td>${this.date_to_formatted}</td>
|
||||
</tr>`);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$('#room-dates-modal .room-booked-dates-table tbody').append(`<tr>
|
||||
<td colspan="3" class="center">{/literal}{l s='No Booking for this room'}{literal}</td>
|
||||
</tr>`);
|
||||
}
|
||||
});
|
||||
{/literal}
|
||||
|
||||
// Add new room detail
|
||||
$('#add-more-rooms-button').on('click',function() {
|
||||
var lengthRooms = parseInt($('.room_data_values').length);
|
||||
@@ -444,18 +500,19 @@
|
||||
$.ajax({
|
||||
url: prod_link,
|
||||
type: 'POST',
|
||||
dataType: 'text',
|
||||
dataType: 'JSON',
|
||||
data: {
|
||||
ajax:true,
|
||||
action:'deleteHotelRoom',
|
||||
id: id_htl_info,
|
||||
},
|
||||
success: function (result) {
|
||||
if (parseInt(result) == 1) {
|
||||
success: function (response) {
|
||||
if (response.success) {
|
||||
showSuccessMessage("{l s='Removed successfully'}");
|
||||
$current.closest(".room_data_values").remove();
|
||||
} else {
|
||||
showErrorMessage("{l s='Some error occurred'}");
|
||||
if (response.errors)
|
||||
showErrorMessage(response.errors);
|
||||
}
|
||||
},
|
||||
error: function(XMLHttpRequest, textStatus, errorThrown) {
|
||||
@@ -499,10 +556,10 @@
|
||||
dateFormat: 'yy-mm-dd',
|
||||
minDate: 0,
|
||||
onSelect: function(selectedDate) {
|
||||
var date_format = selectedDate.split('-');
|
||||
selectedDate = new Date($.datepicker.formatDate('yy-mm-dd', new Date(date_format[0], date_format[1] - 1, date_format[2])));
|
||||
selectedDate.setDate(selectedDate.getDate() + 1);
|
||||
$(this).closest('tr').find('.disabled_date_to').datepicker('option', 'minDate', selectedDate);
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', selectedDate);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
|
||||
$(this).closest('tr').find('.disabled_date_to').datepicker('option', 'minDate', objDateToMin);
|
||||
},
|
||||
onClose: function(selectedDate) {
|
||||
var dateTo = $(this).closest('tr').find('.disabled_date_to').val();
|
||||
@@ -517,16 +574,17 @@
|
||||
dateFormat: 'yy-mm-dd',
|
||||
minDate: 0,
|
||||
beforeShow: function (input, instance) {
|
||||
var date_to = $(this).closest('tr').find('.disabled_date_from').val();
|
||||
if (typeof date_to != 'undefined' && date_to != '') {
|
||||
var date_format = date_to.split('-');
|
||||
var selectedDate = new Date($.datepicker.formatDate('yy-mm-dd', new Date(date_format[0], date_format[1] - 1, date_format[2])));
|
||||
let dateFrom = $(this).closest('tr').find('.disabled_date_from').val();
|
||||
|
||||
let objDateToMin = null;
|
||||
if (typeof dateFrom != 'undefined' && dateFrom != '') {
|
||||
objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
} else {
|
||||
var date_format = new Date();
|
||||
var selectedDate = new Date($.datepicker.formatDate('yy-mm-dd', new Date()));
|
||||
objDateToMin = new Date();
|
||||
}
|
||||
selectedDate.setDate(selectedDate.getDate()+1);
|
||||
$(this).datepicker('option', 'minDate', selectedDate);
|
||||
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
$(this).datepicker('option', 'minDate', objDateToMin);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
{**
|
||||
* 2010-2024 Webkul.
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* All right is reserved,
|
||||
* Please go through LICENSE.txt file inside our module
|
||||
*
|
||||
* 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 CustomizationPolicy.txt file inside our module for more information.
|
||||
*
|
||||
* @author Webkul IN
|
||||
* @copyright 2010-2024 Webkul IN
|
||||
* @license LICENSE.txt
|
||||
*}
|
||||
|
||||
{extends file='helpers/list/list_content.tpl'}
|
||||
|
||||
{block name='td_content'}
|
||||
{if isset($tr.$key) && isset($params.position)}
|
||||
{if $order_by == 'position' && $order_way != 'DESC'}
|
||||
{assign var=filters_has_value_no_location_hotel value=false}
|
||||
|
||||
{foreach $fields_display AS $key => $params}
|
||||
{if $key != 'id_category_default' && (isset($params['value']) && $params['value'] !== false && $params['value'] !== '')}
|
||||
{if is_array($params['value']) && trim(implode('', $params['value'])) == ''}
|
||||
{continue}
|
||||
{/if}
|
||||
|
||||
{assign var=filters_has_value_no_location_hotel value=true}
|
||||
{break}
|
||||
{/if}
|
||||
{/foreach}
|
||||
|
||||
{if !$filters_has_value_no_location_hotel}
|
||||
<div class="dragGroup">
|
||||
<div class="positions">
|
||||
{$tr.$key.position + 1}
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
{$tr.$key.position + 1}
|
||||
{/if}
|
||||
{else}
|
||||
{$tr.$key.position + 1}
|
||||
{/if}
|
||||
{else}
|
||||
{$smarty.block.parent}
|
||||
{/if}
|
||||
{/block}
|
||||
@@ -25,12 +25,393 @@
|
||||
|
||||
{extends file="helpers/list/list_header.tpl"}
|
||||
|
||||
{block name=leadin}
|
||||
{if isset($category_tree)}
|
||||
<div class="bloc-leadin">
|
||||
<div id="container_category_tree">
|
||||
{$category_tree}
|
||||
{block name="tableFilter"}{/block}
|
||||
{block name="override_form_extra"}
|
||||
{if !$simple_header && $show_filters}
|
||||
<script>
|
||||
$(function() {
|
||||
if ($("#list_filters_panel .datepicker").length > 0) {
|
||||
$("#list_filters_panel .datepicker").datepicker({
|
||||
prevText: '',
|
||||
nextText: '',
|
||||
altFormat: 'yy-mm-dd'
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<div class="list_action_wrapper">
|
||||
<div class="row">
|
||||
<div class="col-xs-4 col-sm-3 col-md-2">
|
||||
<div class="list_availibility_container">
|
||||
<button type="button" class="btn btn-default btn-left btn-block dropdown-toggle" data-toggle="dropdown">
|
||||
<span>{l s='Available Fields'}
|
||||
<i class="icon-caret-down pull-right"></i>
|
||||
</button>
|
||||
<ul id="optional-list-toggle" class="dropdown-menu">
|
||||
{foreach $fields_optional as $key => $field}
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="list_fields_visibility" value="{$key}" {if isset($field['selected']) && $field['selected']}checked="checked"{/if}>
|
||||
{$field['title']}
|
||||
</label>
|
||||
</li>
|
||||
{/foreach}
|
||||
{assign var="fields_optional" value=array()}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-3 col-xs-offset-5 col-sm-2 col-sm-offset-7 col-md-1 col-md-offset-9">
|
||||
<div class="list_filter_container">
|
||||
<button type="button" class="btn btn-default btn-block" data-toggle="collapse" data-target="#list_filters_panel">
|
||||
<i class="icon-sliders"></i>
|
||||
<span>{l s='Filters'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{if $filters_has_value}
|
||||
<div id="selected_filter_container">
|
||||
{l s='Filters: '}
|
||||
<span class="selected_filters">
|
||||
{foreach $fields_display AS $key => $params}
|
||||
{if (!isset($params.search) || $params.search) && $params.value != ''}
|
||||
{if ($params.type == 'date' || $params.type == 'datetime') && $params.value|is_array}
|
||||
{assign var="filter_value" value=''}
|
||||
{foreach $params.value as $value}
|
||||
{if ($value|is_string && !empty($value))}
|
||||
{if empty($filter_value)}
|
||||
{assign var="filter_value" value=$value}
|
||||
{else}
|
||||
{assign var="filter_value" value="`$filter_value` - `$value`"}
|
||||
{/if}
|
||||
{/if}
|
||||
{/foreach}
|
||||
{if !empty($filter_value)}
|
||||
<span data-filter_key="{if isset($params.name_date)}{$params.name_date}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$filter_value|escape:'html':'UTF-8'}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{elseif $params.type == 'range' && $params.value|is_array}
|
||||
{assign var="filter_value" value=''}
|
||||
{foreach $params.value as $value}
|
||||
{if (isset($value) && ($value !== '' || $value === 0))}
|
||||
{if !(isset($filter_value) && ($filter_value !== '' || $filter_value === 0))}
|
||||
{assign var="filter_value" value=$value}
|
||||
{else}
|
||||
{assign var="filter_value" value="`$filter_value` - `$value`"}
|
||||
{/if}
|
||||
{/if}
|
||||
{/foreach}
|
||||
{if (isset($filter_value) && ($filter_value !== '' || $filter_value === 0))}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$filter_value|escape:'html':'UTF-8'}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{elseif $params.type == 'select'}
|
||||
{if isset($params.multiple) && $params.multiple}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}" data-multiple="{$params.multiple|intval}" data-operator="{$params.operator}">
|
||||
{$params['title']|escape:'html':'UTF-8'}:
|
||||
<span class="filter_value">
|
||||
{foreach from=$params.value item=option name=foreachInfo}
|
||||
{$params.list[$option]}{if !$smarty.foreach.foreachInfo.last}{if $params.operator == 'or'} | {else}, {/if}{/if}
|
||||
{/foreach}
|
||||
</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{else}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$params['list'][$params['value']]|replace: ' ' : ''}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{elseif $params.type == 'bool' && $key == 'advance_payment'}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{if $params['value'] == 1}{l s='Yes'}{elseif $params['value'] == 0}{l s='No'}{/if}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{else}
|
||||
<span data-filter_key="{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" data-filter_type="{$params.type}">
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$params['value']|escape:'html':'UTF-8'}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
{/foreach}
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="panel collapse" id="list_filters_panel">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="list_filters">
|
||||
{foreach $fields_display AS $key => $params}
|
||||
{if !isset($params.search) || $params.search}
|
||||
<div class="row">
|
||||
<label class="col-xs-3" for="filter_input_{$key}">{$params['title']|escape:'html':'UTF-8'}</label>
|
||||
<div class="col-xs-9">
|
||||
{if $params.type == 'range'}
|
||||
<div class="input_range">
|
||||
<input type="text" class="filter form-control" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}[0]" placeholder="{l s='From'}" value="{if isset($params.value.0)}{$params.value.0}{/if}">
|
||||
<input type="text" class="filter form-control" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}[1]" placeholder="{l s='To'}" value="{if isset($params.value.1)}{$params.value.1}{/if}">
|
||||
</div>
|
||||
{else if $params.type == 'bool'}
|
||||
<select id="filter_input_{$key}" class="filter center" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}">
|
||||
<option value="">-</option>
|
||||
<option value="1" {if $params.value == 1} selected="selected" {/if}>{l s='Yes'}</option>
|
||||
<option value="0" {if $params.value == 0 && $params.value != ''} selected="selected" {/if}>{l s='No'}</option>
|
||||
</select>
|
||||
{elseif $params.type == 'date' || $params.type == 'datetime'}
|
||||
<div class="date_range">
|
||||
<div class="input-group center">
|
||||
<input type="text" class="filter datepicker date-input form-control" id="local_{$params.id_date}_0" name="local_{$params.name_date}[0]" placeholder="{l s='From'}" autocomplete="off"/>
|
||||
<input type="hidden" id="{$params.id_date}_0" name="{$params.name_date}[0]" value="{if isset($params.value.0)}{$params.value.0}{/if}">
|
||||
<span class="input-group-addon">
|
||||
<i class="icon-calendar"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="input-group center">
|
||||
<input type="text" class="filter datepicker date-input form-control" id="local_{$params.id_date}_1" name="local_{$params.name_date}[1]" placeholder="{l s='To'}" autocomplete="off"/>
|
||||
<input type="hidden" id="{$params.id_date}_1" name="{$params.name_date}[1]" value="{if isset($params.value.1)}{$params.value.1}{/if}">
|
||||
<span class="input-group-addon">
|
||||
<i class="icon-calendar"></i>
|
||||
</span>
|
||||
</div>
|
||||
<script>
|
||||
$(function() {
|
||||
var dateStart = parseDate($("#{$params.id_date}_0").val());
|
||||
var dateEnd = parseDate($("#{$params.id_date}_1").val());
|
||||
$("#local_{$params.id_date}_0").datepicker("option", "altField", "#{$params.id_date}_0");
|
||||
$("#local_{$params.id_date}_1").datepicker("option", "altField", "#{$params.id_date}_1");
|
||||
if (dateStart !== null){
|
||||
$("#local_{$params.id_date}_0").datepicker("setDate", dateStart);
|
||||
}
|
||||
if (dateEnd !== null){
|
||||
$("#local_{$params.id_date}_1").datepicker("setDate", dateEnd);
|
||||
}
|
||||
|
||||
$('#local_{$params.id_date}_0').datepicker('option', {
|
||||
prevText: '',
|
||||
nextText: '',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
beforeShow: function() {
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
if (typeof dateTo != 'undefined' && dateTo != '') {
|
||||
let objDateToMax = $.datepicker.parseDate('yy-mm-dd', dateTo);
|
||||
objDateToMax.setDate(objDateToMax.getDate() - 1);
|
||||
$('#local_{$params.id_date}_0').datepicker('option', 'maxDate', objDateToMax);
|
||||
}
|
||||
},
|
||||
onClose: function() {
|
||||
let dateFrom = $('#local_{$params.id_date}_0').val().trim();
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
|
||||
if (dateFrom >= dateTo) {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', {
|
||||
prevText: '',
|
||||
nextText: '',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
beforeShow: function() {
|
||||
let dateFrom = $('#local_{$params.id_date}_0').val().trim();
|
||||
|
||||
if (typeof dateFrom != 'undefined' && dateFrom != '') {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
{elseif $params.type == 'select'}
|
||||
{if isset($params.multiple) && $params.multiple}
|
||||
<select id="filter_input_{$key}" class="filter{if isset($params.align) && $params.align == 'center'}center{/if} select_multiple_{$params.operator} chosen chosen-options-horizontal" multiple name="{$list_id}Filter_{$params.filter_key}[]" {if isset($params.width)} style="width:{$params.width}px"{/if}>
|
||||
{if isset($params.list) && is_array($params.list)}
|
||||
{foreach $params.list AS $option_value => $option_display}
|
||||
<option value="{$option_value}" {if isset($params.value) && $params.value}{if in_array($option_value, $params.value)} selected="selected"{/if}{/if}>{$option_display}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</select>
|
||||
{else}
|
||||
{if isset($params.filter_key)}
|
||||
<select id="filter_input_{$key}" class="filter{if isset($params.align) && $params.align == 'center'}center{/if} {if isset($params.class)}{$params.class}{/if}" {if !isset($params.remove_onchange) || !$params.remove_onchange}onchange="$('#submitFilterButton{$list_id}').focus();$('#submitFilterButton{$list_id}').click();"{/if} name="{$list_id}Filter_{$params.filter_key}" {if isset($params.width)} style="width:{$params.width}px"{/if}>
|
||||
<option value="" {if $params.value == ''} selected="selected" {/if}>-</option>
|
||||
{if isset($params.list) && is_array($params.list)}
|
||||
{foreach $params.list AS $option_value => $option_display}
|
||||
<option value="{$option_value}" {if (string)$option_display === (string)$params.value || (string)$option_value === (string)$params.value} selected="selected"{/if}>{$option_display}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</select>
|
||||
{/if}
|
||||
{/if}
|
||||
{else}
|
||||
<input type="text" class="filter" name="{$list_id}Filter_{if isset($params.filter_key)}{$params.filter_key}{else}{$key}{/if}" value="{$params.value|escape:'html':'UTF-8'}" {if isset($params.width) && $params.width != 'auto'} style="width:{$params.width}px"{/if} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/foreach}
|
||||
{if $has_actions || $show_filters}
|
||||
<div class="actions">
|
||||
<hr>
|
||||
{if $show_filters}
|
||||
<span class="pull-right">
|
||||
<button type="submit" id="submitFilterButton{$list_id}" name="submitFilter" class="btn btn-default" data-list-id="{$list_id}">
|
||||
<i class="icon-search"></i> {l s='Search'}
|
||||
</button>
|
||||
{if $filters_has_value}
|
||||
<button type="submit" name="submitReset{$list_id}" class="btn btn-warning">
|
||||
<i class="icon-eraser"></i> {l s='Reset'}
|
||||
</button>
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#selected_filter_container .selected_filters span i').on('click', function() {
|
||||
let form = $(this).closest('form');
|
||||
let type = $(this).parent().data('filter_type');
|
||||
$(this).parent().remove();
|
||||
if (type == 'date' || type == 'datetime') {
|
||||
$('#list_filters_panel').find('[name*="'+$(this).parent().data('filter_key')+'"]').val('');
|
||||
} else if (type == 'range') {
|
||||
$('#list_filters_panel').find('[name*="productFilter_'+$(this).parent().data('filter_key')+'"]').val('');
|
||||
} else if (type == 'select') {
|
||||
$('#list_filters_panel').find('select[name*="productFilter_'+$(this).parent().data('filter_key')+'"] option:selected').prop('selected', false);
|
||||
} else if (type == 'bool' && $(this).parent().data('filter_key') == 'advance_payment') {
|
||||
$('#list_filters_panel').find('select[name*="productFilter_'+$(this).parent().data('filter_key')+'"] option:selected').prop('selected', false);
|
||||
} else {
|
||||
$('#list_filters_panel').find('input[name*="productFilter_'+$(this).parent().data('filter_key')+'"]').val('');
|
||||
}
|
||||
|
||||
// set post data for empty multi-select filters
|
||||
$(form).find('select[multiple]').each(function (i, selectElement) {
|
||||
if ($(selectElement).find('option:selected').length == 0) {
|
||||
$(form).append('<input type="hidden" name="' + $(selectElement).attr('name').slice(0, -2) + '" value="">');
|
||||
}
|
||||
});
|
||||
|
||||
form.submit();
|
||||
});
|
||||
|
||||
$('#form-product').submit(function () {
|
||||
let form = $(this);
|
||||
$(form).find('select[multiple]').each(function (i, selectElement) {
|
||||
if ($(selectElement).val() == null) {
|
||||
$(form).append('<input type="hidden" name="' + $(selectElement).attr('name').slice(0, -2) + '" value="">');
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.list_action_wrapper {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.list_availibility_container {
|
||||
position: relative;}
|
||||
.list_availibility_container .dropdown-menu {
|
||||
right: 0;
|
||||
padding: 8px 12px;}
|
||||
.list_availibility_container .dropdown-menu label {
|
||||
font-weight: 400;}
|
||||
#selected_filter_container {
|
||||
background-color: #fff;
|
||||
padding: 8px 20px;
|
||||
border: solid 1px #d3d8db;
|
||||
border-radius: 5px 5px 0 0;
|
||||
font-size: 14px;
|
||||
min-height: 52px;
|
||||
margin-top: 15px;}
|
||||
#selected_filter_container .selected_filters > span {
|
||||
font-size: 12px;
|
||||
padding: 6px 10px;
|
||||
display: inline-block;
|
||||
background: #F5F8F9;
|
||||
border: 1px solid #A0D0EB;
|
||||
border-radius: 3px;}
|
||||
#selected_filter_container .selected_filters > span + span {
|
||||
margin-left: 12px;}
|
||||
#selected_filter_container .selected_filters > span .filter_value {
|
||||
font-weight: 700;
|
||||
}
|
||||
#selected_filter_container .selected_filters > span i {
|
||||
cursor: pointer;}
|
||||
|
||||
#content.bootstrap #list_filters_panel{
|
||||
margin-top: 15px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
#content.bootstrap #selected_filter_container + #list_filters_panel {
|
||||
margin-top: 0;
|
||||
}
|
||||
#content.bootstrap #selected_filter_container + div.panel {
|
||||
border-top: transparent;
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
.list_filters {
|
||||
padding: 0 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px 40px;}
|
||||
.list_filters > .row {
|
||||
display: flex;
|
||||
align-items: center;}
|
||||
.list_filters .date_range, .list_filters .input_range {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 15px;}
|
||||
.list_filters .date_range .input-group:first-child {
|
||||
margin-bottom: 0;}
|
||||
.list_filters label {
|
||||
text-align: right;
|
||||
font-weight: 400;}
|
||||
.list_filters .actions {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 4;}
|
||||
@media (max-width: 992px) {
|
||||
.list_filters {
|
||||
grid-template-columns: repeat(2, 1fr);}
|
||||
.list_filters .actions {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 3;}
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.list_filters {
|
||||
grid-template-columns: repeat(1, 1fr);}
|
||||
.list_filters .actions {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;}
|
||||
.list_filters label {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
{/if}
|
||||
{/block}
|
||||
{/block}
|
||||
@@ -24,7 +24,7 @@
|
||||
*}
|
||||
<div class="form-group">
|
||||
<div class="col-lg-12">
|
||||
<input id="{$id|escape:'html':'UTF-8'}" type="file" name="{$name|escape:'html':'UTF-8'}[]"{if isset($url)} data-url="{$url}"{/if}{if isset($multiple) && $multiple} multiple="multiple"{/if} style="width:0px;height:0px;" />
|
||||
<input id="{$id|escape:'html':'UTF-8'}" type="file" accept="image/gif, image/jpg, image/jpeg, image/png" name="{$name|escape:'html':'UTF-8'}[]"{if isset($url)} data-url="{$url}"{/if}{if isset($multiple) && $multiple} multiple="multiple"{/if} style="width:0px;height:0px;" />
|
||||
<button class="btn btn-default" data-style="expand-right" data-size="s" type="button" id="{$id|escape:'html':'UTF-8'}-add-button">
|
||||
<i class="icon-folder-open"></i> {if isset($multiple) && $multiple}{l s='Add files...'}{else}{l s='Add file...'}{/if}
|
||||
</button>
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
{l s='Select Hotel'}
|
||||
</label>
|
||||
<div class="col-sm-5">
|
||||
<select name="id_hotel" id="hotel_place" class="form-control">
|
||||
<select name="id_hotel" id="hotel_place" class="form-control chosen">
|
||||
{foreach from=$htl_info item=htl_dtl}
|
||||
<option value="{$htl_dtl['id']}" >{$htl_dtl['hotel_name']}</option>
|
||||
{/foreach}
|
||||
@@ -273,6 +273,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" id="show_at_front_container">
|
||||
<label class="control-label col-lg-3">
|
||||
<span class="label-tooltip" data-toggle="tooltip" title="{l s='Enable if you want this room type to be shown and to be available for booking from front office.'}">
|
||||
{l s='Show at front office'}
|
||||
</span>
|
||||
</label>
|
||||
<div class="col-lg-3">
|
||||
<span class="switch prestashop-switch fixed-width-lg">
|
||||
<input type="radio" name="show_at_front" id="show_at_front_on" value="1" {if $product->show_at_front || !$product->isAssociatedToShop()}checked="checked"{/if}/>
|
||||
<label for="show_at_front_on" class="radioCheck">
|
||||
{l s='Yes'}
|
||||
</label>
|
||||
<input type="radio" name="show_at_front" id="show_at_front_off" value="0" {if !$product->show_at_front && $product->isAssociatedToShop()}checked="checked"{/if}/>
|
||||
<label for="show_at_front_off" class="radioCheck">
|
||||
{l s='No'}
|
||||
</label>
|
||||
<a class="slide-button btn"></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="product_options" class="form-group hidden">
|
||||
<div class="col-lg-12">
|
||||
<div class="form-group">
|
||||
@@ -422,6 +443,27 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($product->id) && $product->id}
|
||||
<div class="form-group">
|
||||
<label class="control-label col-lg-3" id="category_position" for="category_position">
|
||||
<span class="label-tooltip" data-toggle="tooltip" title="{l s='Set position of the room type when hotel search results are displayed.'}">
|
||||
{l s='Position'}
|
||||
</span>
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input type="text" id="category_position" class="form-control fixed-width-lg" name="category_position" value="{$category_position}" />
|
||||
<p class="help-block">{l s='Please note that position numbering starts from 0. A position of 0 means room type will be displayed at the topmost.'}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($product->id) && $product->id}
|
||||
<div class="alert alert-info">
|
||||
{l s='You can change positions of room types of this hotel from '}
|
||||
<a href="{$link->getAdminLink('AdminProducts')}&id_category={$htl_full_info['id_category']}">{l s='here.'}</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* <div class="form-group">
|
||||
<label class="control-label col-lg-3" for="tags_{$id_lang}">
|
||||
<span class="label-tooltip" data-toggle="tooltip"
|
||||
|
||||
@@ -494,7 +494,7 @@ $(document).ready(function () {
|
||||
<div class="col-lg-9">
|
||||
<div class="row">
|
||||
{if !$multi_shop}
|
||||
<input type="hidden" name="sp_id_shop" value="0" />
|
||||
<input type="hidden" name="sp_id_shop" value="1" />
|
||||
{else}
|
||||
<div class="col-lg-3">
|
||||
<select name="sp_id_shop" id="sp_id_shop">
|
||||
|
||||
@@ -3,77 +3,134 @@
|
||||
<input type="hidden" name="submitted_tabs[]" value="ServiceProduct" />
|
||||
<h3 class="tab"> <i class="icon-AdminAdmin"></i> {l s='Service Products'}</h3>
|
||||
|
||||
{if isset($service_products) && $service_products}
|
||||
{if (isset($associated_service_products) && $associated_service_products) || (isset($unassociated_service_products) && $unassociated_service_products)}
|
||||
<div class="from-group table-responsive-row clearfix">
|
||||
<table class="table tableDnD hotel-roomtype-link-table">
|
||||
<table class="table hotel-roomtype-link-table">
|
||||
<thead>
|
||||
<tr class="nodrag nodrop">
|
||||
<th class="text-center">
|
||||
<input type="checkbox" class="bulk-service-products-status">
|
||||
</th>
|
||||
<th class="col-sm-1">
|
||||
<span>{l s='Id Product'}</span>
|
||||
<span>{l s='ID'}</span>
|
||||
</th>
|
||||
<th class="col-sm-3">
|
||||
<span>{l s='name'}</span>
|
||||
<th class="col-sm-2">
|
||||
<span>{l s='Name'}</span>
|
||||
</th>
|
||||
<th class="">
|
||||
<span>{l s='Auto add to cart'}</span>
|
||||
<th class="text-center">
|
||||
<span>{l s='Auto Add to Cart'}</span>
|
||||
</th>
|
||||
<th>
|
||||
<span>{l s='Position'}</span>
|
||||
</th>
|
||||
<th class="">
|
||||
<th>
|
||||
<span>{l s='Price'}</span>
|
||||
</th>
|
||||
<th class="">
|
||||
<th>
|
||||
<span>{l s='Tax'}</span>
|
||||
</th>
|
||||
<th class="text-right">
|
||||
<span>{l s='Action'}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach from=$service_products key=key item=service_product}
|
||||
<tr id='room_type_service_product_{$service_product.id_room_type_service_product|escape:'html':'UTF-8'}' position='{$service_product.position|escape:'html':'UTF-8'}' id_product='{$service_product.id_product|escape:'html':'UTF-8'}' id_element="{$product->id}" data-roomtype_url="{$link->getAdminLink('AdminProducts', true)|addslashes}">
|
||||
<td class="col-sm-1">{$service_product.id_product|escape:'html':'UTF-8'} <a target="blank" href="{$link->getAdminLink('AdminNormalProducts')|escape:'html':'UTF-8'}&id_product={$service_product.id_product|escape:'html':'UTF-8'}&updateproduct"><i class="icon-external-link-sign"></i></a></td>
|
||||
{foreach from=$associated_service_products item=service_product}
|
||||
<tr id='room_type_service_product_{$service_product.id_product|escape:'html':'UTF-8'}' position="{$service_product.association_info.position|escape:'html':'UTF-8'}" id_product='{$service_product.id_product|escape:'html':'UTF-8'}' id_element="{$product->id}" data-roomtype_url="{$link->getAdminLink('AdminProducts', true)|addslashes}">
|
||||
{assign var=inputs_prefix value="service_product_`$service_product.id_product`_"}
|
||||
<input type="hidden" name="available_service_products[]" value="{$service_product.id_product}">
|
||||
|
||||
<td class="text-center">
|
||||
<input type="checkbox" name="{$inputs_prefix}associated" class="is-associated" checked>
|
||||
</td>
|
||||
<td class="col-sm-1">
|
||||
{$service_product.id_product|escape:'html':'UTF-8'}
|
||||
<a target="blank" href="{$link->getAdminLink('AdminNormalProducts')|escape:'html':'UTF-8'}&id_product={$service_product.id_product|escape:'html':'UTF-8'}&updateproduct">
|
||||
<i class="icon-external-link-sign"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>{$service_product.name}</td>
|
||||
<td><span {if $service_product.auto_add_to_cart}class="badge badge-success"{/if}>{if $service_product.auto_add_to_cart}{l s='Yes'}{else}{l s='No'}{/if}</span></td>
|
||||
<td class="text-center">
|
||||
<span {if $service_product.auto_add_to_cart}class="badge badge-success"{/if}>
|
||||
{if $service_product.auto_add_to_cart}{l s='Yes'}{else}{l s='No'}{/if}
|
||||
</span>
|
||||
</td>
|
||||
<td class="pointer dragHandle center positionImage">
|
||||
<div class="dragGroup">
|
||||
<div class="positions">
|
||||
{$service_product.position + 1}
|
||||
{$service_product.association_info.position + 1}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="field-view service-product-price-text">{if isset($service_product.custom_price) && $service_product.custom_price}{displayPrice price=$service_product.custom_price currency=$currency->id}{else}{displayPrice price=$service_product.default_price currency=$currency->id}{/if}</span>
|
||||
<div class="field-edit" style="display:none">
|
||||
<div class="fixed-width-xl">
|
||||
<div class="input-group">
|
||||
<input type="text" value="{if isset($service_product.custom_price) && $service_product.custom_price}{$service_product.custom_price|escape:'html':'UTF-8'}{else}{$service_product.default_price|escape:'html':'UTF-8'}{/if}" class="service-product-price" data-id_product="{$service_product.id_product|escape:'html':'UTF-8'}">
|
||||
<span class="input-group-addon">{$currency->prefix}{$currency->suffix}</span>
|
||||
{assign var=price_value value=0}
|
||||
{if isset($smarty.post["{$inputs_prefix}price"])}
|
||||
{assign var=price_value value=$smarty.post["{$inputs_prefix}price"]}
|
||||
{else}
|
||||
{if isset($service_product.association_info.custom_price)}
|
||||
{assign var=price_value value=$service_product.association_info.custom_price}
|
||||
{elseif isset($service_product.association_info.default_price)}
|
||||
{assign var=price_value value=$service_product.association_info.default_price}
|
||||
{/if}
|
||||
{/if}
|
||||
<input type="text" name="{$inputs_prefix}price" value="{$price_value}" data-id_product="{$service_product.id_product}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block">{l s='Default price: %s' sprintf={displayPrice price=$service_product.default_price currency=$currency->id}}
|
||||
<div class="help-block">
|
||||
{l s='Default price: %s' sprintf={displayPrice price=$service_product.association_info.default_price currency=$currency->id}}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="field-view service_product_tax_text">{if isset($service_product.tax_rules_group_name) && $service_product.tax_rules_group_name}{$service_product.tax_rules_group_name}{else}{$service_product.default_tax_rules_group_name}{/if}</span>
|
||||
<div class="field-edit" style="display:none">
|
||||
<select class="service_product_id_tax_rules_group">
|
||||
<div class="fixed-width-xl">
|
||||
<select class="service_product_id_tax_rules_group" name="{$inputs_prefix}id_tax_rules_group">
|
||||
<option value="0">{l s='No Tax'}</option>
|
||||
{foreach from=$tax_rules_groups item=tax_rules_group}
|
||||
<option value="{$tax_rules_group.id_tax_rules_group}" {if $service_product.id_tax_rules_group == $tax_rules_group.id_tax_rules_group}selected="selected"{/if} >
|
||||
<option value="{$tax_rules_group.id_tax_rules_group}" {if $service_product.association_info.id_tax_rules_group == $tax_rules_group.id_tax_rules_group}selected="selected"{/if} >
|
||||
{$tax_rules_group['name']|htmlentitiesUTF8}
|
||||
</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="help-block">{l s='Default tax rule: %s' sprintf=$service_product.default_tax_rules_group_name}
|
||||
<div class="help-block">{l s='Default tax rule: %s' sprintf=$service_product.association_info.default_tax_rules_group_name}</div>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a href="#" class="btn btn-default button-edit-price field-view"><i class="icon-pencil"></i></a>
|
||||
<span class="field-edit" style="display:none">
|
||||
<a href="#" class="btn btn-default btn-save" data-roomtype_url="{$link->getAdminLink('AdminProducts', true)|addslashes}" data-id_product="{$service_product.id_product|escape:'html':'UTF-8'}"><i class="icon-save"></i> {l s='save'}</a>
|
||||
<a href="#" class="btn btn-default btn-cancel"><i class="icon-times"></i></a>
|
||||
</span>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
{foreach from=$unassociated_service_products item=service_product}
|
||||
<tr class="nodrop nodrag">
|
||||
{assign var=inputs_prefix value="service_product_`$service_product.id_product`_"}
|
||||
<input type="hidden" name="available_service_products[]" value="{$service_product.id_product}">
|
||||
|
||||
<td class="text-center">
|
||||
<input type="checkbox" name="{$inputs_prefix}associated" class="is-associated" {if isset($smarty.post["{$inputs_prefix}associated"]) && in_array($smarty.post["{$inputs_prefix}associated"], array('on', 'true', '1'))}checked{/if}>
|
||||
</td>
|
||||
<td class="col-sm-1">{$service_product.id_product|escape:'html':'UTF-8'} <a target="blank" href="{$link->getAdminLink('AdminNormalProducts')|escape:'html':'UTF-8'}&id_product={$service_product.id_product|escape:'html':'UTF-8'}&updateproduct"><i class="icon-external-link-sign"></i></a></td>
|
||||
<td>{$service_product.name}</td>
|
||||
<td class="text-center"><span {if $service_product.auto_add_to_cart}class="badge badge-success"{/if}>{if $service_product.auto_add_to_cart}{l s='Yes'}{else}{l s='No'}{/if}</span></td>
|
||||
<td>{l s='--'}</td>
|
||||
<td>
|
||||
<div class="fixed-width-xl">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">{$currency->prefix}{$currency->suffix}</span>
|
||||
<input type="text" name="{$inputs_prefix}price" data-id_product="{$service_product.id_product|escape:'html':'UTF-8'}" value="{if isset($smarty.post["{$inputs_prefix}price"]) && $smarty.post["{$inputs_prefix}price"]}{$smarty.post["{$inputs_prefix}price"]}{else}{$service_product.price}{/if}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="help-block">
|
||||
{l s='Default price: %s' sprintf={displayPrice price=$service_product.price currency=$currency->id}}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="fixed-width-xl">
|
||||
<select class="service_product_id_tax_rules_group" name="{$inputs_prefix}id_tax_rules_group">
|
||||
<option value="0">{l s='No Tax'}</option>
|
||||
{foreach from=$tax_rules_groups item=tax_rules_group}
|
||||
<option value="{$tax_rules_group.id_tax_rules_group}" {if isset($smarty.post["{$inputs_prefix}id_tax_rules_group"])}{if $tax_rules_group.id_tax_rules_group == $smarty.post["{$inputs_prefix}id_tax_rules_group"]}{/if}{elseif $tax_rules_group.id_tax_rules_group == $service_product.id_tax_rules_group}selected{/if}>
|
||||
{$tax_rules_group['name']|htmlentitiesUTF8}
|
||||
</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="help-block">{l s='Default tax rule: %s' sprintf=$service_product.tax_rules_group_name}</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
@@ -108,43 +108,160 @@ $(function() {
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_hotels) && $num_hotels}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_hotels == 1}
|
||||
{l s='1 Hotel'}
|
||||
{else}
|
||||
{l s='%d Hotels' sprintf=$num_hotels}
|
||||
{/if}
|
||||
</h3>
|
||||
{$hotels}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_hotel_features) && $num_hotel_features}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_hotel_features == 1}
|
||||
{l s='1 hotel feature'}
|
||||
{else}
|
||||
{l s='%d hotel features' sprintf=$num_hotel_features}
|
||||
{/if}
|
||||
</h3>
|
||||
{$hotel_features}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_products) && $num_products}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_products == 1}
|
||||
{l s='1 product'}
|
||||
{else}
|
||||
{l s='%d products' sprintf=$num_products}
|
||||
{/if}
|
||||
</h3>
|
||||
{$products}
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_products == 1}
|
||||
{l s='1 room type'}
|
||||
{else}
|
||||
{l s='%d room types' sprintf=$num_products}
|
||||
{/if}
|
||||
</h3>
|
||||
{$products}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_catalog_features) && $num_catalog_features}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_catalog_features == 1}
|
||||
{l s='1 feature'}
|
||||
{else}
|
||||
{l s='%d features' sprintf=$num_catalog_features}
|
||||
{/if}
|
||||
</h3>
|
||||
{$catalog_features}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_service_products) && $num_service_products}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_service_products == 1}
|
||||
{l s='1 service product'}
|
||||
{else}
|
||||
{l s='%d service products' sprintf=$num_service_products}
|
||||
{/if}
|
||||
</h3>
|
||||
{$service_products}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_global_demands) && $num_global_demands}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_global_demands == 1}
|
||||
{l s='1 global demand'}
|
||||
{else}
|
||||
{l s='%d global demands' sprintf=$num_global_demands}
|
||||
{/if}
|
||||
</h3>
|
||||
{$global_demands}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_refund_rules) && $num_refund_rules}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_refund_rules == 1}
|
||||
{l s='1 refund rule'}
|
||||
{else}
|
||||
{l s='%d refund rules' sprintf=$num_refund_rules}
|
||||
{/if}
|
||||
</h3>
|
||||
{$refund_rules}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_customers) && $num_customers}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_customers == 1}
|
||||
{l s='1 customer'}
|
||||
{else}
|
||||
{l s='%d customers' sprintf=$num_customers}
|
||||
{/if}
|
||||
</h3>
|
||||
{$customers}
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_customers == 1}
|
||||
{l s='1 customer'}
|
||||
{else}
|
||||
{l s='%d customers' sprintf=$num_customers}
|
||||
{/if}
|
||||
</h3>
|
||||
{$customers}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_groups) && $num_groups}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_groups == 1}
|
||||
{l s='1 group'}
|
||||
{else}
|
||||
{l s='%d groups' sprintf=$num_groups}
|
||||
{/if}
|
||||
</h3>
|
||||
{$groups}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_customer_address) && $num_customer_address}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_customer_address == 1}
|
||||
{l s='1 customer address'}
|
||||
{else}
|
||||
{l s='%d customer addresses' sprintf=$num_customer_address}
|
||||
{/if}
|
||||
</h3>
|
||||
{$customer_address}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_order_messages) && $num_order_messages}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_order_messages == 1}
|
||||
{l s='1 customer service message'}
|
||||
{else}
|
||||
{l s='%d customer service messages' sprintf=$num_order_messages}
|
||||
{/if}
|
||||
</h3>
|
||||
{$order_messages}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($num_orders) && $num_orders}
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_orders == 1}
|
||||
{l s='1 order'}
|
||||
{else}
|
||||
{l s='%d orders' sprintf=$num_orders}
|
||||
{/if}
|
||||
</h3>
|
||||
{$orders}
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h3>
|
||||
{if $num_orders == 1}
|
||||
{l s='1 order'}
|
||||
{else}
|
||||
{l s='%d orders' sprintf=$num_orders}
|
||||
{/if}
|
||||
</h3>
|
||||
{$orders}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if isset($addons) && $addons}
|
||||
|
||||
@@ -31,13 +31,17 @@
|
||||
<tr>
|
||||
<th class="fixed-width-xs">
|
||||
<span class="title_box">
|
||||
<input type="checkbox" name="checkme" id="checkme" onclick="checkDelBoxes(this.form, 'groupBox[]', this.checked)" />
|
||||
<input type="checkbox" name="checkme" id="checkme" onclick="checkDelBoxes(this.form, '{$input['name']}[]', this.checked)" />
|
||||
</span>
|
||||
</th>
|
||||
<th class="fixed-width-xs">
|
||||
<span class="title_box">
|
||||
{if isset($input['groups_id_title']) && $input['groups_id_title']}{$input['groups_id_title']}{else}{l s='ID'}{/if}
|
||||
</span>
|
||||
</th>
|
||||
<th class="fixed-width-xs"><span class="title_box">{l s='ID'}</span></th>
|
||||
<th>
|
||||
<span class="title_box">
|
||||
{l s='Group name'}
|
||||
{if isset($input['groups_title']) && $input['groups_title']}{$input['groups_title']}{else}{l s='Group name'}{/if}
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
@@ -46,8 +50,8 @@
|
||||
{foreach $groups as $key => $group}
|
||||
<tr>
|
||||
<td>
|
||||
{assign var=id_checkbox value=groupBox|cat:'_'|cat:$group['id_group']}
|
||||
<input type="checkbox" name="groupBox[]" class="groupBox" id="{$id_checkbox}" value="{$group['id_group']}" {if $fields_value[$id_checkbox]}checked="checked"{/if} />
|
||||
{assign var=id_checkbox value=$input['name']|cat:'_'|cat:$group['id_group']}
|
||||
<input type="checkbox" name="{$input['name']}[]" class="groupBox" id="{$id_checkbox}" value="{$group['id_group']}" {if $fields_value[$id_checkbox]}checked="checked"{/if} />
|
||||
</td>
|
||||
<td>{$group['id_group']}</td>
|
||||
<td>
|
||||
|
||||
@@ -422,21 +422,13 @@
|
||||
prevText: '',
|
||||
nextText: '',
|
||||
dateFormat: 'yy-mm-dd',
|
||||
beforeShow: function() {
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
if (typeof dateTo != 'undefined' && dateTo != '') {
|
||||
let objDateToMax = $.datepicker.parseDate('yy-mm-dd', dateTo);
|
||||
objDateToMax.setDate(objDateToMax.getDate() - 1);
|
||||
$('#local_{$params.id_date}_0').datepicker('option', 'maxDate', objDateToMax);
|
||||
}
|
||||
},
|
||||
onClose: function() {
|
||||
let dateFrom = $('#local_{$params.id_date}_0').val().trim();
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
|
||||
if (dateFrom >= dateTo) {
|
||||
if ((dateFrom && dateTo) && (dateFrom >= dateTo)) {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
objDateToMin.setDate(objDateToMin.getDate());
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
@@ -452,7 +444,7 @@
|
||||
|
||||
if (typeof dateFrom != 'undefined' && dateFrom != '') {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate() + 1);
|
||||
objDateToMin.setDate(objDateToMin.getDate());
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<li>
|
||||
<a id="page-header-desc-{$table}-{if isset($btn.imgclass)}{$btn.imgclass|escape}{else}{$k}{/if}" class="toolbar_btn {if isset($btn.target) && $btn.target} _blank{/if} pointer"{if isset($btn.href)} href="{$btn.href|escape}"{/if} title="{if isset($btn.help)}{$btn.help}{else}{$btn.desc|escape}{/if}"{if isset($btn.js) && $btn.js} onclick="{$btn.js}"{/if}{if isset($btn.modal_target) && $btn.modal_target} data-target="{$btn.modal_target}" data-toggle="modal"{/if}{if isset($btn.help)} data-toggle="tooltip" data-placement="bottom"{/if}>
|
||||
<i class="{if isset($btn.icon)}{$btn.icon|escape}{else}process-icon-{if isset($btn.imgclass)}{$btn.imgclass|escape}{else}{$k}{/if}{/if}{if isset($btn.class)} {$btn.class|escape}{/if}"></i>
|
||||
<div{if isset($btn.force_desc) && $btn.force_desc == true } class="locked"{/if}>{$btn.desc|escape}</div>
|
||||
<span{if isset($btn.force_desc) && $btn.force_desc == true } class="locked"{/if}>{$btn.desc|escape}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
@@ -92,7 +92,7 @@
|
||||
<li>
|
||||
<a id="page-header-desc-{$table}-{if isset($toolbar_btn['modules-list'].imgclass)}{$toolbar_btn['modules-list'].imgclass}{else}modules-list{/if}" class="toolbar_btn{if isset($toolbar_btn['modules-list'].class)} {$toolbar_btn['modules-list'].class}{/if}{if isset($toolbar_btn['modules-list'].target) && $toolbar_btn['modules-list'].target} _blank{/if}" {if isset($toolbar_btn['modules-list'].href)}href="{$toolbar_btn['modules-list'].href}"{/if} title="{$toolbar_btn['modules-list'].desc}"{if isset($toolbar_btn['modules-list'].js) && $toolbar_btn['modules-list'].js} onclick="{$toolbar_btn['modules-list'].js}"{/if}>
|
||||
<i class="{if isset($toolbar_btn['modules-list'].icon)}{$toolbar_btn['modules-list'].icon}{else}process-icon-{if isset($toolbar_btn['modules-list'].imgclass)}{$toolbar_btn['modules-list'].imgclass}{else}modules-list{/if}{/if}"></i>
|
||||
<div{if isset($toolbar_btn['modules-list'].force_desc) && $toolbar_btn['modules-list'].force_desc == true } class="locked"{/if}>{$toolbar_btn['modules-list'].desc}</div>
|
||||
<span{if isset($toolbar_btn['modules-list'].force_desc) && $toolbar_btn['modules-list'].force_desc == true } class="locked"{/if}>{$toolbar_btn['modules-list'].desc}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
@@ -115,9 +115,15 @@
|
||||
|
||||
});
|
||||
{/if}
|
||||
$('.process-icon-modules-list').parent('a').unbind().bind('click', function (){
|
||||
$('#modules_list_container').modal('show');
|
||||
openModulesList();
|
||||
$('.process-icon-modules-list').parent('a').unbind().bind('click', async function (){
|
||||
let loggedIn = await checkIfEmployeeIsLoggedIn();
|
||||
|
||||
if (loggedIn) {
|
||||
$('#modules_list_container').modal('show');
|
||||
openModulesList();
|
||||
} else {
|
||||
window.location = window.location.pathname;
|
||||
}
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@@ -39,36 +39,41 @@
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li class="search-book search-option">
|
||||
<a href="#" data-value="1" data-placeholder="{l s='Product name, SKU, reference...'}" data-icon="icon-book">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_CATELOG}" data-placeholder="{l s='Room Types, Service products...'}" data-icon="icon-book">
|
||||
<i class="icon-book"></i> {l s='Catalog'}
|
||||
</a>
|
||||
</li>
|
||||
<li class="search-modules search-option">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_HOTEL}" data-placeholder="{l s='Hotel'}" data-icon="icon-AdminHotelReservationSystemManagement">
|
||||
<i class="icon-building"></i> {l s='Hotel'}
|
||||
</a>
|
||||
</li>
|
||||
<li class="search-customers-name search-option">
|
||||
<a href="#" data-value="2" data-placeholder="{l s='Email, name...'}" data-icon="icon-group">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_CUSTOMER_BY_NAME}" data-placeholder="{l s='Email, name...'}" data-icon="icon-group">
|
||||
<i class="icon-group"></i> {l s='Customers'} {l s='by name'}
|
||||
</a>
|
||||
</li>
|
||||
<li class="search-customers-addresses search-option">
|
||||
<a href="#" data-value="6" data-placeholder="{l s='123.45.67.89'}" data-icon="icon-desktop">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_CUSTOMER_BY_IP}" data-placeholder="{l s='123.45.67.89'}" data-icon="icon-desktop">
|
||||
<i class="icon-desktop"></i> {l s='Customers'} {l s='by ip address'}</a>
|
||||
</li>
|
||||
<li class="search-orders search-option">
|
||||
<a href="#" data-value="3" data-placeholder="{l s='Order ID'}" data-icon="icon-credit-card">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_ORDER}" data-placeholder="{l s='Order ID'}" data-icon="icon-credit-card">
|
||||
<i class="icon-credit-card"></i> {l s='Orders'}
|
||||
</a>
|
||||
</li>
|
||||
<li class="search-invoices search-option">
|
||||
<a href="#" data-value="4" data-placeholder="{l s='Invoice Number'}" data-icon="icon-book">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_INVOICE}" data-placeholder="{l s='Invoice Number'}" data-icon="icon-book">
|
||||
<i class="icon-book"></i> {l s='Invoices'}
|
||||
</a>
|
||||
</li>
|
||||
<li class="search-carts search-option">
|
||||
<a href="#" data-value="5" data-placeholder="{l s='Cart ID'}" data-icon="icon-shopping-cart">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_CART}" data-placeholder="{l s='Cart ID'}" data-icon="icon-shopping-cart">
|
||||
<i class="icon-shopping-cart"></i> {l s='Carts'}
|
||||
</a>
|
||||
</li>
|
||||
<li class="search-modules search-option">
|
||||
<a href="#" data-value="7" data-placeholder="{l s='Module name'}" data-icon="icon-puzzle-piece">
|
||||
<a href="#" data-value="{$QLO_SEARCH_TYPE_MODULE}" data-placeholder="{l s='Module name'}" data-icon="icon-puzzle-piece">
|
||||
<i class="icon-puzzle-piece"></i> {l s='Modules'}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -125,8 +125,8 @@ class AddressCore extends ObjectModel
|
||||
'id_state' => array('type' => self::TYPE_INT, 'validate' => 'isNullOrUnsignedId'),
|
||||
'alias' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32),
|
||||
'company' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 255),
|
||||
'lastname' => array('type' => self::TYPE_STRING, 'validate' => 'isName', 'required' => true, 'size' => 32),
|
||||
'firstname' => array('type' => self::TYPE_STRING, 'validate' => 'isName', 'required' => true, 'size' => 32),
|
||||
'lastname' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32),
|
||||
'firstname' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32),
|
||||
'vat_number' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'),
|
||||
'address1' => array('type' => self::TYPE_STRING, 'validate' => 'isAddress', 'required' => true, 'size' => 128),
|
||||
'address2' => array('type' => self::TYPE_STRING, 'validate' => 'isAddress', 'size' => 128),
|
||||
@@ -180,7 +180,7 @@ class AddressCore extends ObjectModel
|
||||
{
|
||||
// for customer address we need to check of customer address already exists.
|
||||
if ($this->id_customer) {
|
||||
if ($id_address = Customer::getCustomerIdAddress($this->id_customer)) {
|
||||
if ($id_address = Customer::getCustomerIdAddress($this->id_customer, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -482,4 +482,32 @@ class AddressCore extends ObjectModel
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function searchByName($query, $idLang = false)
|
||||
{
|
||||
if (!$idLang) {
|
||||
$idLang = Context::getContext()->language->id;
|
||||
}
|
||||
|
||||
return Db::getInstance()->executeS(
|
||||
'SELECT a.`id_address`, a.`firstname`, a.`lastname`, a.`address1`, a.`postcode`, a.`city`,
|
||||
cl.`name` AS `country_name`, s.`name` AS `state_name`
|
||||
FROM `'._DB_PREFIX_.'address` a
|
||||
LEFT JOIN `'._DB_PREFIX_.'country_lang` cl
|
||||
ON cl.`id_country` = a.`id_country`
|
||||
LEFT JOIN `'._DB_PREFIX_.'state` s
|
||||
ON s.`id_country` = cl.`id_country`
|
||||
WHERE id_customer > 0 AND
|
||||
(a.`address1` LIKE \'%'.$query.'%\' OR
|
||||
a.`postcode` LIKE \'%'.$query.'%\' OR
|
||||
a.`city` LIKE \'%'.$query.'%\' OR
|
||||
a.`phone` LIKE \'%'.$query.'%\' OR
|
||||
a.`company` LIKE \'%'.$query.'%\' OR
|
||||
a.`alias` LIKE \'%'.$query.'%\' OR
|
||||
s.`name` LIKE \'%'.$query.'%\' OR
|
||||
cl.`name` LIKE \'%'.$query.'%\'
|
||||
)
|
||||
');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1300,7 +1300,8 @@ class CarrierCore extends ObjectModel
|
||||
}
|
||||
|
||||
$id_address = (int)((!is_null($id_address_delivery) && $id_address_delivery != 0) ? $id_address_delivery : $cart->id_address_delivery);
|
||||
if ($id_address) {
|
||||
$obj_address = new Address($id_address);
|
||||
if (Validate::isLoadedObject($obj_address)) {
|
||||
$id_zone = Address::getZoneById($id_address);
|
||||
|
||||
// Check the country of the address is activated
|
||||
|
||||
@@ -532,7 +532,7 @@ class CartCore extends ObjectModel
|
||||
$sql = new DbQuery();
|
||||
|
||||
// Build SELECT
|
||||
$sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`, p.`booking_product`, p.`service_product_type`, p.`auto_add_to_cart`, p.`price_addition_type`, product_shop.`allow_multiple_quantity`, product_shop.`price_calculation_method`,
|
||||
$sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`, p.`booking_product`, p.`service_product_type`, p.`auto_add_to_cart`, p.`price_addition_type`, p.`show_at_front`, product_shop.`allow_multiple_quantity`, product_shop.`price_calculation_method`,
|
||||
pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`,
|
||||
p.`id_manufacturer`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`,
|
||||
product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`,
|
||||
@@ -781,8 +781,8 @@ class CartCore extends ObjectModel
|
||||
|
||||
case Order::ROUND_ITEM:
|
||||
default:
|
||||
$row['total'] = Tools::ps_round($totalPriceByProductTaxExcl, _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
|
||||
$row['total_wt'] = Tools::ps_round($totalPriceByProductTaxIncl, _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
|
||||
$row['total'] = Tools::ps_round($totalPriceByProductTaxExcl, _PS_PRICE_COMPUTE_PRECISION_);
|
||||
$row['total_wt'] = Tools::ps_round($totalPriceByProductTaxIncl, _PS_PRICE_COMPUTE_PRECISION_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -804,8 +804,8 @@ class CartCore extends ObjectModel
|
||||
|
||||
case Order::ROUND_ITEM:
|
||||
default:
|
||||
$row['total'] = Tools::ps_round($totalPriceByProductTaxExcl, _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
|
||||
$row['total_wt'] = Tools::ps_round($totalPriceByProductTaxIncl, _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
|
||||
$row['total'] = Tools::ps_round($totalPriceByProductTaxExcl, _PS_PRICE_COMPUTE_PRECISION_);
|
||||
$row['total_wt'] = Tools::ps_round($totalPriceByProductTaxIncl, _PS_PRICE_COMPUTE_PRECISION_);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -2387,7 +2387,6 @@ class CartCore extends ObjectModel
|
||||
$array[$selectedProduct['id_hotel']] = array(
|
||||
'quantity' => $selectedProduct['quantity'],
|
||||
'id_hotel' => $selectedProduct['id_hotel'],
|
||||
'unit_price_tax_incl' => $selectedProduct['unit_price_tax_incl'],
|
||||
'total_price_tax_excl' => $selectedProduct['total_price_tax_excl'],
|
||||
'total_price_tax_incl' => $selectedProduct['total_price_tax_incl'],
|
||||
);
|
||||
@@ -2397,7 +2396,8 @@ class CartCore extends ObjectModel
|
||||
$product['cart_quantity'] = $selectedProduct['quantity'];
|
||||
$product['total'] = $selectedProduct['total_price_tax_excl'];
|
||||
$product['total_wt'] = $selectedProduct['total_price_tax_incl'];
|
||||
$product['price_wt'] = $selectedProduct['unit_price_tax_incl'];
|
||||
$product['price_wt'] = $selectedProduct['total_price_tax_incl'] / $product['cart_quantity'];
|
||||
$product['price'] = $selectedProduct['total_price_tax_excl'] / $product['cart_quantity'];
|
||||
$product['id_hotel'] = $selectedProduct['id_hotel'];
|
||||
$orderPackage[$id_address][$selectedProduct['id_hotel']]['product_list'][] = $product;
|
||||
if (!isset($orderPackage[$id_address][$selectedProduct['id_hotel']]['id_hotel'])) {
|
||||
@@ -2431,6 +2431,7 @@ class CartCore extends ObjectModel
|
||||
$unitPriceWt = $objHotelServiceProductCartDetail->getHotelProductUnitPrice($this->id, $product['id_product'], $hotelProduct['id_hotel'], true);
|
||||
$serviceProduct['total'] = $unitPrice * $hotelProduct['quantity'];
|
||||
$serviceProduct['total_wt'] = $unitPriceWt * $hotelProduct['quantity'];
|
||||
$serviceProduct['price'] = $unitPrice;
|
||||
$serviceProduct['price_wt'] = $unitPriceWt;
|
||||
// if (!empty($hotelProducts['products'])) {
|
||||
// foreach($hotelProducts['products'] as $hotelProduct) {
|
||||
|
||||
@@ -421,7 +421,7 @@ class CartRuleCore extends ObjectModel
|
||||
* @param $name
|
||||
* @return bool
|
||||
*/
|
||||
public static function cartRuleExists($name)
|
||||
public static function cartRuleExists($code, $id_customer = 0)
|
||||
{
|
||||
if (!CartRule::isFeatureActive()) {
|
||||
return false;
|
||||
@@ -430,7 +430,8 @@ class CartRuleCore extends ObjectModel
|
||||
return (bool)Db::getInstance()->getValue('
|
||||
SELECT `id_cart_rule`
|
||||
FROM `'._DB_PREFIX_.'cart_rule`
|
||||
WHERE `code` = \''.pSQL($name).'\'');
|
||||
WHERE `code` = \''.pSQL($code).'\''.
|
||||
($id_customer ? 'AND `id_customer` = '.(int) $id_customer : ''));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -601,7 +602,7 @@ class CartRuleCore extends ObjectModel
|
||||
|
||||
// Check if the cart rule is only usable by a specific customer, and if the current customer is the right one
|
||||
if ($this->id_customer && $context->cart->id_customer != $this->id_customer) {
|
||||
if (!Context::getContext()->customer->isLogged()) {
|
||||
if (!defined('_PS_ADMIN_DIR_') && !Context::getContext()->customer->isLogged()) {
|
||||
return (!$display_error) ? false : (Tools::displayError('You cannot use this voucher').' - '.Tools::displayError('Please log in first'));
|
||||
}
|
||||
return (!$display_error) ? false : Tools::displayError('You cannot use this voucher');
|
||||
@@ -1466,15 +1467,16 @@ class CartRuleCore extends ObjectModel
|
||||
* @param $id_lang
|
||||
* @return array
|
||||
*/
|
||||
public static function getCartsRuleByCode($name, $id_lang, $extended = false)
|
||||
public static function getCartsRuleByCode($name, $id_lang, $extended = false, $id_customer = 0)
|
||||
{
|
||||
$sql_base = 'SELECT cr.*, crl.*
|
||||
FROM '._DB_PREFIX_.'cart_rule cr
|
||||
LEFT JOIN '._DB_PREFIX_.'cart_rule_lang crl ON (cr.id_cart_rule = crl.id_cart_rule AND crl.id_lang = '.(int)$id_lang.')';
|
||||
FROM '._DB_PREFIX_.'cart_rule cr
|
||||
LEFT JOIN '._DB_PREFIX_.'cart_rule_lang crl ON (cr.id_cart_rule = crl.id_cart_rule AND crl.id_lang = '.(int)$id_lang.')
|
||||
WHERE 1'.($id_customer ? ' AND (cr.`id_customer` = 0 OR cr.`id_customer` = '.(int) $id_customer.')' : '');
|
||||
if ($extended) {
|
||||
return Db::getInstance()->executeS('('.$sql_base.' WHERE code LIKE \'%'.pSQL($name).'%\') UNION ('.$sql_base.' WHERE name LIKE \'%'.pSQL($name).'%\')');
|
||||
return Db::getInstance()->executeS('('.$sql_base.' AND code LIKE \'%'.pSQL($name).'%\') UNION ('.$sql_base.' AND name LIKE \'%'.pSQL($name).'%\')');
|
||||
} else {
|
||||
return Db::getInstance()->executeS($sql_base.' WHERE code LIKE \'%'.pSQL($name).'%\'');
|
||||
return Db::getInstance()->executeS($sql_base.' AND code LIKE \'%'.pSQL($name).'%\'');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,6 @@ class ConfigurationTestCore
|
||||
'register_globals' => false,
|
||||
'gz' => false,
|
||||
'mbstring' => false,
|
||||
'magicquotes' => false,
|
||||
'dom' => false,
|
||||
);
|
||||
}
|
||||
@@ -181,11 +180,6 @@ class ConfigurationTestCore
|
||||
return extension_loaded('simplexml');
|
||||
}
|
||||
|
||||
public static function test_magicquotes()
|
||||
{
|
||||
return function_exists('get_magic_quotes_gpc') ? !get_magic_quotes_gpc() : true;
|
||||
}
|
||||
|
||||
public static function test_upload()
|
||||
{
|
||||
return ini_get('file_uploads');
|
||||
|
||||
@@ -93,7 +93,7 @@ class CookieCore
|
||||
$this->_path = str_replace('%7E', '~', $this->_path);
|
||||
$this->_domain = $this->getDomain($shared_urls);
|
||||
$this->_sameSite = Configuration::get('PS_COOKIE_SAMESITE');
|
||||
$this->_name = 'PrestaShop-'.md5(($this->_standalone ? '' : _PS_VERSION_).$name.$this->_domain);
|
||||
$this->_name = 'QloApps-'.md5(($this->_standalone ? '' : _PS_VERSION_).$name.$this->_domain);
|
||||
$this->_allow_writing = true;
|
||||
$this->_salt = $this->_standalone ? str_pad('', 8, md5('ps'.__FILE__)) : _COOKIE_IV_;
|
||||
if ($this->_standalone) {
|
||||
|
||||
@@ -465,10 +465,10 @@ class CustomerCore extends ObjectModel
|
||||
return Cache::retrieve($cache_id);
|
||||
}
|
||||
|
||||
public static function getCustomerIdAddress($id_customer)
|
||||
public static function getCustomerIdAddress($id_customer, $use_cache = true)
|
||||
{
|
||||
$cache_id = 'Customer::getCustomerIdAddress'.(int)$id_customer;
|
||||
if (!Cache::isStored($cache_id)) {
|
||||
if (!$use_cache || !Cache::isStored($cache_id)) {
|
||||
$sql = 'SELECT id_address
|
||||
FROM `'._DB_PREFIX_.'address` a
|
||||
WHERE `id_customer` = '.(int)$id_customer.' AND a.`deleted` = 0';
|
||||
@@ -528,14 +528,16 @@ class CustomerCore extends ObjectModel
|
||||
* @return array|false|mysqli_result|null|PDOStatement|resource Corresponding customers
|
||||
* @throws PrestaShopDatabaseException
|
||||
*/
|
||||
public static function searchByName($query, $limit = null)
|
||||
public static function searchByName($query, $limit = null, $skip_deleted = false)
|
||||
{
|
||||
$sql_base = 'SELECT *
|
||||
FROM `'._DB_PREFIX_.'customer`';
|
||||
$sql = '('.$sql_base.' WHERE `email` LIKE \'%'.pSQL($query).'%\' '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
$sql .= ' UNION ('.$sql_base.' WHERE `id_customer` = '.(int)$query.' '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
$sql .= ' UNION ('.$sql_base.' WHERE `lastname` LIKE \'%'.pSQL($query).'%\' '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
$sql .= ' UNION ('.$sql_base.' WHERE `firstname` LIKE \'%'.pSQL($query).'%\' '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
FROM `'._DB_PREFIX_.'customer`';
|
||||
$where_deleted = $skip_deleted ? ' AND `deleted` = 0' : '';
|
||||
|
||||
$sql = '('.$sql_base.' WHERE `email` LIKE \'%'.pSQL($query).'%\' '.$where_deleted.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
$sql .= ' UNION ('.$sql_base.' WHERE `id_customer` = '.(int)$query.' '.$where_deleted.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
$sql .= ' UNION ('.$sql_base.' WHERE `lastname` LIKE \'%'.pSQL($query).'%\' '.$where_deleted.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
$sql .= ' UNION ('.$sql_base.' WHERE `firstname` LIKE \'%'.pSQL($query).'%\' '.$where_deleted.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER).')';
|
||||
|
||||
if ($limit) {
|
||||
$sql .= ' LIMIT 0, '.(int)$limit;
|
||||
@@ -796,6 +798,7 @@ class CustomerCore extends ObjectModel
|
||||
$this->passwd = Tools::encrypt($password);
|
||||
$this->cleanGroups();
|
||||
$this->addGroups(array(Configuration::get('PS_CUSTOMER_GROUP'))); // add default customer group
|
||||
$this->id_default_group = (int) Configuration::get('PS_CUSTOMER_GROUP');
|
||||
if ($this->update()) {
|
||||
$vars = array(
|
||||
'{firstname}' => $this->firstname,
|
||||
|
||||
@@ -118,7 +118,7 @@ class CustomerMessageCore extends ObjectModel
|
||||
}
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
|
||||
public static function getMessagesByDate($date)
|
||||
{
|
||||
return Db::getInstance()->getValue(
|
||||
@@ -127,4 +127,18 @@ class CustomerMessageCore extends ObjectModel
|
||||
WHERE cm.`date_add` BETWEEN "'.pSQL($date).' 00:00:00" AND "'.pSQL($date).' 23:59:59"'
|
||||
);
|
||||
}
|
||||
|
||||
public function searchByName($query)
|
||||
{
|
||||
return Db::getInstance()->executeS('
|
||||
SELECT cm.*, ct.*, CONCAT(c.`firstname`, \' \', c.`lastname`) `customer_name`
|
||||
FROM `'._DB_PREFIX_.'customer_message` cm
|
||||
LEFT JOIN '._DB_PREFIX_.'customer_thread ct
|
||||
ON (ct.`id_customer_thread` = cm.`id_customer_thread`)
|
||||
LEFT JOIN '._DB_PREFIX_.'customer c
|
||||
ON (IFNULL(ct.`id_customer`, ct.`email`) = IFNULL(c.`id_customer`, c.`email`))
|
||||
WHERE `message` LIKE \'%'.$query.'%\'
|
||||
');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -279,7 +279,12 @@ class DispatcherCore
|
||||
$controllers = Dispatcher::getControllers(_PS_MODULE_DIR_.$module_name.'/controllers/front/');
|
||||
if (isset($controllers[strtolower($this->controller)])) {
|
||||
include_once(_PS_MODULE_DIR_.$module_name.'/controllers/front/'.$this->controller.'.php');
|
||||
$controller_class = $module_name.$this->controller.'ModuleFrontController';
|
||||
if (file_exists(_PS_OVERRIDE_DIR_.'modules/'.$module_name.'/controllers/front/'.$this->controller.'.php')) {
|
||||
include_once(_PS_OVERRIDE_DIR_.'modules/'.$module_name.'/controllers/front/'.$this->controller.'.php');
|
||||
$controller_class = $module_name.$this->controller.'ModuleFrontControllerOverride';
|
||||
} else {
|
||||
$controller_class = $module_name.$this->controller.'ModuleFrontController';
|
||||
}
|
||||
}
|
||||
}
|
||||
$params_hook_action_dispatcher = array('controller_type' => self::FC_FRONT, 'controller_class' => $controller_class, 'is_module' => 1);
|
||||
@@ -300,12 +305,22 @@ class DispatcherCore
|
||||
} else {
|
||||
$controllers = Dispatcher::getControllers(_PS_MODULE_DIR_.$tab->module.'/controllers/admin/');
|
||||
if (!isset($controllers[strtolower($this->controller)])) {
|
||||
// If this is a parent tab, load the first child
|
||||
if (Validate::isLoadedObject($tab) && $tab->id_parent == 0 && ($tabs = Tab::getTabs(Context::getContext()->language->id, $tab->id)) && isset($tabs[0])) {
|
||||
Tools::redirectAdmin(Context::getContext()->link->getAdminLink($tabs[0]['class_name']));
|
||||
}
|
||||
|
||||
$this->controller = $this->controller_not_found;
|
||||
$controller_class = 'AdminNotFoundController';
|
||||
} else {
|
||||
// Controllers in modules can be named AdminXXX.php or AdminXXXController.php
|
||||
include_once(_PS_MODULE_DIR_.$tab->module.'/controllers/admin/'.$controllers[strtolower($this->controller)].'.php');
|
||||
$controller_class = $controllers[strtolower($this->controller)].(strpos($controllers[strtolower($this->controller)], 'Controller') ? '' : 'Controller');
|
||||
if (file_exists(_PS_OVERRIDE_DIR_ . 'modules/' . $tab->module . '/controllers/admin/' . $controllers[strtolower($this->controller)] . '.php')) {
|
||||
include_once(_PS_OVERRIDE_DIR_ . 'modules/' . $tab->module . '/controllers/admin/' . $controllers[strtolower($this->controller)] . '.php');
|
||||
$controller_class = $controllers[strtolower($this->controller)] . (strpos($controllers[strtolower($this->controller)], 'Controller') ? 'Override' : 'ControllerOverride');
|
||||
} else {
|
||||
$controller_class = $controllers[strtolower($this->controller)] . (strpos($controllers[strtolower($this->controller)], 'Controller') ? '' : 'Controller');
|
||||
}
|
||||
}
|
||||
}
|
||||
$params_hook_action_dispatcher = array('controller_type' => self::FC_ADMIN, 'controller_class' => $controller_class, 'is_module' => 1);
|
||||
|
||||
@@ -361,4 +361,18 @@ class FeatureCore extends ObjectModel
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public static function searchByName($name, $idLang = false)
|
||||
{
|
||||
if (!$idLang) {
|
||||
$idLang = Context::getContext()->language->id;
|
||||
}
|
||||
|
||||
return Db::getInstance()->executeS('
|
||||
SELECT *
|
||||
FROM '._DB_PREFIX_.'feature_lang
|
||||
WHERE `name` LIKE \'%'.pSQL($name).'%\'
|
||||
AND `id_lang`='.(int)$idLang
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,4 +372,16 @@ class GroupCore extends ObjectModel
|
||||
WHERE `name` = \''.pSQL($query).'\'
|
||||
');
|
||||
}
|
||||
|
||||
public function searchGroupsByName($query)
|
||||
{
|
||||
return Db::getInstance()->executeS('
|
||||
SELECT g.*, gl.*
|
||||
FROM `'._DB_PREFIX_.'group` g
|
||||
LEFT JOIN `'._DB_PREFIX_.'group_lang` gl
|
||||
ON (g.`id_group` = gl.`id_group`)
|
||||
WHERE `name` LIKE \'%'.pSQL($query).'%\'
|
||||
');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -211,7 +211,9 @@ abstract class ObjectModelCore implements Core_Foundation_Database_EntityInterfa
|
||||
throw new PrestaShopException('Identifier or table format not valid for class '.$class_name);
|
||||
}
|
||||
|
||||
ObjectModel::$loaded_classes[$class_name] = get_object_vars($this);
|
||||
$objProperties = get_object_vars($this);
|
||||
Hook::exec('actionObject'.$class_name.'PropertiesModifier', array('obj_properties' => &$objProperties));
|
||||
ObjectModel::$loaded_classes[$class_name] = $objProperties;
|
||||
} else {
|
||||
foreach (ObjectModel::$loaded_classes[$class_name] as $key => $value) {
|
||||
$this->{$key} = $value;
|
||||
@@ -1885,6 +1887,8 @@ abstract class ObjectModelCore implements Core_Foundation_Database_EntityInterfa
|
||||
);
|
||||
}
|
||||
|
||||
Hook::exec('actionObject'.$class.'DefinitionModifier', array('definition' => &$definition));
|
||||
|
||||
if ($field) {
|
||||
return isset($definition['fields'][$field]) ? $definition['fields'][$field] : null;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ abstract class PaymentModuleCore extends Module
|
||||
if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
|
||||
$address = new Address((int)$id_address);
|
||||
$this->context->country = new Country((int)$address->id_country, (int)$this->context->cart->id_lang);
|
||||
if (!$this->context->country->active) {
|
||||
if (!$this->context->country->active && $this->name != 'wsorder') {
|
||||
throw new PrestaShopException('The delivery address country is not active.');
|
||||
}
|
||||
}
|
||||
@@ -468,7 +468,7 @@ abstract class PaymentModuleCore extends Module
|
||||
$this->context->country = $context_country;
|
||||
}
|
||||
|
||||
if (!$this->context->country->active) {
|
||||
if (!$this->context->country->active && $this->name != 'wsorder') {
|
||||
PrestaShopLogger::addLog('PaymentModule::validateOrder - Country is not active', 3, null, 'Cart', (int)$id_cart, true);
|
||||
throw new PrestaShopException('The order address country is not active.');
|
||||
}
|
||||
@@ -646,17 +646,17 @@ abstract class PaymentModuleCore extends Module
|
||||
// THEN
|
||||
// The voucher is cloned with a new value corresponding to the remainder
|
||||
$reduction_amount_converted = $cart_rule['obj']->reduction_amount;
|
||||
if ((int) $cart_rule['obj']->reduction_currency !== (int) $cart->id_currency) {
|
||||
if ((int) $cart_rule['obj']->reduction_currency !== (int) $this->context->cart->id_currency) {
|
||||
$reduction_amount_converted = Tools::convertPriceFull(
|
||||
$cart_rule['obj']->reduction_amount,
|
||||
new Currency($cart_rule['obj']->reduction_currency),
|
||||
new Currency($cart->id_currency)
|
||||
new Currency($this->context->cart->id_currency)
|
||||
);
|
||||
}
|
||||
if ($cart_rule['obj']->reduction_tax) {
|
||||
$remaining_amount = $reduction_amount_converted - $values['tax_incl'];
|
||||
$remaining_amount = $values['tax_incl'] - $order->total_products_wt;
|
||||
} else {
|
||||
$remaining_amount = $reduction_amount_converted - $values['tax_excl'];
|
||||
$remaining_amount = $values['tax_excl'] - $order->total_products;
|
||||
}
|
||||
if ($remaining_amount > 0 && $cart_rule['obj']->partial_use == 1 && $reduction_amount_converted > 0) {
|
||||
// Create a new voucher from the original
|
||||
@@ -664,9 +664,13 @@ abstract class PaymentModuleCore extends Module
|
||||
unset($voucher->id);
|
||||
|
||||
// Set a new voucher code
|
||||
// For a customer, applying voucher ABCD will create partial vouchers ABCD-2, ABCD-3 and so on, and
|
||||
// applying voucher ABCD-2 will create vouchers ABCD-2-2, ABCD-2-3 and so on
|
||||
$voucher->code = empty($voucher->code) ? substr(md5($order->id.'-'.$order->id_customer.'-'.$cart_rule['obj']->id), 0, 16) : $voucher->code.'-2';
|
||||
if (preg_match('/\-([0-9]{1,2})\-([0-9]{1,2})$/', $voucher->code, $matches) && $matches[1] == $matches[2]) {
|
||||
$voucher->code = preg_replace('/'.$matches[0].'$/', '-'.(intval($matches[1]) + 1), $voucher->code);
|
||||
while (CartRule::cartRuleExists($voucher->code, $order->id_customer)) {
|
||||
if (preg_match('/\-([0-9]{1,2})$/', $voucher->code, $matches)) {
|
||||
$voucher->code = preg_replace('/'.$matches[1].'$/', (intval($matches[1]) + 1), $voucher->code);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the new voucher value
|
||||
@@ -862,7 +866,11 @@ abstract class PaymentModuleCore extends Module
|
||||
$objBookingDetail->total_paid_amount = $objAdvancedPayment->getRoomMinAdvPaymentAmount(
|
||||
$idProduct,
|
||||
$objCartBookingData->date_from,
|
||||
$objCartBookingData->date_to
|
||||
$objCartBookingData->date_to,
|
||||
1,
|
||||
$objCartBookingData->id_room,
|
||||
$objCartBookingData->id_cart,
|
||||
$objCartBookingData->id_guest
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -920,7 +928,6 @@ abstract class PaymentModuleCore extends Module
|
||||
$objBookingDemand->tax_computation_method = (int)$taxCalc->computation_method;
|
||||
if ($objBookingDemand->save()) {
|
||||
$objBookingDemand->tax_calculator = $taxCalc;
|
||||
$objBookingDemand->id_global_demand = $idGlobalDemand;
|
||||
// Now save tax details of the extra demand
|
||||
$objBookingDemand->setBookingDemandTaxDetails();
|
||||
}
|
||||
@@ -1005,11 +1012,9 @@ abstract class PaymentModuleCore extends Module
|
||||
// Set the order status
|
||||
$new_history = new OrderHistory();
|
||||
$new_history->id_order = (int)$order->id;
|
||||
if ($order_status->logable && $order->is_advance_payment && $order->advance_paid_amount < $order->total_paid_tax_incl) {
|
||||
$new_history->changeIdOrderState((int)Configuration::get('PS_OS_PARTIAL_PAYMENT'), $order, true);
|
||||
} else {
|
||||
$new_history->changeIdOrderState((int)$id_order_state, $order, true);
|
||||
}
|
||||
|
||||
$new_history->changeIdOrderState((int)$id_order_state, $order, true);
|
||||
|
||||
$new_history->addWithemail(true, $extra_vars);
|
||||
|
||||
// Switch to back order if needed
|
||||
@@ -1044,47 +1049,19 @@ abstract class PaymentModuleCore extends Module
|
||||
$normal_products_data_txt = $this->getEmailTemplateContent('hotel-service-product-data-text.tpl', Mail::TYPE_TEXT, $orderServiceProducts);
|
||||
|
||||
// total room price
|
||||
$room_price_tax_excl = $order->getTotalProductsWithoutTaxes(false, true);
|
||||
$room_price_tax_incl = $order->getTotalProductsWithTaxes(false, true);
|
||||
$room_tax = ($order->getTotalProductsWithTaxes(false, true) - $order->getTotalProductsWithoutTaxes(false, true));
|
||||
$room_price_tax_excl = $order->getTotalProductsWithoutTaxes(false, true) + $order->getTotalProductsWithoutTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE, 1, Product::PRICE_ADDITION_TYPE_WITH_ROOM);
|
||||
$room_price_tax_incl = $order->getTotalProductsWithTaxes(false, true) + $order->getTotalProductsWithTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE, 1, Product::PRICE_ADDITION_TYPE_WITH_ROOM);
|
||||
$room_tax = ($room_price_tax_incl - $room_price_tax_excl);
|
||||
|
||||
// extra services
|
||||
$additional_service_price_tax_excl = ($order->getTotalProductsWithoutTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE) + $cart_booking_data['total_extra_demands_te']);
|
||||
$additional_service_price_tax_incl = ($order->getTotalProductsWithTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE) + $cart_booking_data['total_extra_demands_ti']);
|
||||
$additional_service_tax = (($order->getTotalProductsWithTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE) + $cart_booking_data['total_extra_demands_ti']) - ($order->getTotalProductsWithoutTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE) + $cart_booking_data['total_extra_demands_te']));
|
||||
$additional_service_price_tax_excl = ($order->getTotalProductsWithoutTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE, 0) + $cart_booking_data['total_extra_demands_te']);
|
||||
$additional_service_price_tax_incl = ($order->getTotalProductsWithTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE, 0) + $cart_booking_data['total_extra_demands_ti']);
|
||||
$additional_service_tax = ($additional_service_price_tax_incl - $additional_service_price_tax_excl);
|
||||
|
||||
|
||||
// convenience fee price
|
||||
$objRoomTypeServiceProductOrderDetail = new RoomTypeServiceProductOrderDetail();
|
||||
$total_convenience_fee_ti = $objRoomTypeServiceProductOrderDetail->getroomTypeServiceProducts(
|
||||
$order->id,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
Product::PRICE_ADDITION_TYPE_INDEPENDENT
|
||||
);
|
||||
$total_convenience_fee_te = $objRoomTypeServiceProductOrderDetail->getroomTypeServiceProducts(
|
||||
$order->id,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
Product::PRICE_ADDITION_TYPE_INDEPENDENT
|
||||
);
|
||||
$additional_service_price_tax_excl = $additional_service_price_tax_excl - $total_convenience_fee_te;
|
||||
$additional_service_price_tax_incl = $additional_service_price_tax_incl - $total_convenience_fee_ti;
|
||||
$room_price_tax_excl = $room_price_tax_excl + $additional_service_price_tax_excl;
|
||||
$room_price_tax_incl = $room_price_tax_incl + $additional_service_price_tax_incl;
|
||||
$total_convenience_fee_ti = $order->getTotalProductsWithTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE, 1, Product::PRICE_ADDITION_TYPE_INDEPENDENT);
|
||||
$total_convenience_fee_te = $order->getTotalProductsWithoutTaxes(false, false, Product::SERVICE_PRODUCT_WITH_ROOMTYPE, 1, Product::PRICE_ADDITION_TYPE_INDEPENDENT);
|
||||
|
||||
// service products
|
||||
// $service_products_price_tax_excl = $order->getTotalProductsWithoutTaxes(false, false, Product::SERVICE_PRODUCT_WITHOUT_ROOMTYPE);
|
||||
@@ -1237,25 +1214,27 @@ abstract class PaymentModuleCore extends Module
|
||||
}
|
||||
if (Configuration::get('PS_ORDER_CONF_MAIL_TO_SUPERADMIN')){
|
||||
// send superadmin information
|
||||
if (Validate::isLoadedObject($superAdmin = new Employee(_PS_ADMIN_PROFILE_))) {
|
||||
if (Validate::isEmail($superAdmin->email)) {
|
||||
$data['{customer_name}'] = $this->context->customer->firstname.' '.$this->context->customer->lastname;
|
||||
$data['{customer_email}'] = $this->context->customer->email;
|
||||
$data['{firstname}'] = $superAdmin->firstname;
|
||||
$data['{lastname}'] = $superAdmin->lastname;
|
||||
$data['{email}'] = $superAdmin->email;
|
||||
Mail::Send(
|
||||
(int)$order->id_lang,
|
||||
'order_conf_admin',
|
||||
Mail::l('Order confirmation', (int)$order->id_lang),
|
||||
$data,
|
||||
$superAdmin->email,
|
||||
$superAdmin->firstname.' '.$superAdmin->lastname,
|
||||
null,
|
||||
null,
|
||||
$file_attachement,
|
||||
null, _PS_MAIL_DIR_, false, (int)$order->id_shop
|
||||
);
|
||||
if ($superAdminEmployees = Employee::getEmployeesByProfile(_PS_ADMIN_PROFILE_, true)) {
|
||||
foreach ($superAdminEmployees as $superAdminEmployee) {
|
||||
if (Validate::isEmail($superAdminEmployee['email'])) {
|
||||
$data['{customer_name}'] = $this->context->customer->firstname.' '.$this->context->customer->lastname;
|
||||
$data['{customer_email}'] = $this->context->customer->email;
|
||||
$data['{firstname}'] = $superAdminEmployee['firstname'];
|
||||
$data['{lastname}'] = $superAdminEmployee['lastname'];
|
||||
$data['{email}'] = $superAdminEmployee['email'];
|
||||
Mail::Send(
|
||||
(int)$order->id_lang,
|
||||
'order_conf_admin',
|
||||
Mail::l('Order confirmation', (int)$order->id_lang),
|
||||
$data,
|
||||
$superAdminEmployee['email'],
|
||||
$superAdminEmployee['firstname'].' '.$superAdminEmployee['lastname'],
|
||||
null,
|
||||
null,
|
||||
$file_attachement,
|
||||
null, _PS_MAIL_DIR_, false, (int)$order->id_shop
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1289,7 +1268,7 @@ abstract class PaymentModuleCore extends Module
|
||||
$data['{customer_name}'] = $this->context->customer->firstname.' '.$this->context->customer->lastname;
|
||||
$data['{customer_email}'] = $this->context->customer->email;
|
||||
foreach ($htlAccesses as $access) {
|
||||
if ($access['id_profile'] != _PS_ADMIN_PROFILE_) {
|
||||
if ($access['access'] && $access['id_profile'] != _PS_ADMIN_PROFILE_) {
|
||||
if ($htlEmployees = Employee::getEmployeesByProfile($access['id_profile'])) {
|
||||
foreach ($htlEmployees as $empl) {
|
||||
if (Validate::isEmail($empl['email'])) {
|
||||
@@ -1659,8 +1638,11 @@ abstract class PaymentModuleCore extends Module
|
||||
);
|
||||
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] = $data_v['total_price_tax_incl']/$num_days;
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['avg_paid_unit_price_tax_incl'] += ($cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_excl'] = $data_v['total_price_tax_excl']/$num_days;
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['avg_paid_unit_price_tax_incl'] += ($cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_ti']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['avg_paid_unit_price_tax_excl'] += ($cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_excl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['amount_tax_incl'] += ($data_v['total_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['amount_tax_excl'] += ($data_v['total_price_tax_excl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
} else {
|
||||
$num_days = $obj_htl_bk_dtl->getNumberOfDays($data_v['date_from'], $data_v['date_to']);
|
||||
|
||||
@@ -1762,8 +1744,11 @@ abstract class PaymentModuleCore extends Module
|
||||
);
|
||||
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] = $data_v['total_price_tax_incl']/$num_days;
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['avg_paid_unit_price_tax_incl'] = ($cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['amount_tax_incl'] = ($data_v['total_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_excl'] = $data_v['total_price_tax_excl']/$num_days;
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['avg_paid_unit_price_tax_incl'] = ($cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_ti']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['avg_paid_unit_price_tax_excl'] = ($cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_excl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['amount_tax_incl'] = ($data_v['total_price_tax_incl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_ti']);
|
||||
$cart_htl_data[$type_key]['date_diff'][$date_join]['amount_tax_excl'] = ($data_v['total_price_tax_excl'] + $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_auto_add_te']);
|
||||
|
||||
$result['total_extra_demands_te'] += $cart_htl_data[$type_key]['date_diff'][$date_join]['extra_demands_price_te'];
|
||||
$result['total_extra_demands_ti'] += $cart_htl_data[$type_key]['date_diff'][$date_join]['extra_demands_price_ti'];
|
||||
@@ -1771,10 +1756,10 @@ abstract class PaymentModuleCore extends Module
|
||||
$result['total_additional_services_ti'] += $cart_htl_data[$type_key]['date_diff'][$date_join]['additional_services_price_ti'];
|
||||
}
|
||||
}
|
||||
}
|
||||
// calculate averages now
|
||||
foreach ($cart_htl_data[$type_key]['date_diff'] as $key => &$value) {
|
||||
$value['avg_paid_unit_price_tax_incl'] = Tools::ps_round($value['avg_paid_unit_price_tax_incl'] / $value['num_rm'], 6);
|
||||
// calculate averages now
|
||||
foreach ($cart_htl_data[$type_key]['date_diff'] as $key => &$value) {
|
||||
$value['avg_paid_unit_price_tax_incl'] = Tools::ps_round($value['avg_paid_unit_price_tax_incl'] / $value['num_rm'], 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,12 +649,12 @@ class ProductCore extends ObjectModel
|
||||
* @param int $position
|
||||
* return boolean Update result
|
||||
*/
|
||||
public function updatePosition($way, $position)
|
||||
public function updatePosition($way, $position, $id_category = null)
|
||||
{
|
||||
if (!$res = Db::getInstance()->executeS('
|
||||
SELECT cp.`id_product`, cp.`position`, cp.`id_category`
|
||||
FROM `'._DB_PREFIX_.'category_product` cp
|
||||
WHERE cp.`id_category` = '.(int)Tools::getValue('id_category', 1).'
|
||||
WHERE cp.`id_category` = '.(int) ($id_category ? $id_category: Tools::getValue('id_category', 1)).'
|
||||
ORDER BY cp.`position` ASC')
|
||||
) {
|
||||
return false;
|
||||
@@ -1454,23 +1454,25 @@ class ProductCore extends ObjectModel
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getServiceProducts($idLang, $front = false, $context = false)
|
||||
public function getServiceProducts($active = null, $serviceProductType = null, $idLang = null, $orderBy = 'pl.name', $orderWay = 'ASC')
|
||||
{
|
||||
if (!$context) {
|
||||
$context = Context::getContext();
|
||||
if (!$idLang) {
|
||||
$idLang = Context::getContext()->language->id;
|
||||
}
|
||||
$sql = 'SELECT p.*, product_shop.*, pl.*, image_shop.`id_image` id_image, il.`legend` as legend
|
||||
FROM `'._DB_PREFIX_.'product` p
|
||||
'.Shop::addSqlAssociation('product', 'p').'
|
||||
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` '.Shop::addSqlRestrictionOnLang('pl').')
|
||||
LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
|
||||
ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'image_lang` il
|
||||
ON (image_shop.`id_image` = il.`id_image`
|
||||
AND il.`id_lang` = '.(int)$idLang.')';
|
||||
$sql .= 'WHERE pl.`id_lang` = '.(int)$idLang.' AND p.`booking_product` = 0
|
||||
AND p.`service_product_type` = '.Product::SERVICE_PRODUCT_WITHOUT_ROOMTYPE.'
|
||||
ORDER BY pl.`name`';
|
||||
|
||||
$sql = 'SELECT p.*, pl.*, i.`id_image`, il.`legend` AS legend
|
||||
FROM `'._DB_PREFIX_.'product` p
|
||||
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = p.`id_product` AND pl.`id_lang` = '.(int) $idLang.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
|
||||
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (il.`id_image` = i.`id_image` AND il.`id_lang` = '.(int) $idLang.')
|
||||
WHERE p.`booking_product` = 0'.
|
||||
(!is_null($active) ? ' AND p.`active` = '.(int) $active : '').
|
||||
($serviceProductType ? ' AND p.`service_product_type` = '.(int) $serviceProductType : '');
|
||||
|
||||
if (Validate::isOrderBy($orderBy) && Validate::isOrderBy($orderWay)) {
|
||||
$sql .= ' ORDER BY '.$orderBy.' '.$orderWay;
|
||||
}
|
||||
|
||||
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
|
||||
}
|
||||
|
||||
@@ -2580,9 +2582,15 @@ class ProductCore extends ObjectModel
|
||||
|
||||
$id_address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
|
||||
$ids = Address::getCountryAndState($id_address);
|
||||
$id_country = $ids['id_country'] ? (int) $ids['id_country'] : (int) Configuration::get('PS_COUNTRY_DEFAULT');
|
||||
|
||||
return SpecificPrice::getProductIdByDate(
|
||||
$id_country = null;
|
||||
if (isset($ids['id_country']) && (int) $ids['id_country']) {
|
||||
$id_country = (int) $ids['id_country'];
|
||||
} else {
|
||||
$id_country = (int) Configuration::get('PS_COUNTRY_DEFAULT');
|
||||
}
|
||||
|
||||
return SpecificPrice::getProductIdByDate(
|
||||
$context->shop->id,
|
||||
$context->currency->id,
|
||||
$id_country,
|
||||
@@ -3473,9 +3481,18 @@ class ProductCore extends ObjectModel
|
||||
);
|
||||
}
|
||||
|
||||
public function getPriceWithoutReduct($notax = false, $id_product_attribute = false, $decimals = 6)
|
||||
public function getPriceWithoutReduct($notax = false, $id_product_attribute = false, $decimals = 6, $with_auto_add_services = 0)
|
||||
{
|
||||
return Product::getPriceStatic((int)$this->id, !$notax, $id_product_attribute, $decimals, null, false, false);
|
||||
$price = Product::getPriceStatic((int)$this->id, !$notax, $id_product_attribute, $decimals, null, false, false);
|
||||
if ($with_auto_add_services) {
|
||||
if ($services = RoomTypeServiceProduct::getAutoAddServices((int) $this->id, null, null, Product::PRICE_ADDITION_TYPE_WITH_ROOM, !$notax)) {
|
||||
foreach($services as $service) {
|
||||
$price += $service['price'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $price;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5320,6 +5337,68 @@ class ProductCore extends ObjectModel
|
||||
return $tax_calculator->getTotalRate();
|
||||
}
|
||||
|
||||
public function getPositionInCategory()
|
||||
{
|
||||
return Db::getInstance()->getValue(
|
||||
'SELECT position
|
||||
FROM `'._DB_PREFIX_.'category_product`
|
||||
WHERE id_category = '.(int) $this->id_category_default.'
|
||||
AND id_product = '.(int) $this->id
|
||||
);
|
||||
}
|
||||
|
||||
public function setPositionInCategory($position)
|
||||
{
|
||||
if ($position < 0) {
|
||||
die(Tools::displayError('You cannot set a negative position, the minimum for a position is 0.'));
|
||||
}
|
||||
|
||||
$result = Db::getInstance()->executeS(
|
||||
'SELECT `id_product`
|
||||
FROM `'._DB_PREFIX_.'category_product`
|
||||
WHERE `id_category` = '.(int) $this->id_category_default.'
|
||||
ORDER BY `position`'
|
||||
);
|
||||
|
||||
if (($position > 0) && ($position + 1 > count($result))) {
|
||||
die(Tools::displayError('You cannot set a position greater than the total number of room types in the hotel, minus 1 (position numbering starts at 0).'));
|
||||
}
|
||||
|
||||
foreach ($result as &$value) {
|
||||
$value = $value['id_product'];
|
||||
}
|
||||
|
||||
$currentPosition = $this->getPositionInCategory();
|
||||
|
||||
if ($currentPosition && isset($result[$currentPosition])) {
|
||||
$save = $result[$currentPosition];
|
||||
unset($result[$currentPosition]);
|
||||
array_splice($result, (int)$position, 0, $save);
|
||||
}
|
||||
|
||||
$return = true;
|
||||
foreach ($result as $position => $id_product) {
|
||||
$return &= Db::getInstance()->update(
|
||||
'category_product',
|
||||
array('position' => $position),
|
||||
'(`id_category` = '.(int) $this->id_category_default.' AND `id_product` = '.(int) $id_product.')'
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function getHighestPositionInCategory($idCategory)
|
||||
{
|
||||
$position = Db::getInstance()->getValue(
|
||||
'SELECT MAX(`position`)
|
||||
FROM `'._DB_PREFIX_.'category_product`
|
||||
WHERE `id_category` = '.(int) $idCategory
|
||||
);
|
||||
|
||||
return (is_numeric($position)) ? $position : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Webservice getter : get product features association
|
||||
* @return array
|
||||
@@ -5568,14 +5647,7 @@ class ProductCore extends ObjectModel
|
||||
*/
|
||||
public function getWsPositionInCategory()
|
||||
{
|
||||
$result = Db::getInstance()->executeS('SELECT position
|
||||
FROM `'._DB_PREFIX_.'category_product`
|
||||
WHERE id_category = '.(int)$this->id_category_default.'
|
||||
AND id_product = '.(int)$this->id);
|
||||
if (count($result) > 0) {
|
||||
return $result[0]['position'];
|
||||
}
|
||||
return '';
|
||||
return $this->getPositionInCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -145,7 +145,12 @@ class SpecificPriceCore extends ObjectModel
|
||||
FROM `'._DB_PREFIX_.'specific_price`
|
||||
WHERE 1 '.self::filterOutField('id_product', $id_product).
|
||||
($id_product_attribute ? ' AND id_product_attribute = '.(int) $id_product_attribute : '').'
|
||||
AND id_cart = '.(int) $id_cart
|
||||
AND id_cart = '.(int) $id_cart.'
|
||||
GROUP BY
|
||||
case when id_specific_price_rule <> 0
|
||||
then id_specific_price_rule
|
||||
else id_specific_price
|
||||
end'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,6 +180,12 @@ class SpecificPriceCore extends ObjectModel
|
||||
$select = '(';
|
||||
|
||||
$priority = SpecificPrice::getPriority($id_product);
|
||||
if (!Group::isFeatureActive()) {
|
||||
if (($key = array_search('id_group', $priority)) !== false) {
|
||||
unset($priority[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_reverse($priority) as $k => $field) {
|
||||
if (!empty($field)) {
|
||||
$select .= ' IF (`'.bqSQL($field).'` = '.(int)$$field.', '.pow(2, $k + 1).', 0) + ';
|
||||
@@ -353,8 +364,8 @@ class SpecificPriceCore extends ObjectModel
|
||||
WHERE
|
||||
`id_shop` '.self::formatIntInQuery(0, $id_shop).' AND
|
||||
`id_currency` '.self::formatIntInQuery(0, $id_currency).' AND
|
||||
`id_country` '.self::formatIntInQuery(0, $id_country).' AND
|
||||
`id_group` '.self::formatIntInQuery(0, $id_group).' '.$query_extra.'
|
||||
`id_country` '.self::formatIntInQuery(0, $id_country).
|
||||
(Group::isFeatureActive() ? ' AND `id_group` '.self::formatIntInQuery(0, $id_group) : '').' '.$query_extra.'
|
||||
AND IF(`from_quantity` > 1, `from_quantity`, 0) <= ';
|
||||
|
||||
$query .= (Configuration::get('PS_QTY_DISCOUNT_ON_COMBINATION') || !$id_cart || !$real_quantity) ? (int)$quantity : max(1, (int)$real_quantity);
|
||||
|
||||
@@ -80,6 +80,39 @@ class ToolsCore
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function generateRandomZipcode($idCountry)
|
||||
{
|
||||
$randomZipCode = '';
|
||||
$alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$alphabetLength = Tools::strlen($alphabet);
|
||||
if (Validate::isLoadedObject($objCountry = new Country($idCountry))
|
||||
&& $objCountry->need_zip_code
|
||||
) {
|
||||
if ($zipCodeFormat = $objCountry->zip_code_format) {
|
||||
for ($i = 0; $i < Tools::strlen($zipCodeFormat); $i++) {
|
||||
$formatCharacter = $zipCodeFormat[$i];
|
||||
if (in_array($formatCharacter, array('N', 'L', 'C'))) {
|
||||
if ($formatCharacter == 'N') {
|
||||
$randomZipCode .= mt_rand(0, 9);
|
||||
} elseif ($formatCharacter == 'L') {
|
||||
$randomZipCode .= $alphabet[mt_rand(0, $alphabetLength - 1)];
|
||||
} elseif ($formatCharacter == 'C') {
|
||||
$randomZipCode .= $objCountry->iso_code;
|
||||
}
|
||||
} else {
|
||||
$randomZipCode .= $formatCharacter;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ($i = 1; $i <= 5; $i++) {
|
||||
$randomZipCode .= mt_rand(0, 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $randomZipCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Random bytes generator
|
||||
*
|
||||
@@ -3023,6 +3056,8 @@ exit;
|
||||
$smarty = Context::getContext()->smarty;
|
||||
Tools::clearCache($smarty);
|
||||
Tools::clearCompile($smarty);
|
||||
@copy(_PS_CACHE_DIR_.'smarty/index.php', _PS_CACHE_DIR_.'smarty/cache/index.php');
|
||||
@copy(_PS_CACHE_DIR_.'smarty/index.php', _PS_CACHE_DIR_.'smarty/compile/index.php');
|
||||
}
|
||||
|
||||
public static function clearColorListCache($id_product = false)
|
||||
@@ -3603,6 +3638,8 @@ exit;
|
||||
|
||||
public static function purifyHTML($html, $uri_unescape = null, $allow_style = false)
|
||||
{
|
||||
require_once(_PS_TOOL_DIR_.'htmlpurifier/HTMLPurifier.auto.php');
|
||||
|
||||
static $use_html_purifier = null;
|
||||
static $purifier = null;
|
||||
|
||||
|
||||
@@ -397,6 +397,14 @@ class AdminControllerCore extends Controller
|
||||
|
||||
/** @var int level for permissions View/read */
|
||||
const LEVEL_VIEW = 1;
|
||||
const QLO_SEARCH_TYPE_CATELOG = 1;
|
||||
const QLO_SEARCH_TYPE_CUSTOMER_BY_NAME = 2;
|
||||
const QLO_SEARCH_TYPE_ORDER = 3;
|
||||
const QLO_SEARCH_TYPE_INVOICE = 4;
|
||||
const QLO_SEARCH_TYPE_CART = 5;
|
||||
const QLO_SEARCH_TYPE_CUSTOMER_BY_IP = 6;
|
||||
const QLO_SEARCH_TYPE_MODULE = 7;
|
||||
const QLO_SEARCH_TYPE_HOTEL = 8;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -407,6 +415,9 @@ class AdminControllerCore extends Controller
|
||||
|
||||
$this->controller_type = 'admin';
|
||||
$this->controller_name = get_class($this);
|
||||
if (strpos($this->controller_name, 'ControllerOverride')) {
|
||||
$this->controller_name = substr($this->controller_name, 0, -18);
|
||||
}
|
||||
if (strpos($this->controller_name, 'Controller')) {
|
||||
$this->controller_name = substr($this->controller_name, 0, -10);
|
||||
}
|
||||
@@ -875,13 +886,15 @@ class AdminControllerCore extends Controller
|
||||
|
||||
if ($field = $this->filterToField($key, $filter)) {
|
||||
$type = (array_key_exists('filter_type', $field) ? $field['filter_type'] : (array_key_exists('type', $field) ? $field['type'] : false));
|
||||
if (($type == 'date' || $type == 'datetime' || $type == 'range') && is_string($value)) {
|
||||
if ((($type == 'date' || $type == 'datetime' || $type == 'range') || ($type == 'select' && (isset($field['multiple']) && $field['multiple'])))
|
||||
&& is_string($value)
|
||||
) {
|
||||
$value = json_decode($value, true);
|
||||
}
|
||||
$key = isset($tmp_tab[1]) ? $tmp_tab[0].'.`'.$tmp_tab[1].'`' : '`'.$tmp_tab[0].'`';
|
||||
|
||||
// as in database 0 means position 1 in the renderlist
|
||||
if (isset($field['position'])) {
|
||||
if (isset($field['position']) && Validate::isInt($value)) {
|
||||
$value -= 1;
|
||||
}
|
||||
|
||||
@@ -893,21 +906,35 @@ class AdminControllerCore extends Controller
|
||||
} else {
|
||||
$sql_filter = & $this->_filter;
|
||||
}
|
||||
/* Only for date filtering (from, to) */
|
||||
|
||||
if (is_array($value)) {
|
||||
if ($type == 'range') {
|
||||
if (isset($value[0]) && !empty($value[0])) {
|
||||
if (!Validate::isUnsignedInt($value[0])) {
|
||||
if ($type == 'select' && (isset($field['multiple']) && $field['multiple']) && isset($field['operator'])) {
|
||||
if ($field['operator'] == 'and') {
|
||||
$sql_filter .= ' AND '.pSQL($key).' IN ('.pSQL(implode(',', $value)).')';
|
||||
$this->_filterHaving .= ' AND COUNT(DISTINCT '.pSQL($key).') = '.(int) count($value);
|
||||
} elseif ($field['operator'] == 'or') {
|
||||
$sql_filter .= ' AND '.pSQL($key).' IN ('.pSQL(implode(',', $value)).')';
|
||||
}
|
||||
} elseif ($type == 'range') {
|
||||
// set validation type
|
||||
if (isset($field['validation']) && $field['validation'] && method_exists('Validate', $field['validation'])) {
|
||||
$validation = $field['validation'];
|
||||
} else {
|
||||
$validation = 'isUnsignedInt';
|
||||
}
|
||||
|
||||
if (isset($value[0]) && ($value[0] !== '' || $value[0] === 0)) {
|
||||
if (!Validate::$validation($value[0])) {
|
||||
$this->errors[] = Tools::displayError('The \'From\' value is invalid');
|
||||
} else {
|
||||
$sql_filter .= ' AND '.pSQL($key).' >= '.pSQL($value[0]);
|
||||
}
|
||||
}
|
||||
if (isset($value[1]) && !empty($value[1])) {
|
||||
if (!Validate::isUnsignedInt($value[1])) {
|
||||
$this->errors[] = Tools::displayError('The \'From\' value is invalid');
|
||||
} elseif (isset($value[0]) && !empty($value[0]) && $value[0] > $value[1]) {
|
||||
$this->errors[] = Tools::displayError('The \'To\' value cannot be less than from value');
|
||||
if (isset($value[1]) && ($value[1] !== '' || $value[1] === 0)) {
|
||||
if (!Validate::$validation($value[1])) {
|
||||
$this->errors[] = Tools::displayError('The \'To\' value is invalid');
|
||||
} elseif ((isset($value[0]) && ($value[0] !== '' || $value[0] === 0)) && $value[0] > $value[1]) {
|
||||
$this->errors[] = Tools::displayError('The \'To\' value cannot be less than \'From\' value');
|
||||
} else {
|
||||
$sql_filter .= ' AND '.pSQL($key).' <= '.pSQL($value[1]);
|
||||
}
|
||||
@@ -925,7 +952,7 @@ class AdminControllerCore extends Controller
|
||||
if (!Validate::isDate($value[1])) {
|
||||
$this->errors[] = Tools::displayError('The \'To\' date format is invalid (YYYY-MM-DD)');
|
||||
} elseif (isset($value[0]) && !empty($value[0]) && strtotime($value[0]) > strtotime($value[1])) {
|
||||
$this->errors[] = Tools::displayError('The \'To\' date cannot be before than from date');
|
||||
$this->errors[] = Tools::displayError('The \'To\' date cannot be earlier than \'From\' date');
|
||||
} else {
|
||||
$sql_filter .= ' AND '.pSQL($key).' <= \''.pSQL(Tools::dateTo($value[1])).'\'';
|
||||
}
|
||||
@@ -2030,6 +2057,14 @@ class AdminControllerCore extends Controller
|
||||
'employee' => $this->context->employee,
|
||||
'search_type' => Tools::getValue('bo_search_type'),
|
||||
'bo_query' => Tools::safeOutput(Tools::stripslashes(Tools::getValue('bo_query'))),
|
||||
'QLO_SEARCH_TYPE_CATELOG' => self::QLO_SEARCH_TYPE_CATELOG,
|
||||
'QLO_SEARCH_TYPE_CUSTOMER_BY_NAME' => self::QLO_SEARCH_TYPE_CUSTOMER_BY_NAME,
|
||||
'QLO_SEARCH_TYPE_CUSTOMER_BY_IP' => self::QLO_SEARCH_TYPE_CUSTOMER_BY_IP,
|
||||
'QLO_SEARCH_TYPE_ORDER' => self::QLO_SEARCH_TYPE_ORDER,
|
||||
'QLO_SEARCH_TYPE_INVOICE' => self::QLO_SEARCH_TYPE_INVOICE,
|
||||
'QLO_SEARCH_TYPE_CART' => self::QLO_SEARCH_TYPE_CART,
|
||||
'QLO_SEARCH_TYPE_MODULE' => self::QLO_SEARCH_TYPE_MODULE,
|
||||
'QLO_SEARCH_TYPE_HOTEL' => self::QLO_SEARCH_TYPE_HOTEL,
|
||||
'quick_access' => $quick_access,
|
||||
'multi_shop' => Shop::isFeatureActive(),
|
||||
'shop_list' => $helperShop->getRenderedShopList(),
|
||||
@@ -2171,6 +2206,8 @@ class AdminControllerCore extends Controller
|
||||
*/
|
||||
protected function initTabModuleList()
|
||||
{
|
||||
$this->tab_modules_list = Tab::getTabModulesList($this->id);
|
||||
|
||||
if (is_array($this->tab_modules_list['default_list']) && count($this->tab_modules_list['default_list'])) {
|
||||
$this->filter_modules_list = $this->tab_modules_list['default_list'];
|
||||
} elseif (is_array($this->tab_modules_list['slider_list']) && count($this->tab_modules_list['slider_list'])) {
|
||||
@@ -2344,16 +2381,6 @@ class AdminControllerCore extends Controller
|
||||
//Force override translation key
|
||||
Context::getContext()->override_controller_name_for_translations = 'AdminModules';
|
||||
|
||||
$this->modals[] = array(
|
||||
'modal_id' => 'modal_addons_connect',
|
||||
'modal_class' => 'modal-md',
|
||||
'modal_title' => '<i class="icon-puzzle-piece"></i> <a target="_blank" href="http://addons.prestashop.com/'
|
||||
.'?utm_source=back-office&utm_medium=modules'
|
||||
.'&utm_campaign=back-office-'.Tools::strtoupper($this->context->language->iso_code)
|
||||
.'&utm_content='.(defined('_PS_HOST_MODE_') ? 'cloud' : 'download').'">PrestaShop Addons</a>',
|
||||
'modal_content' => $this->context->smarty->fetch('controllers/modules/login_addons.tpl'),
|
||||
);
|
||||
|
||||
//After override translation, remove it
|
||||
Context::getContext()->override_controller_name_for_translations = null;
|
||||
}
|
||||
@@ -4018,9 +4045,23 @@ class AdminControllerCore extends Controller
|
||||
$object = new $this->className((int)$id);
|
||||
$object->setFieldsToUpdate(array('active' => true));
|
||||
$object->active = (int)$status;
|
||||
$result &= $object->update();
|
||||
$isUpdated = (bool) $object->update();
|
||||
$result &= $isUpdated;
|
||||
|
||||
if (!$isUpdated) {
|
||||
$this->errors[] = sprintf($this->l('Can\'t update #%d status.'), (int) $id);
|
||||
}
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$this->redirect_after = self::$currentIndex.'&conf=5&token='.$this->token;
|
||||
} else {
|
||||
$this->errors[] = $this->l('An error occurred while updating the status.');
|
||||
}
|
||||
} else {
|
||||
$this->errors[] = $this->l('You must select at least one item to perform a bulk action.');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
@@ -221,6 +221,7 @@ class FrontControllerCore extends Controller
|
||||
'js_dir' => _THEME_JS_DIR_,
|
||||
'base_dir' => __PS_BASE_URI__,
|
||||
'language_code' => $this->context->language->language_code ? $this->context->language->language_code : $this->context->language->iso_code,
|
||||
'language_is_rtl' => $this->context->language->is_rtl,
|
||||
]);
|
||||
|
||||
/* get page name to display it in body id */
|
||||
@@ -795,6 +796,9 @@ class FrontControllerCore extends Controller
|
||||
'HOOK_MAINTENANCE' => Hook::exec('displayMaintenance', array()),
|
||||
'allowEmployee' => Configuration::get('PS_ALLOW_EMP'),
|
||||
'maintenance' => $this->context->link->getAdminLink('AdminMaintenance', false),
|
||||
'languages' => Language::getLanguages(true, $this->context->shop->id),
|
||||
'lang_iso' => $this->context->language->iso_code,
|
||||
'link' => $this->context->link,
|
||||
));
|
||||
// If the controller is a module, then getTemplatePath will try to find the template in the modules, so we need to instanciate a real frontcontroller
|
||||
$front_controller = preg_match('/ModuleFrontController$/', get_class($this)) ? new FrontController() : $this;
|
||||
@@ -917,8 +921,16 @@ class FrontControllerCore extends Controller
|
||||
}
|
||||
$excluded_key = array('isolang', 'id_lang', 'controller', 'fc', 'id_product', 'id_category', 'id_manufacturer', 'id_supplier', 'id_cms');
|
||||
foreach ($_GET as $key => $value) {
|
||||
if (!in_array($key, $excluded_key) && Validate::isUrl($key) && Validate::isUrl($value)) {
|
||||
$params[Tools::safeOutput($key)] = Tools::safeOutput($value);
|
||||
if (!in_array($key, $excluded_key)) {
|
||||
if (is_array($value)) {
|
||||
if (Validate::isUrl($key)) {
|
||||
$params[Tools::safeOutput($key)] = $this->sanitizeQueryOutput($value);
|
||||
}
|
||||
} else {
|
||||
if (Validate::isUrl($key) && Validate::isUrl($value)) {
|
||||
$params[Tools::safeOutput($key)] = Tools::safeOutput($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,6 +955,24 @@ class FrontControllerCore extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
protected function sanitizeQueryOutput($query)
|
||||
{
|
||||
$params = array();
|
||||
foreach ($query as $key => $value) {
|
||||
if (Validate::isUrl($key)) {
|
||||
if (is_array($value)) {
|
||||
$params[Tools::safeOutput($key)] = $this->sanitizeQueryOutput($value);
|
||||
} else {
|
||||
if (Validate::isUrl($value)) {
|
||||
$params[Tools::safeOutput($key)] = Tools::safeOutput($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Geolocation management
|
||||
*
|
||||
|
||||
@@ -660,23 +660,41 @@ class HelperListCore extends Helper
|
||||
$value = json_decode($value, true);
|
||||
}
|
||||
|
||||
if (isset($value[0]) && !Validate::isUnsignedInt($value[0])) {
|
||||
// set validation type
|
||||
if (isset($params['validation']) && $params['validation'] && method_exists('Validate', $params['validation'])) {
|
||||
$validation = $params['validation'];
|
||||
} else {
|
||||
$validation = 'isUnsignedInt';
|
||||
}
|
||||
|
||||
$hasValueFrom = isset($value[0]) && ($value[0] !== '' || $value[0] === 0);
|
||||
if ($hasValueFrom && !Validate::$validation($value[0])) {
|
||||
$value[0] = '';
|
||||
}
|
||||
if (isset($value[1]) && !Validate::isUnsignedInt($value[1])) {
|
||||
|
||||
$hasValueTo = isset($value[1]) && ($value[1] !== '' || $value[1] === 0);
|
||||
if ($hasValueTo && !Validate::$validation($value[1])) {
|
||||
$value[1] = '';
|
||||
}
|
||||
if (isset($value[0]) && isset($value[1]) && $value[0] > $value[1]) {
|
||||
|
||||
if ($hasValueFrom && $hasValueTo && $value[0] > $value[1]) {
|
||||
$value[1] = '';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
foreach ($params['list'] as $option_value => $option_display) {
|
||||
if (isset(Context::getContext()->cookie->{$prefix.$this->list_id.'Filter_'.$params['filter_key']})
|
||||
&& Context::getContext()->cookie->{$prefix.$this->list_id.'Filter_'.$params['filter_key']} == $option_value
|
||||
&& Context::getContext()->cookie->{$prefix.$this->list_id.'Filter_'.$params['filter_key']} != '') {
|
||||
$this->fields_list[$key]['select'][$option_value]['selected'] = 'selected';
|
||||
if (isset($params['multiple']) && $params['multiple']) {
|
||||
if (!isset($params['operator'])) {
|
||||
$params['operator'] = 'or';
|
||||
}
|
||||
$value = json_decode($value, true);
|
||||
} else {
|
||||
foreach ($params['list'] as $option_value => $option_display) {
|
||||
if (isset(Context::getContext()->cookie->{$prefix.$this->list_id.'Filter_'.$params['filter_key']})
|
||||
&& Context::getContext()->cookie->{$prefix.$this->list_id.'Filter_'.$params['filter_key']} == $option_value
|
||||
&& Context::getContext()->cookie->{$prefix.$this->list_id.'Filter_'.$params['filter_key']} != '') {
|
||||
$this->fields_list[$key]['select'][$option_value]['selected'] = 'selected';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -185,6 +185,10 @@ abstract class ModuleCore
|
||||
|
||||
public static $hosted_modules_blacklist = array('autoupgrade');
|
||||
|
||||
const OVERRIDE_TYPE_CORE = 1;
|
||||
const OVERRIDE_TYPE_MODULE = 2;
|
||||
const OVERRIDE_TYPE_MODULE_CONTROLLER = 3;
|
||||
|
||||
/**
|
||||
* Set the flag to indicate we are doing an import
|
||||
*
|
||||
@@ -2873,6 +2877,34 @@ abstract class ModuleCore
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getOverrides()
|
||||
{
|
||||
if (!is_dir($this->getLocalPath().'override')) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$overrides = array();
|
||||
foreach (Tools::scandir($this->getLocalPath().'override', 'php', '', true) as $file) {
|
||||
$class = basename($file, '.php');
|
||||
$classInfo = array('class' => $class, 'file' => $file, 'type' => null);
|
||||
if (PrestaShopAutoload::getInstance()->getClassPath($class.'Core')) {
|
||||
$classInfo['type'] = self::OVERRIDE_TYPE_CORE;
|
||||
} elseif (Module::getModuleIdByName($class)) {
|
||||
$classInfo['type'] = self::OVERRIDE_TYPE_MODULE;
|
||||
} elseif (preg_match('#^modules/([a-zA-Z0-9_-]+)/controllers/(admin|front)/([0-9a-zA-Z-_]+).php#', $file, $matches)) {
|
||||
$classInfo['type'] = self::OVERRIDE_TYPE_MODULE_CONTROLLER;
|
||||
$classInfo['module'] = $matches[1];
|
||||
$classInfo['controller_type'] = $matches[2];
|
||||
}
|
||||
|
||||
if ($classInfo['type']) {
|
||||
$overrides[] = $classInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return $overrides;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install overrides files for the module
|
||||
*
|
||||
@@ -2885,10 +2917,9 @@ abstract class ModuleCore
|
||||
}
|
||||
|
||||
$result = true;
|
||||
foreach (Tools::scandir($this->getLocalPath().'override', 'php', '', true) as $file) {
|
||||
$class = basename($file, '.php');
|
||||
if (PrestaShopAutoload::getInstance()->getClassPath($class.'Core') || Module::getModuleIdByName($class)) {
|
||||
$result &= $this->addOverride($class);
|
||||
if ($overrideClassInfos = $this->getOverrides()) {
|
||||
foreach ($overrideClassInfos as $classInfo) {
|
||||
$result &= $this->addOverride($classInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2907,10 +2938,9 @@ abstract class ModuleCore
|
||||
}
|
||||
|
||||
$result = true;
|
||||
foreach (Tools::scandir($this->getLocalPath().'override', 'php', '', true) as $file) {
|
||||
$class = basename($file, '.php');
|
||||
if (PrestaShopAutoload::getInstance()->getClassPath($class.'Core') || Module::getModuleIdByName($class)) {
|
||||
$result &= $this->removeOverride($class);
|
||||
if ($overrideClassInfos = $this->getOverrides()) {
|
||||
foreach ($overrideClassInfos as $classInfo) {
|
||||
$result &= $this->removeOverride($classInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2923,28 +2953,50 @@ abstract class ModuleCore
|
||||
* @param string $classname
|
||||
* @return bool
|
||||
*/
|
||||
public function addOverride($classname)
|
||||
public function addOverride($classInfo)
|
||||
{
|
||||
$orig_path = $path = PrestaShopAutoload::getInstance()->getClassPath($classname.'Core');
|
||||
if (!$path) {
|
||||
$path = 'modules'.DIRECTORY_SEPARATOR.$classname.DIRECTORY_SEPARATOR.$classname.'.php';
|
||||
}
|
||||
$path_override = $this->getLocalPath().'override'.DIRECTORY_SEPARATOR.$path;
|
||||
$classname = $classInfo['class'];
|
||||
|
||||
if (!file_exists($path_override)) {
|
||||
$parentClassFilePath = '';
|
||||
$overrideClassName = $classname;
|
||||
if ($classInfo['type'] == self::OVERRIDE_TYPE_CORE) {
|
||||
$parentClassFilePath = PrestaShopAutoload::getInstance()->getClassPath($classname.'Core');
|
||||
} elseif ($classInfo['type'] == self::OVERRIDE_TYPE_MODULE) {
|
||||
$parentClassFilePath = 'modules/'.$classname.'/'.$classname.'.php';
|
||||
|
||||
// require module main file
|
||||
require_once _PS_ROOT_DIR_.'/'.$parentClassFilePath;
|
||||
$overrideClassName = Tools::ucfirst($classname).'Override';
|
||||
} elseif ($classInfo['type'] == self::OVERRIDE_TYPE_MODULE_CONTROLLER) {
|
||||
$parentClassFilePath = $classInfo['file'];
|
||||
|
||||
// require module controller file
|
||||
require_once _PS_ROOT_DIR_.'/'.$parentClassFilePath;
|
||||
if ($classInfo['controller_type'] == 'admin') {
|
||||
$overrideClassName = $classname.((strpos($classname, 'Controller') === false) ? 'Controller' : '').'Override';
|
||||
} else {
|
||||
$overrideClassName = Tools::ucfirst($classInfo['module']).Tools::ucfirst($classInfo['class']).'ModuleFrontControllerOverride';
|
||||
}
|
||||
}
|
||||
|
||||
// the file in module which contains override information (methods, properties and constants)
|
||||
$moduleClassFilePath = $this->getLocalPath().'override/'.$parentClassFilePath;
|
||||
|
||||
if (!file_exists($moduleClassFilePath)) {
|
||||
return false;
|
||||
} else {
|
||||
file_put_contents($path_override, preg_replace('#(\r\n|\r)#ism', "\n", file_get_contents($path_override)));
|
||||
// save $moduleClassFilePath file with consistent newline character, "\n"
|
||||
file_put_contents($moduleClassFilePath, preg_replace('#(\r\n|\r)#ism', "\n", file_get_contents($moduleClassFilePath)));
|
||||
}
|
||||
|
||||
$pattern_escape_com = '#(^\s*?\/\/.*?\n|\/\*(?!\n\s+\* module:.*?\* date:.*?\* version:.*?\*\/).*?\*\/)#ism';
|
||||
// Check if there is already an override file, if not, we just need to copy the file
|
||||
if ($file = PrestaShopAutoload::getInstance()->getClassPath($classname)) {
|
||||
// Check if override file is writable
|
||||
$override_path = _PS_ROOT_DIR_.'/'.$file;
|
||||
$patternEscapeCommon = '#(^\s*?\/\/.*?\n|\/\*(?!\n\s+\* module:.*?\* date:.*?\* version:.*?\*\/).*?\*\/)#ism';
|
||||
|
||||
if ((!file_exists($override_path) && !is_writable(dirname($override_path))) || (file_exists($override_path) && !is_writable($override_path))) {
|
||||
throw new Exception(sprintf(Tools::displayError('file (%s) not writable'), $override_path));
|
||||
$overrideClassFilePath = _PS_ROOT_DIR_.'/override/'.$parentClassFilePath;
|
||||
// Case 1: Check if there is already an override file, if so, merge override information otherwise just copy it
|
||||
if (file_exists($overrideClassFilePath)) {
|
||||
// Check if override file is writable
|
||||
if (!is_writable(dirname($overrideClassFilePath)) || !is_writable($overrideClassFilePath)) {
|
||||
throw new Exception(sprintf(Tools::displayError('file (%s) not writable'), $overrideClassFilePath));
|
||||
}
|
||||
|
||||
// Get a uniq id for the class, because you can override a class (or remove the override) twice in the same session and we need to avoid redeclaration
|
||||
@@ -2953,262 +3005,340 @@ abstract class ModuleCore
|
||||
} while (class_exists($classname.'OverrideOriginal_remove', false));
|
||||
|
||||
// Make a reflection of the override class and the module override class
|
||||
$override_file = file($override_path);
|
||||
$override_file = array_diff($override_file, array("\n"));
|
||||
eval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+'.$classname.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'), array(' ', 'class '.$classname.'OverrideOriginal'.$uniq), implode('', $override_file)));
|
||||
$override_class = new ReflectionClass($classname.'OverrideOriginal'.$uniq);
|
||||
$overrideClassFileArray = file($overrideClassFilePath);
|
||||
$overrideClassFileArray = array_diff($overrideClassFileArray, array("\n")); // remove empty lines from array
|
||||
|
||||
$module_file = file($path_override);
|
||||
$module_file = array_diff($module_file, array("\n"));
|
||||
eval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+'.$classname.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array(' ', 'class '.$classname.'Override'.$uniq), implode('', $module_file)));
|
||||
$module_class = new ReflectionClass($classname.'Override'.$uniq);
|
||||
eval(
|
||||
preg_replace(
|
||||
array(
|
||||
'#^\s*<\?(?:php)?#',
|
||||
'#class\s+'.$overrideClassName.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'
|
||||
),
|
||||
array(
|
||||
' ',
|
||||
'class '.$overrideClassName.'OverrideOriginal'.$uniq
|
||||
),
|
||||
implode('', $overrideClassFileArray)
|
||||
)
|
||||
);
|
||||
$reflectionClassOverride = new ReflectionClass($overrideClassName.'OverrideOriginal'.$uniq);
|
||||
|
||||
// Check if none of the methods already exists in the override class
|
||||
foreach ($module_class->getMethods() as $method) {
|
||||
if ($override_class->hasMethod($method->getName())) {
|
||||
$method_override = $override_class->getMethod($method->getName());
|
||||
if (preg_match('/module: (.*)/ism', $override_file[$method_override->getStartLine() - 5], $name) && preg_match('/date: (.*)/ism', $override_file[$method_override->getStartLine() - 4], $date) && preg_match('/version: ([0-9.]+)/ism', $override_file[$method_override->getStartLine() - 3], $version)) {
|
||||
throw new Exception(sprintf(Tools::displayError('The method %1$s in the class %2$s is already overridden by the module %3$s version %4$s at %5$s.'), $method->getName(), $classname, $name[1], $version[1], $date[1]));
|
||||
}
|
||||
throw new Exception(sprintf(Tools::displayError('The method %1$s in the class %2$s is already overridden.'), $method->getName(), $classname));
|
||||
}
|
||||
$moduleClassFileArray = file($moduleClassFilePath);
|
||||
$moduleClassFileArray = array_diff($moduleClassFileArray, array("\n")); // remove empty lines from array
|
||||
|
||||
$module_file = preg_replace('/((:?public|private|protected)\s+(static\s+)?function\s+(?:\b'.$method->getName().'\b))/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1", $module_file);
|
||||
if ($module_file === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override method %1$s in class %2$s.'), $method->getName(), $classname));
|
||||
}
|
||||
}
|
||||
eval(
|
||||
preg_replace(
|
||||
array(
|
||||
'#^\s*<\?(?:php)?#',
|
||||
'#class\s+'.$overrideClassName.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'
|
||||
),
|
||||
array(
|
||||
' ',
|
||||
'class '.$overrideClassName.'Override'.$uniq
|
||||
),
|
||||
implode('', $moduleClassFileArray)
|
||||
)
|
||||
);
|
||||
$reflectionClassModule = new ReflectionClass($overrideClassName.'Override'.$uniq);
|
||||
|
||||
// Check if none of the properties already exists in the override class
|
||||
foreach ($module_class->getProperties() as $property) {
|
||||
if ($override_class->hasProperty($property->getName())) {
|
||||
throw new Exception(sprintf(Tools::displayError('The property %1$s in the class %2$s is already defined.'), $property->getName(), $classname));
|
||||
}
|
||||
|
||||
$module_file = preg_replace('/((?:public|private|protected)\s)\s*(static\s)?\s*(\$\b'.$property->getName().'\b)/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1$2$3", $module_file);
|
||||
if ($module_file === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override property %1$s in class %2$s.'), $property->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($module_class->getConstants() as $constant => $value) {
|
||||
if ($override_class->hasConstant($constant)) {
|
||||
throw new Exception(sprintf(Tools::displayError('The constant %1$s in the class %2$s is already defined.'), $constant, $classname));
|
||||
}
|
||||
|
||||
$module_file = preg_replace('/(const\s)\s*(\b'.$constant.'\b)/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1$2", $module_file);
|
||||
if ($module_file === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override constant %1$s in class %2$s.'), $constant, $classname));
|
||||
}
|
||||
}
|
||||
$moduleClassFileArray = $this->getCommentedClass($moduleClassFileArray, $reflectionClassModule, $reflectionClassOverride, $overrideClassFileArray);
|
||||
|
||||
// Insert the methods from module override in override
|
||||
$copy_from = array_slice($module_file, $module_class->getStartLine() + 1, $module_class->getEndLine() - $module_class->getStartLine() - 2);
|
||||
array_splice($override_file, $override_class->getEndLine() - 1, 0, $copy_from);
|
||||
$code = implode('', $override_file);
|
||||
$generatedCodeToCopy = array_slice($moduleClassFileArray, $reflectionClassModule->getStartLine() + 1, $reflectionClassModule->getEndLine() - $reflectionClassModule->getStartLine() - 2);
|
||||
|
||||
file_put_contents($override_path, preg_replace($pattern_escape_com, '', $code));
|
||||
// Merge code with that in destination override file
|
||||
array_splice($overrideClassFileArray, $reflectionClassOverride->getEndLine() - 1, 0, $generatedCodeToCopy);
|
||||
$code = implode('', $overrideClassFileArray);
|
||||
|
||||
file_put_contents($overrideClassFilePath, preg_replace($patternEscapeCommon, '', $code));
|
||||
} else {
|
||||
$override_src = $path_override;
|
||||
// Case 2: Override file does not exist just copy override information (methods, properties and constants)
|
||||
$baseDirectoryPath = dirname($overrideClassFilePath);
|
||||
|
||||
$override_dest = _PS_ROOT_DIR_.DIRECTORY_SEPARATOR.'override'.DIRECTORY_SEPARATOR.$path;
|
||||
$dir_name = dirname($override_dest);
|
||||
|
||||
if (!$orig_path && !is_dir($dir_name)) {
|
||||
// Check if directory exists, if not, create
|
||||
if (!is_dir($baseDirectoryPath)) {
|
||||
$oldumask = umask(0000);
|
||||
@mkdir($dir_name, 0777);
|
||||
@mkdir($baseDirectoryPath, 0777, true); // create subdirectories if needed
|
||||
umask($oldumask);
|
||||
}
|
||||
|
||||
if (!is_writable($dir_name)) {
|
||||
throw new Exception(sprintf(Tools::displayError('directory (%s) not writable'), $dir_name));
|
||||
}
|
||||
$module_file = file($override_src);
|
||||
$module_file = array_diff($module_file, array("\n"));
|
||||
|
||||
if ($orig_path) {
|
||||
do {
|
||||
$uniq = uniqid();
|
||||
} while (class_exists($classname.'OverrideOriginal_remove', false));
|
||||
eval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+'.$classname.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array(' ', 'class '.$classname.'Override'.$uniq), implode('', $module_file)));
|
||||
$module_class = new ReflectionClass($classname.'Override'.$uniq);
|
||||
|
||||
// For each method found in the override, prepend a comment with the module name and version
|
||||
foreach ($module_class->getMethods() as $method) {
|
||||
$module_file = preg_replace('/((:?public|private|protected)\s+(static\s+)?function\s+(?:\b'.$method->getName().'\b))/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1", $module_file);
|
||||
if ($module_file === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override method %1$s in class %2$s.'), $method->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
// Same loop for properties
|
||||
foreach ($module_class->getProperties() as $property) {
|
||||
$module_file = preg_replace('/((?:public|private|protected)\s)\s*(static\s)?\s*(\$\b'.$property->getName().'\b)/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1$2$3", $module_file);
|
||||
if ($module_file === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override property %1$s in class %2$s.'), $property->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
// Same loop for constants
|
||||
foreach ($module_class->getConstants() as $constant => $value) {
|
||||
$module_file = preg_replace('/(const\s)\s*(\b'.$constant.'\b)/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1$2", $module_file);
|
||||
if ($module_file === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override constant %1$s in class %2$s.'), $constant, $classname));
|
||||
}
|
||||
}
|
||||
if (!is_writable($baseDirectoryPath)) {
|
||||
throw new Exception(sprintf(Tools::displayError('directory (%s) not writable'), $baseDirectoryPath));
|
||||
}
|
||||
|
||||
file_put_contents($override_dest, preg_replace($pattern_escape_com, '', $module_file));
|
||||
$moduleClassFileArray = file($moduleClassFilePath); // read file as array
|
||||
$moduleClassFileArray = array_diff($moduleClassFileArray, array("\n")); // remove empty lines from array
|
||||
|
||||
do {
|
||||
$uniq = uniqid();
|
||||
} while (class_exists($classname.'OverrideOriginal_remove', false));
|
||||
|
||||
eval(
|
||||
preg_replace(
|
||||
array(
|
||||
'#^\s*<\?(?:php)?#',
|
||||
'#class\s+'.$overrideClassName.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'
|
||||
),
|
||||
array(
|
||||
' ',
|
||||
'class '.$overrideClassName.'Override'.$uniq
|
||||
),
|
||||
implode('', $moduleClassFileArray)
|
||||
)
|
||||
);
|
||||
$reflectionClassModule = new ReflectionClass($overrideClassName.'Override'.$uniq);
|
||||
|
||||
$moduleClassFileArray = $this->getCommentedClass($moduleClassFileArray, $reflectionClassModule);
|
||||
|
||||
file_put_contents($overrideClassFilePath, preg_replace($patternEscapeCommon, '', $moduleClassFileArray));
|
||||
|
||||
// Re-generate the class index
|
||||
Tools::generateIndex();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getCommentedClass($moduleClassFileArray, $reflectionClassModule, $reflectionClassOverride = null, $overrideClassFileArray = null)
|
||||
{
|
||||
// Check if none of the methods already exists in the override class
|
||||
foreach ($reflectionClassModule->getMethods() as $method) {
|
||||
if ($reflectionClassOverride) {
|
||||
if ($reflectionClassOverride->hasMethod($method->getName())) {
|
||||
$overrideMethodInfo = $reflectionClassOverride->getMethod($method->getName());
|
||||
if (preg_match('/module: (.*)/ism', $overrideClassFileArray[$overrideMethodInfo->getStartLine() - 5], $name) && preg_match('/date: (.*)/ism', $overrideClassFileArray[$overrideMethodInfo->getStartLine() - 4], $date) && preg_match('/version: ([0-9.]+)/ism', $overrideClassFileArray[$overrideMethodInfo->getStartLine() - 3], $version)) {
|
||||
throw new Exception(sprintf(Tools::displayError('The method %1$s in the class %2$s is already overridden by the module %3$s version %4$s at %5$s.'), $method->getName(), $classname, $name[1], $version[1], $date[1]));
|
||||
}
|
||||
throw new Exception(sprintf(Tools::displayError('The method %1$s in the class %2$s is already overridden.'), $method->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
$moduleClassFileArray = preg_replace('/((:?public|private|protected)\s+(static\s+)?function\s+(?:\b'.$method->getName().'\b))/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1", $moduleClassFileArray);
|
||||
if ($moduleClassFileArray === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override method %1$s in class %2$s.'), $method->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if none of the properties already exists in the override class
|
||||
foreach ($reflectionClassModule->getProperties() as $property) {
|
||||
if ($reflectionClassOverride) {
|
||||
if ($reflectionClassOverride->hasProperty($property->getName())) {
|
||||
throw new Exception(sprintf(Tools::displayError('The property %1$s in the class %2$s is already defined.'), $property->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
$moduleClassFileArray = preg_replace('/((?:public|private|protected)\s)\s*(static\s)?\s*(\$\b'.$property->getName().'\b)/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1$2$3", $moduleClassFileArray);
|
||||
if ($moduleClassFileArray === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override property %1$s in class %2$s.'), $property->getName(), $classname));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if none of the constants already exists in the override class
|
||||
foreach ($reflectionClassModule->getConstants() as $constant => $value) {
|
||||
if ($reflectionClassOverride) {
|
||||
if ($reflectionClassOverride->hasConstant($constant)) {
|
||||
throw new Exception(sprintf(Tools::displayError('The constant %1$s in the class %2$s is already defined.'), $constant, $classname));
|
||||
}
|
||||
}
|
||||
|
||||
$moduleClassFileArray = preg_replace('/(const\s)\s*(\b'.$constant.'\b)/ism', "/*\n * module: ".$this->name."\n * date: ".date('Y-m-d H:i:s')."\n * version: ".$this->version."\n */\n $1$2", $moduleClassFileArray);
|
||||
if ($moduleClassFileArray === null) {
|
||||
throw new Exception(sprintf(Tools::displayError('Failed to override constant %1$s in class %2$s.'), $constant, $classname));
|
||||
}
|
||||
}
|
||||
|
||||
return $moduleClassFileArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all methods in a module override from the override class
|
||||
*
|
||||
* @param string $classname
|
||||
* @return bool
|
||||
*/
|
||||
public function removeOverride($classname)
|
||||
public function removeOverride($classInfo)
|
||||
{
|
||||
$orig_path = $path = PrestaShopAutoload::getInstance()->getClassPath($classname.'Core');
|
||||
$classname = $classInfo['class'];
|
||||
|
||||
if ($orig_path && !$file = PrestaShopAutoload::getInstance()->getClassPath($classname)) {
|
||||
$parentClassFilePath = '';
|
||||
$overrideClassName = $classname;
|
||||
if ($classInfo['type'] == self::OVERRIDE_TYPE_CORE) {
|
||||
$parentClassFilePath = PrestaShopAutoload::getInstance()->getClassPath($classname.'Core');
|
||||
} elseif ($classInfo['type'] == self::OVERRIDE_TYPE_MODULE) {
|
||||
$parentClassFilePath = 'modules/'.$classname.'/'.$classname.'.php';
|
||||
|
||||
require_once _PS_ROOT_DIR_.'/'.$parentClassFilePath;
|
||||
$overrideClassName = Tools::ucfirst($classname).'Override';
|
||||
} elseif ($classInfo['type'] == self::OVERRIDE_TYPE_MODULE_CONTROLLER) {
|
||||
$parentClassFilePath = $classInfo['file'];
|
||||
|
||||
require_once _PS_ROOT_DIR_.'/'.$parentClassFilePath;
|
||||
if ($classInfo['controller_type'] == 'admin') {
|
||||
$overrideClassName = $classname.((strpos($classname, 'Controller') === false) ? 'Controller' : '').'Override';
|
||||
} else {
|
||||
$overrideClassName = Tools::ucfirst($classInfo['module']).Tools::ucfirst($classInfo['class']).'ModuleFrontControllerOverride';
|
||||
}
|
||||
}
|
||||
|
||||
$overrideClassFilePath = _PS_ROOT_DIR_.'/override/'.$parentClassFilePath;
|
||||
|
||||
// if override file does not exist return true
|
||||
if (!file_exists($overrideClassFilePath)) {
|
||||
return true;
|
||||
} elseif (!$orig_path && Module::getModuleIdByName($classname)) {
|
||||
$path = 'modules'.DIRECTORY_SEPARATOR.$classname.DIRECTORY_SEPARATOR.$classname.'.php';
|
||||
}
|
||||
|
||||
// Check if override file is writable
|
||||
if ($orig_path) {
|
||||
$override_path = _PS_ROOT_DIR_.'/'.$file;
|
||||
} else {
|
||||
$override_path = _PS_OVERRIDE_DIR_.$path;
|
||||
}
|
||||
|
||||
if (!is_file($override_path) || !is_writable($override_path)) {
|
||||
if (!is_file($overrideClassFilePath) || !is_writable($overrideClassFilePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file_put_contents($override_path, preg_replace('#(\r\n|\r)#ism', "\n", file_get_contents($override_path)));
|
||||
// save $overrideClassFilePath file with consistent newline character, "\n"
|
||||
file_put_contents($overrideClassFilePath, preg_replace('#(\r\n|\r)#ism', "\n", file_get_contents($overrideClassFilePath)));
|
||||
|
||||
if ($orig_path) {
|
||||
// Get a uniq id for the class, because you can override a class (or remove the override) twice in the same session and we need to avoid redeclaration
|
||||
do {
|
||||
$uniq = uniqid();
|
||||
} while (class_exists($classname.'OverrideOriginal_remove', false));
|
||||
// Get a uniq id for the class, because you can override a class (or remove the override) twice in the same session and we need to avoid redeclaration
|
||||
do {
|
||||
$uniq = uniqid();
|
||||
} while (class_exists($classname.'OverrideOriginal_remove', false));
|
||||
|
||||
// Make a reflection of the override class and the module override class
|
||||
$override_file = file($override_path);
|
||||
// Make a reflection of the override class and the module override class
|
||||
$overrideClassFileArray = file($overrideClassFilePath);
|
||||
$moduleClassFileArray = array_diff($moduleClassFileArray, array("\n")); // remove empty lines from array
|
||||
|
||||
eval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+'.$classname.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'), array(' ', 'class '.$classname.'OverrideOriginal_remove'.$uniq), implode('', $override_file)));
|
||||
$override_class = new ReflectionClass($classname.'OverrideOriginal_remove'.$uniq);
|
||||
eval(
|
||||
preg_replace(
|
||||
array(
|
||||
'#^\s*<\?(?:php)?#',
|
||||
'#class\s+'.$overrideClassName.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'
|
||||
),
|
||||
array(
|
||||
' ',
|
||||
'class '.$overrideClassName.'Original_remove'.$uniq
|
||||
),
|
||||
implode('', $overrideClassFileArray)
|
||||
)
|
||||
);
|
||||
$reflectionClassOverride = new ReflectionClass($overrideClassName.'Original_remove'.$uniq);
|
||||
|
||||
$module_file = file($this->getLocalPath().'override/'.$path);
|
||||
eval(preg_replace(array('#^\s*<\?(?:php)?#', '#class\s+'.$classname.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array(' ', 'class '.$classname.'Override_remove'.$uniq), implode('', $module_file)));
|
||||
$module_class = new ReflectionClass($classname.'Override_remove'.$uniq);
|
||||
$moduleClassFileArray = file($this->getLocalPath().'override/'.$parentClassFilePath);
|
||||
eval(
|
||||
preg_replace(
|
||||
array(
|
||||
'#^\s*<\?(?:php)?#',
|
||||
'#class\s+'.$overrideClassName.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'
|
||||
),
|
||||
array(
|
||||
' ',
|
||||
'class '.$overrideClassName.'Override_remove'.$uniq
|
||||
),
|
||||
implode('', $moduleClassFileArray)
|
||||
)
|
||||
);
|
||||
$reflectionClassModule = new ReflectionClass($overrideClassName.'Override_remove'.$uniq);
|
||||
|
||||
// Remove methods from override file
|
||||
foreach ($module_class->getMethods() as $method) {
|
||||
if (!$override_class->hasMethod($method->getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$method = $override_class->getMethod($method->getName());
|
||||
$length = $method->getEndLine() - $method->getStartLine() + 1;
|
||||
|
||||
$module_method = $module_class->getMethod($method->getName());
|
||||
$module_length = $module_method->getEndLine() - $module_method->getStartLine() + 1;
|
||||
|
||||
$override_file_orig = $override_file;
|
||||
|
||||
$orig_content = preg_replace('/\s/', '', implode('', array_splice($override_file, $method->getStartLine() - 1, $length, array_pad(array(), $length, '#--remove--#'))));
|
||||
$module_content = preg_replace('/\s/', '', implode('', array_splice($module_file, $module_method->getStartLine() - 1, $length, array_pad(array(), $length, '#--remove--#'))));
|
||||
|
||||
$replace = true;
|
||||
if (preg_match('/\* module: ('.$this->name.')/ism', $override_file[$method->getStartLine() - 5])) {
|
||||
$override_file[$method->getStartLine() - 6] = $override_file[$method->getStartLine() - 5] = $override_file[$method->getStartLine() - 4] = $override_file[$method->getStartLine() - 3] = $override_file[$method->getStartLine() - 2] = '#--remove--#';
|
||||
$replace = false;
|
||||
}
|
||||
|
||||
if (md5($module_content) != md5($orig_content) && $replace) {
|
||||
$override_file = $override_file_orig;
|
||||
}
|
||||
// Remove methods from override file
|
||||
foreach ($reflectionClassModule->getMethods() as $method) {
|
||||
if (!$reflectionClassOverride->hasMethod($method->getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove properties from override file
|
||||
foreach ($module_class->getProperties() as $property) {
|
||||
if (!$override_class->hasProperty($property->getName())) {
|
||||
continue;
|
||||
}
|
||||
$method = $reflectionClassOverride->getMethod($method->getName());
|
||||
$length = $method->getEndLine() - $method->getStartLine() + 1;
|
||||
|
||||
// Replace the declaration line by #--remove--#
|
||||
foreach ($override_file as $line_number => &$line_content) {
|
||||
if (preg_match('/(public|private|protected)\s+(static\s+)?(\$)?'.$property->getName().'/i', $line_content)) {
|
||||
if (preg_match('/\* module: ('.$this->name.')/ism', $override_file[$line_number - 4])) {
|
||||
$override_file[$line_number - 5] = $override_file[$line_number - 4] = $override_file[$line_number - 3] = $override_file[$line_number - 2] = $override_file[$line_number - 1] = '#--remove--#';
|
||||
}
|
||||
$line_content = '#--remove--#';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$moduleMethodInfo = $reflectionClassModule->getMethod($method->getName());
|
||||
|
||||
$overrideClassFileArrayOriginal = $overrideClassFileArray;
|
||||
|
||||
$overrideFileContent = preg_replace('/\s/', '', implode('', array_splice($overrideClassFileArray, $method->getStartLine() - 1, $length, array_pad(array(), $length, '#--remove--#'))));
|
||||
$moduleFileContent = preg_replace('/\s/', '', implode('', array_splice($moduleClassFileArray, $moduleMethodInfo->getStartLine() - 1, $length, array_pad(array(), $length, '#--remove--#'))));
|
||||
|
||||
$replace = true;
|
||||
if (preg_match('/\* module: ('.$this->name.')/ism', $overrideClassFileArray[$method->getStartLine() - 5])) {
|
||||
$overrideClassFileArray[$method->getStartLine() - 6] = $overrideClassFileArray[$method->getStartLine() - 5] = $overrideClassFileArray[$method->getStartLine() - 4] = $overrideClassFileArray[$method->getStartLine() - 3] = $overrideClassFileArray[$method->getStartLine() - 2] = '#--remove--#';
|
||||
$replace = false;
|
||||
}
|
||||
|
||||
// Remove properties from override file
|
||||
foreach ($module_class->getConstants() as $constant => $value) {
|
||||
if (!$override_class->hasConstant($constant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Replace the declaration line by #--remove--#
|
||||
foreach ($override_file as $line_number => &$line_content) {
|
||||
if (preg_match('/(const)\s+(static\s+)?(\$)?'.$constant.'/i', $line_content)) {
|
||||
if (preg_match('/\* module: ('.$this->name.')/ism', $override_file[$line_number - 4])) {
|
||||
$override_file[$line_number - 5] = $override_file[$line_number - 4] = $override_file[$line_number - 3] = $override_file[$line_number - 2] = $override_file[$line_number - 1] = '#--remove--#';
|
||||
}
|
||||
$line_content = '#--remove--#';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (md5($moduleFileContent) != md5($overrideFileContent) && $replace) {
|
||||
$overrideClassFileArray = $overrideClassFileArrayOriginal;
|
||||
}
|
||||
|
||||
$count = count($override_file);
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (preg_match('/(^\s*\/\/.*)/i', $override_file[$i])) {
|
||||
$override_file[$i] = '#--remove--#';
|
||||
} elseif (preg_match('/(^\s*\/\*)/i', $override_file[$i])) {
|
||||
if (!preg_match('/(^\s*\* module:)/i', $override_file[$i + 1])
|
||||
&& !preg_match('/(^\s*\* date:)/i', $override_file[$i + 2])
|
||||
&& !preg_match('/(^\s*\* version:)/i', $override_file[$i + 3])
|
||||
&& !preg_match('/(^\s*\*\/)/i', $override_file[$i + 4])) {
|
||||
for (; $override_file[$i] && !preg_match('/(.*?\*\/)/i', $override_file[$i]); ++$i) {
|
||||
$override_file[$i] = '#--remove--#';
|
||||
}
|
||||
$override_file[$i] = '#--remove--#';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite nice code
|
||||
$code = '';
|
||||
foreach ($override_file as $line) {
|
||||
if ($line == '#--remove--#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code .= $line;
|
||||
}
|
||||
|
||||
$to_delete = preg_match('/<\?(?:php)?\s+(?:abstract|interface)?\s*?class\s+'.$classname.'\s+extends\s+'.$classname.'Core\s*?[{]\s*?[}]/ism', $code);
|
||||
}
|
||||
|
||||
if (!isset($to_delete) || $to_delete) {
|
||||
unlink($override_path);
|
||||
// Remove properties from override file
|
||||
foreach ($reflectionClassModule->getProperties() as $property) {
|
||||
if (!$reflectionClassOverride->hasProperty($property->getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Replace the declaration line by #--remove--#
|
||||
foreach ($overrideClassFileArray as $lineNumber => &$line_content) {
|
||||
if (preg_match('/(public|private|protected)\s+(static\s+)?(\$)?'.$property->getName().'/i', $line_content)) {
|
||||
if (preg_match('/\* module: ('.$this->name.')/ism', $overrideClassFileArray[$lineNumber - 4])) {
|
||||
$overrideClassFileArray[$lineNumber - 5] = $overrideClassFileArray[$lineNumber - 4] = $overrideClassFileArray[$lineNumber - 3] = $overrideClassFileArray[$lineNumber - 2] = $overrideClassFileArray[$lineNumber - 1] = '#--remove--#';
|
||||
}
|
||||
$line_content = '#--remove--#';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove constants from override file
|
||||
foreach ($reflectionClassModule->getConstants() as $constant => $value) {
|
||||
if (!$reflectionClassOverride->hasConstant($constant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Replace the declaration line by #--remove--#
|
||||
foreach ($overrideClassFileArray as $lineNumber => &$line_content) {
|
||||
if (preg_match('/(const)\s+(static\s+)?(\$)?'.$constant.'/i', $line_content)) {
|
||||
if (preg_match('/\* module: ('.$this->name.')/ism', $overrideClassFileArray[$lineNumber - 4])) {
|
||||
$overrideClassFileArray[$lineNumber - 5] = $overrideClassFileArray[$lineNumber - 4] = $overrideClassFileArray[$lineNumber - 3] = $overrideClassFileArray[$lineNumber - 2] = $overrideClassFileArray[$lineNumber - 1] = '#--remove--#';
|
||||
}
|
||||
$line_content = '#--remove--#';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($overrideClassFileArray);
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
if (preg_match('/(^\s*\/\/.*)/i', $overrideClassFileArray[$i])) {
|
||||
$overrideClassFileArray[$i] = '#--remove--#';
|
||||
} elseif (preg_match('/(^\s*\/\*)/i', $overrideClassFileArray[$i])) {
|
||||
if (!preg_match('/(^\s*\* module:)/i', $overrideClassFileArray[$i + 1])
|
||||
&& !preg_match('/(^\s*\* date:)/i', $overrideClassFileArray[$i + 2])
|
||||
&& !preg_match('/(^\s*\* version:)/i', $overrideClassFileArray[$i + 3])
|
||||
&& !preg_match('/(^\s*\*\/)/i', $overrideClassFileArray[$i + 4])) {
|
||||
for (; $overrideClassFileArray[$i] && !preg_match('/(.*?\*\/)/i', $overrideClassFileArray[$i]); ++$i) {
|
||||
$overrideClassFileArray[$i] = '#--remove--#';
|
||||
}
|
||||
$overrideClassFileArray[$i] = '#--remove--#';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite nice code
|
||||
$code = '';
|
||||
foreach ($overrideClassFileArray as $line) {
|
||||
if ($line == '#--remove--#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code .= $line;
|
||||
}
|
||||
|
||||
// set regex for empty class to decide if override class must be deleted
|
||||
$emptyClassRegex = '/<\?(?:php)?\s+(?:abstract|interface)?\s*?class\s+'.$overrideClassName.'\s+extends\s+'.$classname.(($classInfo['type'] == self::OVERRIDE_TYPE_CORE) ? 'Core' : '').'\s*?[{]\s*?[}]/ism';
|
||||
if ($classInfo['type'] == self::OVERRIDE_TYPE_MODULE_CONTROLLER) {
|
||||
$emptyClassRegex = '/<\?(?:php)?\s+(?:abstract|interface)?\s*?class\s+'.$overrideClassName.'\s+extends\s+'.substr($overrideClassName, 0, -8).'\s*?[{]\s*?[}]/ism';
|
||||
}
|
||||
|
||||
$toDelete = preg_match($emptyClassRegex, $code);
|
||||
|
||||
if (!isset($toDelete) || $toDelete) {
|
||||
unlink($overrideClassFilePath);
|
||||
if ($classInfo['type'] == self::OVERRIDE_TYPE_MODULE_CONTROLLER) {
|
||||
$this->cleanModulesOverrideDir($overrideClassFilePath);
|
||||
}
|
||||
} else {
|
||||
file_put_contents($override_path, $code);
|
||||
file_put_contents($overrideClassFilePath, $code);
|
||||
}
|
||||
|
||||
// Re-generate the class index
|
||||
@@ -3217,6 +3347,21 @@ abstract class ModuleCore
|
||||
return true;
|
||||
}
|
||||
|
||||
private function cleanModulesOverrideDir($dir)
|
||||
{
|
||||
if (rtrim($dir, '/') == _PS_ROOT_DIR_.'/override/modules') {
|
||||
return;
|
||||
}
|
||||
|
||||
$files = Tools::scandir($dir, '');
|
||||
$diffResult = array_diff($files, array('.', '..', 'index.php'));
|
||||
|
||||
if (!count($diffResult)) {
|
||||
Tools::deleteDirectory($dir);
|
||||
$this->cleanModulesOverrideDir(dirname($dir));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hooks list where this module can be hooked.
|
||||
*
|
||||
|
||||
@@ -37,6 +37,8 @@ abstract class ModuleGraphCore extends Module
|
||||
/**@var array string graph titles */
|
||||
protected $_titles = array('main' => null, 'x' => null, 'y' => null);
|
||||
|
||||
protected $_formats = array('x' => null, 'y' => null);
|
||||
|
||||
/** @var ModuleGraphEngine graph engine */
|
||||
protected $_render;
|
||||
|
||||
@@ -258,6 +260,7 @@ abstract class ModuleGraphCore extends Module
|
||||
$this->_render->setSize($width, $height);
|
||||
$this->_render->setLegend($this->_legend);
|
||||
$this->_render->setTitles($this->_titles);
|
||||
$this->_render->setFormat($this->_formats);
|
||||
}
|
||||
|
||||
public function draw()
|
||||
|
||||
@@ -34,6 +34,14 @@ class OrderCore extends ObjectModel
|
||||
const ORDER_PAYMENT_TYPE_FULL = 1;
|
||||
const ORDER_PAYMENT_TYPE_ADVANCE = 2;
|
||||
|
||||
//Consts for: In the order list in which currency prices should be displayed
|
||||
const ORDER_LIST_PRICE_DISPLAY_IN_PAYMENT_CURRENCY = 1;
|
||||
const ORDER_LIST_PRICE_DISPLAY_IN_DEFAULT_CURRENCY = 2;
|
||||
|
||||
const ORDER_COMPLETE_REFUND_FLAG = 1;
|
||||
const ORDER_COMPLETE_CANCELLATION_FLAG = 2;
|
||||
const ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG = 3;
|
||||
|
||||
/** @var int Delivery address id */
|
||||
public $id_address_delivery;
|
||||
|
||||
@@ -1835,6 +1843,12 @@ class OrderCore extends ObjectModel
|
||||
}
|
||||
}
|
||||
|
||||
// Whenever payment is adding in any order then set a cumulative conversion rate for the payment currency in the order
|
||||
if ($avgConversionRate = $order_payment->getAverageConversionRate($this->reference, $this->id_currency)) {
|
||||
$this->conversion_rate = $avgConversionRate;
|
||||
}
|
||||
$this->save();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
@@ -1852,7 +1866,10 @@ class OrderCore extends ObjectModel
|
||||
if ($payment->id_currency == $this->id_currency) {
|
||||
$this->total_paid_real += $order_payment_detail->amount;
|
||||
} else {
|
||||
$this->total_paid_real += Tools::ps_round(Tools::convertPrice($order_payment_detail->amount, $payment->id_currency, false), 2);
|
||||
$this->total_paid_real += Tools::ps_round(
|
||||
Tools::convertPriceFull($order_payment_detail->amount, new Currency($payment->id_currency), new Currency($this->id_currency)),
|
||||
6
|
||||
);
|
||||
}
|
||||
|
||||
if (!validate::isPrice($this->total_paid_real)) {
|
||||
@@ -1891,18 +1908,18 @@ class OrderCore extends ObjectModel
|
||||
unset($invoices[$key]);
|
||||
}
|
||||
}
|
||||
$delivery_slips = $this->getDeliverySlipsCollection()->getResults();
|
||||
// @TODO review
|
||||
foreach ($delivery_slips as $key => $delivery) {
|
||||
$delivery->is_delivery = true;
|
||||
$delivery->date_add = $delivery->delivery_date;
|
||||
if (!$invoice->delivery_number) {
|
||||
unset($delivery_slips[$key]);
|
||||
}
|
||||
}
|
||||
// $delivery_slips = $this->getDeliverySlipsCollection()->getResults();
|
||||
// // @TODO review
|
||||
// foreach ($delivery_slips as $key => $delivery) {
|
||||
// $delivery->is_delivery = true;
|
||||
// $delivery->date_add = $delivery->delivery_date;
|
||||
// if (!$invoice->delivery_number) {
|
||||
// unset($delivery_slips[$key]);
|
||||
// }
|
||||
// }
|
||||
$order_slips = $this->getOrderSlipsCollection()->getResults();
|
||||
|
||||
$documents = array_merge($invoices, $order_slips, $delivery_slips);
|
||||
$documents = array_merge($invoices, $order_slips);
|
||||
usort($documents, array('Order', 'sortDocuments'));
|
||||
|
||||
return $documents;
|
||||
@@ -2534,12 +2551,12 @@ class OrderCore extends ObjectModel
|
||||
$order_ecotax_tax = Tools::ps_round($order_ecotax_tax, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode);
|
||||
|
||||
$tax_rounding_error = $expected_total_tax - $actual_total_tax - $order_ecotax_tax;
|
||||
if ($tax_rounding_error !== 0) {
|
||||
if ($tax_rounding_error != 0) {
|
||||
Tools::spreadAmount($tax_rounding_error, _PS_PRICE_COMPUTE_PRECISION_, $order_detail_tax_rows, 'total_amount');
|
||||
}
|
||||
|
||||
$base_rounding_error = $expected_total_base - $actual_total_base;
|
||||
if ($base_rounding_error !== 0) {
|
||||
if ($base_rounding_error != 0) {
|
||||
Tools::spreadAmount($base_rounding_error, _PS_PRICE_COMPUTE_PRECISION_, $order_detail_tax_rows, 'total_tax_base');
|
||||
}
|
||||
}
|
||||
@@ -2599,51 +2616,53 @@ class OrderCore extends ObjectModel
|
||||
return Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$id_cart);
|
||||
}
|
||||
|
||||
// Order is considered as refunded if all bookings are requested for refund and all are with refunded status
|
||||
// $refundFlag [ORDER_RETURN_STATE_FLAG_REFUNDED || ORDER_RETURN_STATE_FLAG_DENIED]
|
||||
public function hasCompletelyRefunded($refundFlag = 0)
|
||||
/**
|
||||
* Function to check if order has been completely refunded
|
||||
* @param integer action: can have 3 values as below
|
||||
* Order::ORDER_COMPLETE_REFUND_FLAG for complete refunded and
|
||||
* Order::ORDER_COMPLETE_CANCELLATION_FLAG for completely cancelled and
|
||||
* Order::ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG for all rooms are either cancelled or requested for refunded
|
||||
* @return boolean: true if order has been completely refunded as per requested parameters or false
|
||||
*/
|
||||
public function hasCompletelyRefunded($action = 0)
|
||||
{
|
||||
$objHotelBooking = new HotelBookingdetail();
|
||||
if ($refundBookings = OrderReturn::getOrdersReturnDetail($this->id)) {
|
||||
if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
|
||||
if (count($refundBookings) == count($orderBookings)) {
|
||||
if ($refundFlag) {
|
||||
foreach ($refundBookings as $refundRow) {
|
||||
if (Validate::isLoadedObject(
|
||||
$objReturnState = new OrderReturnState($refundRow['state']
|
||||
))) {
|
||||
if ($refundFlag == OrderReturnState::ORDER_RETURN_STATE_FLAG_REFUNDED
|
||||
&& !$objReturnState->refunded
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if ($refundFlag == OrderReturnState::ORDER_RETURN_STATE_FLAG_DENIED
|
||||
&& !$objReturnState->denied
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
|
||||
// If action is Order::ORDER_COMPLETE_REFUND_FLAG (for refunded) then we will check
|
||||
// that all rooms must be refunded and at least one booking is not cancelled
|
||||
if ($action == Order::ORDER_COMPLETE_REFUND_FLAG) {
|
||||
$uniqueRefundedBookings = array_unique(array_column($orderBookings, 'is_refunded'));
|
||||
if (count($uniqueRefundedBookings) == 1 && $uniqueRefundedBookings[0] == 1) {
|
||||
foreach ($orderBookings as $booking) {
|
||||
if ($booking['is_cancelled'] == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If action is Order::ORDER_COMPLETE_CANCELLATION_FLAG (for cancelled) then we will check that all rooms must be cancelled
|
||||
} elseif ($action == Order::ORDER_COMPLETE_CANCELLATION_FLAG) {
|
||||
$uniqueRefundedBookings = array_unique(array_column($orderBookings, 'is_cancelled'));
|
||||
if (count($uniqueRefundedBookings) == 1 && $uniqueRefundedBookings[0] == 1) {
|
||||
return true;
|
||||
}
|
||||
// If action is Order::ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG (for cancelled and refund requests) then we will check that all rooms are either cancelled or requested for refund
|
||||
} elseif ($action == Order::ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG) {
|
||||
foreach ($orderBookings as $booking) {
|
||||
if (!$booking['is_refunded']) {
|
||||
if (!OrderReturn::getOrdersReturnDetail($this->id, 0, $booking['id'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
// Default process to check if order is fully refunded or cancelled or not
|
||||
} else {
|
||||
// if is_refunded is 1 means booking either is cancelled or refunded. So check all bookings must have is_refunded = 1
|
||||
$uniqueRefundedBookings = array_unique(array_column($orderBookings, 'is_refunded'));
|
||||
if (count($uniqueRefundedBookings) == 1 && $uniqueRefundedBookings[0] == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} elseif ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
|
||||
if (count(array_unique(array_column($orderBookings, 'is_cancelled'))) === 1
|
||||
&& array_unique(array_column($orderBookings, 'is_cancelled'))[0] != 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Order is considered as denied if all bookings are requested for refund and all are with denied status
|
||||
public function orderRefundHasBeenDenied()
|
||||
{
|
||||
if (OrderReturn::getOrdersReturn($this->id_customer, $this->id)) {
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2660,4 +2679,4 @@ class OrderCore extends ObjectModel
|
||||
{
|
||||
$this->transaction_id = $transactionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,6 @@ class OrderHistoryCore extends ObjectModel
|
||||
|
||||
// set orders as paid
|
||||
if ($new_os->paid == 1) {
|
||||
$invoices = $order->getInvoicesCollection();
|
||||
if ($order->total_paid != 0) {
|
||||
// if order is created by API then create a direct object instead of creating an object from module
|
||||
if ($order->module == 'wsorder') {
|
||||
@@ -323,22 +322,43 @@ class OrderHistoryCore extends ObjectModel
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
/** @var OrderInvoice $invoice */
|
||||
$rest_paid = $invoice->getRestPaid();
|
||||
// if order has invoices then create payment entry for all the invoices
|
||||
if ($invoices = $order->getInvoicesCollection()->getResults()) {
|
||||
foreach ($invoices as $invoice) {
|
||||
/** @var OrderInvoice $invoice */
|
||||
$rest_paid = $invoice->getRestPaid();
|
||||
if ($rest_paid > 0) {
|
||||
if ($order->total_paid != 0) {
|
||||
$payment_method = $payment_method->displayName;
|
||||
} else {
|
||||
$payment_method = null;
|
||||
}
|
||||
$order->addOrderPayment(
|
||||
$rest_paid,
|
||||
$payment_method,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$invoice
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$rest_paid = $order->total_paid_tax_incl - $order->total_paid_real;
|
||||
if ($rest_paid > 0) {
|
||||
if ($order->total_paid != 0) {
|
||||
$payment_method = $payment_method->displayName;
|
||||
} else {
|
||||
$payment_method = null;
|
||||
}
|
||||
|
||||
$order->addOrderPayment(
|
||||
$rest_paid,
|
||||
$payment_method,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$invoice
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -420,11 +440,29 @@ class OrderHistoryCore extends ObjectModel
|
||||
'{firstname}' => $result['firstname'],
|
||||
'{id_order}' => (int)$this->id_order,
|
||||
'{order_name}' => $order->getUniqReference(),
|
||||
'{total_paid_real}' => Tools::displayPrice($order->total_paid_real, (int)$order->id_currency),
|
||||
'{is_advance_payment}' => $order->is_advance_payment,
|
||||
'{advance_paid_amount}' => Tools::displayPrice($order->advance_paid_amount, (int)$order->id_currency),
|
||||
'{extra_mail_content_html}' => '',
|
||||
'{extra_mail_content_txt}' => '',
|
||||
'{payment_method}' => '',
|
||||
);
|
||||
|
||||
if ($idHotel = HotelBookingDetail::getIdHotelByIdOrder($order->id)) {
|
||||
$objHotelBranchInformation = new HotelBranchInformation($idHotel, $order->id_lang);
|
||||
$fields = array_merge(
|
||||
$objHotelBranchInformation->getFields(),
|
||||
$objHotelBranchInformation->getFieldsLang()[$order->id_lang],
|
||||
$objHotelBranchInformation->getAddress($idHotel, $order->id_lang)
|
||||
);
|
||||
foreach ($fields as $key => $value) {
|
||||
$data['{hotel_'.$key.'}'] = $value;
|
||||
}
|
||||
$objHotelBookingDetail = new HotelBookingDetail();
|
||||
$hotelBookingDetail = $objHotelBookingDetail->getBookingDataByOrderId($order->id);
|
||||
$data['{num_rooms}'] = count($hotelBookingDetail);
|
||||
}
|
||||
|
||||
if ($result['module_name']) {
|
||||
if (Validate::isLoadedObject($module = Module::getInstanceByName($result['module_name']))) {
|
||||
$data['{payment_method}'] = $module->displayName;
|
||||
|
||||
@@ -443,23 +443,27 @@ class OrderInvoiceCore extends ObjectModel
|
||||
$details = $grouped_details;
|
||||
}
|
||||
foreach ($details as $row) {
|
||||
$rate = sprintf('%.3f', $row['tax_rate']);
|
||||
if (!isset($breakdown[$rate])) {
|
||||
$breakdown[$rate] = array(
|
||||
if (!$sum_composite_taxes) {
|
||||
$key = $row['id_tax'];
|
||||
} else {
|
||||
$key = sprintf('%.3f', $row['tax_rate']);
|
||||
}
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' => $rate,
|
||||
'rate' => sprintf('%.3f', $row['tax_rate']),
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown[$rate]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$rate]['total_amount'] += $row['total_amount'];
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
|
||||
foreach ($breakdown as $rate => $data) {
|
||||
$breakdown[$rate]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$rate]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
foreach ($breakdown as $key => $data) {
|
||||
$breakdown[$key]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$key]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
}
|
||||
|
||||
ksort($breakdown);
|
||||
@@ -503,23 +507,27 @@ class OrderInvoiceCore extends ObjectModel
|
||||
$details = $grouped_details;
|
||||
}
|
||||
foreach ($details as $row) {
|
||||
$rate = sprintf('%.3f', $row['tax_rate']);
|
||||
if (!isset($breakdown[$rate])) {
|
||||
$breakdown[$rate] = array(
|
||||
if (!$sum_composite_taxes) {
|
||||
$key = $row['id_tax'];
|
||||
} else {
|
||||
$key = sprintf('%.3f', $row['tax_rate']);
|
||||
}
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' => $rate,
|
||||
'rate' => sprintf('%.3f', $row['tax_rate']),
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown[$rate]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$rate]['total_amount'] += $row['total_amount'];
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
|
||||
foreach ($breakdown as $rate => $data) {
|
||||
$breakdown[$rate]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$rate]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
foreach ($breakdown as $key => $data) {
|
||||
$breakdown[$key]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$key]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
}
|
||||
|
||||
ksort($breakdown);
|
||||
@@ -569,23 +577,27 @@ class OrderInvoiceCore extends ObjectModel
|
||||
}
|
||||
|
||||
foreach ($details as $row) {
|
||||
$rate = sprintf('%.3f', $row['tax_rate']);
|
||||
if (!isset($breakdown[$rate])) {
|
||||
$breakdown[$rate] = array(
|
||||
if (!$sum_composite_taxes) {
|
||||
$key = $row['id_tax'];
|
||||
} else {
|
||||
$key = sprintf('%.3f', $row['tax_rate']);
|
||||
}
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' => $rate,
|
||||
'rate' => sprintf('%.3f', $row['tax_rate']),
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown[$rate]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$rate]['total_amount'] += $row['total_amount'];
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
|
||||
foreach ($breakdown as $rate => $data) {
|
||||
$breakdown[$rate]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$rate]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
foreach ($breakdown as $key => $data) {
|
||||
$breakdown[$key]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$key]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
}
|
||||
|
||||
ksort($breakdown);
|
||||
@@ -629,23 +641,27 @@ class OrderInvoiceCore extends ObjectModel
|
||||
$details = $grouped_details;
|
||||
}
|
||||
foreach ($details as $row) {
|
||||
$rate = sprintf('%.3f', $row['tax_rate']);
|
||||
if (!isset($breakdown[$rate])) {
|
||||
$breakdown[$rate] = array(
|
||||
if (!$sum_composite_taxes) {
|
||||
$key = $row['id_tax'];
|
||||
} else {
|
||||
$key = sprintf('%.3f', $row['tax_rate']);
|
||||
}
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' => $rate,
|
||||
'rate' => $key,
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown[$rate]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$rate]['total_amount'] += $row['total_amount'];
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
|
||||
foreach ($breakdown as $rate => $data) {
|
||||
$breakdown[$rate]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$rate]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
foreach ($breakdown as $key => $data) {
|
||||
$breakdown[$key]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
$breakdown[$key]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $order->round_mode);
|
||||
}
|
||||
|
||||
ksort($breakdown);
|
||||
@@ -693,17 +709,18 @@ class OrderInvoiceCore extends ObjectModel
|
||||
}
|
||||
} else {
|
||||
foreach ($details as $row) {
|
||||
$key = $row['id_tax'];
|
||||
$rate = sprintf('%.3f', $row['rate']);
|
||||
if (!isset($breakdown[$rate])) {
|
||||
$breakdown[$rate] = array(
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' =>$rate,
|
||||
'rate' => $rate,
|
||||
);
|
||||
}
|
||||
$breakdown[$rate]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$rate]['total_amount'] += $row['total_amount'];
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
}
|
||||
foreach ($breakdown as $rate => $data) {
|
||||
@@ -887,9 +904,11 @@ class OrderInvoiceCore extends ObjectModel
|
||||
SELECT oi.*
|
||||
FROM `'._DB_PREFIX_.'order_invoice` oi
|
||||
LEFT JOIN `'._DB_PREFIX_.'orders` o ON (o.`id_order` = oi.`id_order`)
|
||||
INNER JOIN `'._DB_PREFIX_.'htl_booking_detail` hbd ON (oi.id_order = hbd.id_order)
|
||||
WHERE DATE_ADD(oi.date_add, INTERVAL -1 DAY) <= \''.pSQL($date_to).'\'
|
||||
AND oi.date_add >= \''.pSQL($date_from).'\'
|
||||
'.Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o').'
|
||||
'.Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o')
|
||||
.HotelBranchInformation::addHotelRestriction(false, 'hbd').'
|
||||
AND oi.number > 0
|
||||
ORDER BY oi.date_add ASC
|
||||
');
|
||||
@@ -908,8 +927,10 @@ class OrderInvoiceCore extends ObjectModel
|
||||
SELECT oi.*
|
||||
FROM `'._DB_PREFIX_.'order_invoice` oi
|
||||
LEFT JOIN `'._DB_PREFIX_.'orders` o ON (o.`id_order` = oi.`id_order`)
|
||||
INNER JOIN `'._DB_PREFIX_.'htl_booking_detail` hbd ON (oi.id_order = hbd.id_order)
|
||||
WHERE '.(int)$id_order_state.' = o.current_state
|
||||
'.Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o').'
|
||||
'.Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o')
|
||||
.HotelBranchInformation::addHotelRestriction(false, 'hbd').'
|
||||
AND oi.number > 0
|
||||
ORDER BY oi.`date_add` ASC
|
||||
');
|
||||
|
||||
@@ -148,4 +148,15 @@ class OrderPaymentCore extends ObjectModel
|
||||
|
||||
return new OrderInvoice((int)$res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the average conversion rate for a given order in any currency
|
||||
* @param [string] $order_reference
|
||||
* @param [int] $idCurrency
|
||||
* @return float
|
||||
*/
|
||||
public function getAverageConversionRate($order_reference, $idCurrency)
|
||||
{
|
||||
return Db::getInstance()->getValue('SELECT (SUM(`amount` * `conversion_rate`) / SUM(`amount`)) FROM `'._DB_PREFIX_.'order_payment` WHERE `order_reference` = \''.pSQL($order_reference).'\' AND `id_currency` = '.(int)$idCurrency);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,8 @@ class OrderReturnCore extends ObjectModel
|
||||
public function hasBeenCompleted()
|
||||
{
|
||||
if (Validate::isLoadedObject($objReturnState = new OrderReturnState($this->state))) {
|
||||
if ($objReturnState->denied || $objReturnState->refunded) {
|
||||
// refund process will be considered as completed when the state is "Refunded"
|
||||
if ($objReturnState->refunded) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -510,29 +511,31 @@ class OrderReturnCore extends ObjectModel
|
||||
|
||||
// send mail to the super admin
|
||||
if ($objOrderReturnState->send_email_to_superadmin) {
|
||||
// send superadmin information
|
||||
if (Validate::isLoadedObject($superAdmin = new Employee(_PS_ADMIN_PROFILE_))) {
|
||||
if (Validate::isEmail($superAdmin->email)) {
|
||||
$data['{customer_name}'] = $objCustomer->firstname.' '.$objCustomer->lastname;
|
||||
$data['{customer_email}'] = $objCustomer->email;
|
||||
$data['{firstname}'] = $superAdmin->firstname;
|
||||
$data['{lastname}'] = $superAdmin->lastname;
|
||||
// Get all the employees with super admin profile
|
||||
if ($superAdminEmployees = Employee::getEmployeesByProfile(_PS_ADMIN_PROFILE_, true)) {
|
||||
foreach ($superAdminEmployees as $superAdminEmployee) {
|
||||
if (Validate::isEmail($superAdminEmployee['email'])) {
|
||||
$data['{customer_name}'] = $objCustomer->firstname.' '.$objCustomer->lastname;
|
||||
$data['{customer_email}'] = $objCustomer->email;
|
||||
$data['{firstname}'] = $superAdminEmployee['firstname'];
|
||||
$data['{lastname}'] = $superAdminEmployee['lastname'];
|
||||
|
||||
Mail::Send(
|
||||
(int)$idLang,
|
||||
$objOrderReturnState->admin_template,
|
||||
$objOrderReturnState->name,
|
||||
$data,
|
||||
$superAdmin->email,
|
||||
$superAdmin->firstname.' '.$superAdmin->lastname,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
_PS_MAIL_DIR_,
|
||||
false,
|
||||
(int)$objOrder->id_shop
|
||||
);
|
||||
Mail::Send(
|
||||
(int)$idLang,
|
||||
$objOrderReturnState->admin_template,
|
||||
$objOrderReturnState->name,
|
||||
$data,
|
||||
$superAdminEmployee['email'],
|
||||
$superAdminEmployee['firstname'].' '.$superAdminEmployee['lastname'],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
_PS_MAIL_DIR_,
|
||||
false,
|
||||
(int)$objOrder->id_shop
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -570,7 +573,7 @@ class OrderReturnCore extends ObjectModel
|
||||
$data['{customer_name}'] = $objCustomer->firstname.' '.$objCustomer->lastname;
|
||||
$data['{customer_email}'] = $objCustomer->email;
|
||||
foreach ($htlAccesses as $access) {
|
||||
if ($access['id_profile'] != _PS_ADMIN_PROFILE_) {
|
||||
if ($access['access'] && $access['id_profile'] != _PS_ADMIN_PROFILE_) {
|
||||
if ($htlEmployees = Employee::getEmployeesByProfile($access['id_profile'])) {
|
||||
foreach ($htlEmployees as $empl) {
|
||||
if (Validate::isEmail($empl['email'])) {
|
||||
|
||||
@@ -100,10 +100,10 @@ abstract class HTMLTemplateCore
|
||||
|
||||
$id_shop = (int)$this->shop->id;
|
||||
|
||||
if (Configuration::get('PS_LOGO_INVOICE', null, null, $id_shop) != false && file_exists(_PS_IMG_DIR_.Configuration::get('PS_LOGO_INVOICE', null, null, $id_shop))) {
|
||||
$logo = _PS_IMG_DIR_.Configuration::get('PS_LOGO_INVOICE', null, null, $id_shop);
|
||||
} elseif (Configuration::get('PS_LOGO', null, null, $id_shop) != false && file_exists(_PS_IMG_DIR_.Configuration::get('PS_LOGO', null, null, $id_shop))) {
|
||||
$logo = _PS_IMG_DIR_.Configuration::get('PS_LOGO', null, null, $id_shop);
|
||||
if (Configuration::get('PS_LOGO_INVOICE', null, null, $id_shop) != false) {
|
||||
$logo = Context::getContext()->link->getMediaLink(_PS_IMG_.Configuration::get('PS_LOGO_INVOICE', null, null, $id_shop));
|
||||
} elseif (Configuration::get('PS_LOGO', null, null, $id_shop) != false) {
|
||||
$logo = Context::getContext()->link->getMediaLink(_PS_IMG_.Configuration::get('PS_LOGO', null, null, $id_shop));
|
||||
}
|
||||
return $logo;
|
||||
}
|
||||
|
||||
@@ -353,10 +353,8 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate
|
||||
} else {
|
||||
$order_bk_data = $obj_htl_bk_dtl->getOnlyOrderBookingData($this->order->id, $customer->id_guest, $type_value['product_id']);
|
||||
}
|
||||
$rm_dtl = $obj_rm_type->getRoomTypeInfoByIdProduct($type_value['product_id']);
|
||||
|
||||
$cart_htl_data[$type_key]['id_product'] = $type_value['product_id'];
|
||||
$cart_htl_data[$type_key]['hotel_name'] = $rm_dtl['hotel_name'];
|
||||
$objBookingDemand = new HotelBookingDemands();
|
||||
foreach ($order_bk_data as $data_k => $data_v) {
|
||||
$date_join = strtotime($data_v['date_from']).strtotime($data_v['date_to']);
|
||||
@@ -368,6 +366,7 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate
|
||||
$unit_price_tax_excl = $order_details_obj->unit_price_tax_excl;
|
||||
$unit_price_tax_incl = $order_details_obj->unit_price_tax_incl;
|
||||
|
||||
$cart_htl_data[$type_key]['hotel_name'] = $data_v['hotel_name'];
|
||||
$cart_htl_data[$type_key]['name'] = $order_details_obj->product_name;
|
||||
$cart_htl_data[$type_key]['unit_price_tax_excl'] = $unit_price_tax_excl;
|
||||
$cart_htl_data[$type_key]['unit_price_tax_incl'] = $unit_price_tax_incl;
|
||||
@@ -634,7 +633,6 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate
|
||||
'tax_excluded_display' => $tax_excluded_display,
|
||||
'display_product_images' => $display_product_images,
|
||||
'layout' => $layout,
|
||||
'tax_tab' => $this->getTaxTabContent(),
|
||||
'customer' => $customer,
|
||||
'footer' => $footer,
|
||||
'ps_price_compute_precision' => _PS_PRICE_COMPUTE_PRECISION_,
|
||||
|
||||
@@ -200,8 +200,6 @@ class HTMLTemplateOrderSlipCore extends HTMLTemplateInvoice
|
||||
{
|
||||
$address = new Address((int)$this->order->id_address_tax);
|
||||
$this->smarty->assign(array(
|
||||
'product_tax_breakdown' => $this->getProductTaxesBreakdown(),
|
||||
'shipping_tax_breakdown' => $this->getShippingTaxesBreakdown(),
|
||||
'order' => $this->order,
|
||||
'ecotax_tax_breakdown' => $this->order_slip->getEcoTaxTaxesBreakdown(),
|
||||
'is_order_slip' => true,
|
||||
@@ -220,7 +218,7 @@ class HTMLTemplateOrderSlipCore extends HTMLTemplateInvoice
|
||||
protected function getTaxBreakdown()
|
||||
{
|
||||
$breakdowns = array(
|
||||
'product_tax' => $this->getProductTaxesBreakdown(),
|
||||
'room_tax' => $this->getRoomTypeTaxesBreakdown(),
|
||||
'shipping_tax' => $this->getShippingTaxesBreakdown(),
|
||||
'ecotax_tax' => $this->order_slip->getEcoTaxTaxesBreakdown(),
|
||||
);
|
||||
@@ -251,33 +249,78 @@ class HTMLTemplateOrderSlipCore extends HTMLTemplateInvoice
|
||||
return $breakdowns;
|
||||
}
|
||||
|
||||
public function getProductTaxesBreakdown()
|
||||
public function useOneAfterAnotherTaxComputationMethod()
|
||||
{
|
||||
// if one of the order details use the tax computation method the display will be different
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT od.`tax_computation_method`
|
||||
FROM `' . _DB_PREFIX_ . 'order_detail_tax` odt
|
||||
LEFT JOIN `' . _DB_PREFIX_ . 'order_detail` od ON (od.`id_order_detail` = odt.`id_order_detail`)
|
||||
WHERE od.`id_order` = ' . (int) $this->order->id_order . '
|
||||
AND od.`tax_computation_method` = ' . (int) TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
|
||||
|| Configuration::get('PS_INVOICE_TAXES_BREAKDOWN');
|
||||
}
|
||||
|
||||
public function getRoomTypeTaxesBreakdown()
|
||||
{
|
||||
$sum_composite_taxes = !$this->useOneAfterAnotherTaxComputationMethod();
|
||||
|
||||
// $breakdown will be an array with tax rates as keys and at least the columns:
|
||||
// - 'total_price_tax_excl'
|
||||
// - 'total_amount'
|
||||
$breakdown = array();
|
||||
|
||||
$details = $this->order->getProductTaxesDetails($this->order->products);
|
||||
$order_detail = array_filter($this->order->products, function($v) {
|
||||
return ($v['is_booking_product']
|
||||
|| ($v['product_auto_add']
|
||||
&& $v['product_service_type'] == Product::SERVICE_PRODUCT_WITH_ROOMTYPE
|
||||
&& $v['product_price_addition_type'] == ProductCore::PRICE_ADDITION_TYPE_WITH_ROOM)
|
||||
);
|
||||
});
|
||||
|
||||
$details = $this->order->getProductTaxesDetails($order_detail);
|
||||
|
||||
if ($sum_composite_taxes) {
|
||||
$grouped_details = array();
|
||||
foreach ($details as $row) {
|
||||
if (!isset($grouped_details[$row['id_order_detail']])) {
|
||||
$grouped_details[$row['id_order_detail']] = array(
|
||||
'tax_rate' => 0,
|
||||
'total_tax_base' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
);
|
||||
}
|
||||
|
||||
$grouped_details[$row['id_order_detail']]['tax_rate'] += $row['tax_rate'];
|
||||
$grouped_details[$row['id_order_detail']]['total_tax_base'] += $row['total_tax_base'];
|
||||
$grouped_details[$row['id_order_detail']]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
$details = $grouped_details;
|
||||
}
|
||||
|
||||
foreach ($details as $row) {
|
||||
$rate = sprintf('%.3f', $row['tax_rate']);
|
||||
if (!isset($breakdown[$rate])) {
|
||||
$breakdown[$rate] = array(
|
||||
if (!$sum_composite_taxes) {
|
||||
$key = $row['id_tax'];
|
||||
} else {
|
||||
$key = sprintf('%.3f', $row['tax_rate']);
|
||||
}
|
||||
if (!isset($breakdown[$key])) {
|
||||
$breakdown[$key] = array(
|
||||
'total_price_tax_excl' => 0,
|
||||
'total_amount' => 0,
|
||||
'id_tax' => $row['id_tax'],
|
||||
'rate' =>$rate,
|
||||
'rate' => sprintf('%.3f', $row['tax_rate']),
|
||||
);
|
||||
}
|
||||
|
||||
$breakdown[$rate]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$rate]['total_amount'] += $row['total_amount'];
|
||||
$breakdown[$key]['total_price_tax_excl'] += $row['total_tax_base'];
|
||||
$breakdown[$key]['total_amount'] += $row['total_amount'];
|
||||
}
|
||||
|
||||
foreach ($breakdown as $rate => $data) {
|
||||
$breakdown[$rate]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $this->order->round_mode);
|
||||
$breakdown[$rate]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $this->order->round_mode);
|
||||
foreach ($breakdown as $key => $data) {
|
||||
$breakdown[$key]['total_price_tax_excl'] = Tools::ps_round($data['total_price_tax_excl'], _PS_PRICE_COMPUTE_PRECISION_, $this->order->round_mode);
|
||||
$breakdown[$key]['total_amount'] = Tools::ps_round($data['total_amount'], _PS_PRICE_COMPUTE_PRECISION_, $this->order->round_mode);
|
||||
}
|
||||
|
||||
ksort($breakdown);
|
||||
|
||||
@@ -521,6 +521,7 @@ class WebserviceSpecificManagementImagesCore implements WebserviceSpecificManage
|
||||
$ids[] = $image['id_hotel'];
|
||||
}
|
||||
$ids = array_unique($ids, SORT_NUMERIC);
|
||||
asort($ids);
|
||||
foreach ($ids as $id) {
|
||||
$this->output .= $this->objOutput->getObjectRender()->renderNodeHeader('image', array(), array('id' => $id, 'xlink_resource'=>$this->wsObject->wsUrl.'images/'.'hotels'.'/'.$id), false);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,8 @@ function smartyTranslate($params, $smarty)
|
||||
}
|
||||
|
||||
// If the tpl is used by a Helper
|
||||
if (strpos($filename, 'helpers') === 0) {
|
||||
$className = isset(Context::getContext()->controller->controller_name) ? Tools::toUnderscoreCase(substr(Context::getContext()->controller->controller_name, 5)) : '';
|
||||
if (strpos($filename, 'helpers') === 0 && $className && strpos($smarty->source->name, '/template/controllers/'.$className.'/') === false) {
|
||||
$class = 'Helper';
|
||||
}
|
||||
// If the tpl is used by a Controller
|
||||
|
||||
@@ -74,16 +74,6 @@ class AdminAddressesControllerCore extends AdminController
|
||||
'city' => array('title' => $this->l('City')),
|
||||
'country' => array('title' => $this->l('Country'), 'type' => 'select', 'list' => $this->countries_array, 'filter_key' => 'cl!id_country'));
|
||||
|
||||
|
||||
// START send access query information to the admin controller
|
||||
$this->access_select = ' SELECT a.`id_address` FROM '._DB_PREFIX_.'address a';
|
||||
$this->access_join = ' INNER JOIN '._DB_PREFIX_.'customer cust ON (cust.id_customer = a.id_customer)';
|
||||
$this->access_join .= ' INNER JOIN '._DB_PREFIX_.'orders ord ON (cust.id_customer = ord.id_customer)';
|
||||
$this->access_join .= ' INNER JOIN '._DB_PREFIX_.'htl_booking_detail hbd ON (hbd.id_order = ord.id_order)';
|
||||
if ($acsHtls = HotelBranchInformation::getProfileAccessedHotels($this->context->employee->id_profile, 1, 1)) {
|
||||
$this->access_where = ' WHERE hbd.id_hotel IN ('.implode(',', $acsHtls).')';
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->_select = 'cl.`name` as country';
|
||||
@@ -177,6 +167,18 @@ class AdminAddressesControllerCore extends AdminController
|
||||
)
|
||||
);
|
||||
|
||||
if (!Tools::getValue('liteDisplaying')) {
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->fields_value['address_type'] = (int)Tools::getValue('address_type', 1);
|
||||
|
||||
$id_customer = (int)Tools::getValue('id_customer');
|
||||
|
||||
@@ -768,7 +768,12 @@ class AdminCartRulesControllerCore extends AdminController
|
||||
public function displayAjaxSearchCartRuleVouchers()
|
||||
{
|
||||
$found = false;
|
||||
if ($vouchers = CartRule::getCartsRuleByCode(Tools::getValue('q'), (int)$this->context->language->id, true)) {
|
||||
if ($vouchers = CartRule::getCartsRuleByCode(
|
||||
Tools::getValue('q'),
|
||||
(int)$this->context->language->id,
|
||||
true,
|
||||
(int) Tools::getValue('id_customer')
|
||||
)) {
|
||||
$found = true;
|
||||
}
|
||||
echo json_encode(array('found' => $found, 'vouchers' => $vouchers));
|
||||
|
||||
@@ -54,7 +54,7 @@ class AdminCartsControllerCore extends AdminController
|
||||
LEFT JOIN `'._DB_PREFIX_.'connections` co ON (a.id_guest = co.id_guest AND TIME_TO_SEC(TIMEDIFF(\''.pSQL(date('Y-m-d H:i:00', time())).'\', co.`date_add`)) < 1800)';
|
||||
$this->_group = ' GROUP BY a.`id_cart`';
|
||||
|
||||
if (Tools::getValue('action') == 'filterAbandonedCarts') {
|
||||
if (Tools::getValue('action') == 'filterOnlyAbandonedCarts') {
|
||||
$this->_filterHaving = ' AND `ids_order` = 0 AND `time_diff` > 86400';
|
||||
}
|
||||
|
||||
@@ -333,6 +333,9 @@ class AdminCartsControllerCore extends AdminController
|
||||
}
|
||||
$this->context->cart = new Cart((int)$id_cart);
|
||||
|
||||
CartRule::autoRemoveFromCart($this->context);
|
||||
CartRule::autoAddToCart($this->context);
|
||||
|
||||
if (!$this->context->cart->id) {
|
||||
$this->context->cart->recyclable = 0;
|
||||
$this->context->cart->gift = 0;
|
||||
|
||||
@@ -105,7 +105,19 @@ class AdminCmsCategoriesControllerCore extends AdminController
|
||||
$object = parent::postProcess();
|
||||
$this->updateAssoShop((int)Tools::getValue('id_cms_category'));
|
||||
if ($object !== false) {
|
||||
Tools::redirectAdmin(self::$currentIndex.'&conf=3&id_cms_category='.(int)$object->id.'&token='.Tools::getValue('token'));
|
||||
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) {
|
||||
if ($this->id_object) {
|
||||
Tools::redirectAdmin(self::$currentIndex.'&update'.$this->table.'&conf=4&id_cms_category='.(int)$object->id.'&token='.Tools::getValue('token'));
|
||||
} else {
|
||||
Tools::redirectAdmin(self::$currentIndex.'&update'.$this->table.'&conf=3&id_cms_category='.(int)$object->id.'&token='.Tools::getValue('token'));
|
||||
}
|
||||
} else {
|
||||
if ($this->id_object) {
|
||||
Tools::redirectAdmin(self::$currentIndex.'&conf=4&id_cms_category='.(int)$object->id.'&token='.Tools::getValue('token'));
|
||||
} else {
|
||||
Tools::redirectAdmin(self::$currentIndex.'&conf=3&id_cms_category='.(int)$object->id.'&token='.Tools::getValue('token'));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
@@ -289,7 +301,16 @@ class AdminCmsCategoriesControllerCore extends AdminController
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
)
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (Shop::isFeatureActive()) {
|
||||
|
||||
@@ -218,6 +218,13 @@ class AdminCmsControllerCore extends AdminController
|
||||
'title' => $this->l('Save'),
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
'save_and_preview' => array(
|
||||
'name' => 'viewcms',
|
||||
'type' => 'submit',
|
||||
|
||||
@@ -113,7 +113,16 @@ class AdminContactsControllerCore extends AdminController
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
)
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (Shop::isFeatureActive()) {
|
||||
|
||||
@@ -54,20 +54,20 @@ class AdminCountriesControllerCore extends AdminController
|
||||
'dir' => 'st'
|
||||
);
|
||||
|
||||
$this->fields_options = array(
|
||||
'general' => array(
|
||||
'title' => $this->l('Country options'),
|
||||
'fields' => array(
|
||||
'PS_RESTRICT_DELIVERED_COUNTRIES' => array(
|
||||
'title' => $this->l('Restrict country selections in front office to those covered by active carriers'),
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '0'
|
||||
)
|
||||
),
|
||||
'submit' => array('title' => $this->l('Save'))
|
||||
)
|
||||
);
|
||||
// $this->fields_options = array(
|
||||
// 'general' => array(
|
||||
// 'title' => $this->l('Country options'),
|
||||
// 'fields' => array(
|
||||
// 'PS_RESTRICT_DELIVERED_COUNTRIES' => array(
|
||||
// 'title' => $this->l('Restrict country selections in front office to those covered by active carriers'),
|
||||
// 'cast' => 'intval',
|
||||
// 'type' => 'bool',
|
||||
// 'default' => '0'
|
||||
// )
|
||||
// ),
|
||||
// 'submit' => array('title' => $this->l('Save'))
|
||||
// )
|
||||
// );
|
||||
|
||||
$zones_array = array();
|
||||
$this->zones = Zone::getZones();
|
||||
@@ -368,6 +368,16 @@ class AdminCountriesControllerCore extends AdminController
|
||||
'title' => $this->l('Save')
|
||||
);
|
||||
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
)
|
||||
);
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
|
||||
@@ -231,6 +231,16 @@ class AdminCurrenciesControllerCore extends AdminController
|
||||
'title' => $this->l('Save'),
|
||||
);
|
||||
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
)
|
||||
);
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,13 @@ class AdminCustomerPreferencesControllerCore extends AdminController
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool'
|
||||
),
|
||||
'PS_CUSTOMER_BIRTHDATE' => array(
|
||||
'title' => $this->l('Enable date of birth'),
|
||||
'hint' => $this->l('Display or not the date of birth field.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool'
|
||||
),
|
||||
'PS_CUSTOMER_NWSL' => array(
|
||||
'title' => $this->l('Enable newsletter registration'),
|
||||
'hint' => $this->l('Display or not the newsletter registration tick box.'),
|
||||
@@ -108,7 +115,7 @@ class AdminCustomerPreferencesControllerCore extends AdminController
|
||||
),
|
||||
'PS_CUSTOMER_OPTIN' => array(
|
||||
'title' => $this->l('Enable opt-in'),
|
||||
'hint' => $this->l('Display or not the opt-in tick box, to receive offers from the store\'s partners.'),
|
||||
'hint' => $this->l('Display or not the opt-in tick box, to receive offers from your hotel partners.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool'
|
||||
|
||||
@@ -62,6 +62,15 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$status_array[$k] = $v['alt'];
|
||||
}
|
||||
|
||||
// START send access query information to the admin controller
|
||||
$this->access_select = ' SELECT a.`id_customer_thread` FROM '._DB_PREFIX_.'customer_thread a';
|
||||
$this->access_join = ' LEFT JOIN '._DB_PREFIX_.'orders ord ON (a.id_order = ord.id_order)';
|
||||
$this->access_join .= ' LEFT JOIN '._DB_PREFIX_.'htl_booking_detail hbd ON (hbd.id_order = ord.id_order)';
|
||||
$this->access_where = ' WHERE 1 ';
|
||||
if ($acsHtls = HotelBranchInformation::getProfileAccessedHotels($this->context->employee->id_profile, 1, 1)) {
|
||||
$this->access_where .= ' AND IF(a.`id_order`, hbd.`id_hotel` IN ('.implode(',', $acsHtls).'), 1)';
|
||||
}
|
||||
|
||||
$this->fields_list = array(
|
||||
'id_customer_thread' => array(
|
||||
'title' => $this->l('ID'),
|
||||
|
||||
@@ -39,8 +39,8 @@ class AdminCustomersControllerCore extends AdminController
|
||||
public function __construct()
|
||||
{
|
||||
$this->bootstrap = true;
|
||||
$this->required_database = true;
|
||||
$this->required_fields = array('newsletter','optin');
|
||||
// $this->required_database = true;
|
||||
// $this->required_fields = array('newsletter','optin');
|
||||
$this->table = 'customer';
|
||||
$this->className = 'Customer';
|
||||
$this->lang = false;
|
||||
@@ -152,16 +152,6 @@ class AdminCustomersControllerCore extends AdminController
|
||||
|
||||
$this->shopLinkType = 'shop';
|
||||
$this->shopShareDatas = Shop::SHARE_CUSTOMER;
|
||||
|
||||
|
||||
// START send access query information to the admin controller
|
||||
$this->access_select = ' SELECT a.`id_customer` FROM '._DB_PREFIX_.'customer a';
|
||||
$this->access_join = ' INNER JOIN '._DB_PREFIX_.'orders ord ON (a.id_customer = ord.id_customer)';
|
||||
$this->access_join .= ' INNER JOIN '._DB_PREFIX_.'htl_booking_detail hbd ON (hbd.id_order = ord.id_order)';
|
||||
if ($acsHtls = HotelBranchInformation::getProfileAccessedHotels($this->context->employee->id_profile, 1, 1)) {
|
||||
$this->access_where = ' WHERE hbd.id_hotel IN ('.implode(',', $acsHtls).')';
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->_select = '
|
||||
@@ -458,8 +448,9 @@ class AdminCustomersControllerCore extends AdminController
|
||||
'label' => $this->l('Disabled')
|
||||
)
|
||||
),
|
||||
'disabled' => (bool)!Configuration::get('PS_CUSTOMER_NWSL'),
|
||||
'hint' => $this->l('This customer will receive your newsletter via email.')
|
||||
'disabled' => (bool)!Configuration::get('PS_CUSTOMER_NWSL'),
|
||||
'hint' => $this->l('This customer will receive your newsletter via email.'),
|
||||
'desc' => (bool)!Configuration::get('PS_CUSTOMER_NWSL') ? sprintf($this->l('This field is disabled as option \'Enable newsletter registration\' is disabled. You can change it from %sPreferences > Customers%s page.'), '<a href="'.$this->context->link->getAdminLink('AdminCustomerPreferences').'" target="_blank">', '</a>') : '',
|
||||
),
|
||||
array(
|
||||
'type' => 'switch',
|
||||
@@ -597,6 +588,18 @@ class AdminCustomersControllerCore extends AdminController
|
||||
'title' => $this->l('Save'),
|
||||
);
|
||||
|
||||
if (!Tools::getValue('liteDisplaying')) {
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$birthday = explode('-', $this->getFieldValue($obj, 'birthday'));
|
||||
|
||||
$this->fields_value = array(
|
||||
@@ -630,6 +633,10 @@ class AdminCustomersControllerCore extends AdminController
|
||||
Tools::getValue('groupBox_'.$group['id_group'], in_array($group['id_group'], $customer_groups_ids));
|
||||
}
|
||||
|
||||
if ($back = Tools::getValue('back')) {
|
||||
$this->tpl_form_vars['back_url'] = Tools::htmlentitiesDecodeUTF8(Tools::safeOutput(urldecode($back)));
|
||||
}
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
@@ -866,6 +873,25 @@ class AdminCustomersControllerCore extends AdminController
|
||||
|
||||
public function processDelete()
|
||||
{
|
||||
// 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->deleted = 1;
|
||||
if (!$objCustomer->update()) {
|
||||
$this->errors[] = Tools::displayError('Some error ocurred while deleting the Customer');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->redirect_after = self::$currentIndex.'&conf=1&token='.$this->token;
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$this->errors[] = Tools::displayError('Customer not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_setDeletedMode();
|
||||
parent::processDelete();
|
||||
}
|
||||
@@ -884,6 +910,44 @@ class AdminCustomersControllerCore extends AdminController
|
||||
|
||||
protected function processBulkDelete()
|
||||
{
|
||||
// If customer is going to be deleted permanently then if customer has orders the change this customer as an anonymous customer
|
||||
if ($this->delete_mode == 'real') {
|
||||
if (is_array($this->boxes) && !empty($this->boxes)) {
|
||||
foreach ($this->boxes as $key => $idCustomer) {
|
||||
if (Validate::isLoadedObject($objCustomer = new Customer($idCustomer))) {
|
||||
// check if customer has orders for email change else customer will be deleted
|
||||
if (Order::getCustomerOrders($objCustomer->id, true)) {
|
||||
$objCustomer->email = 'anonymous'.'-'.$objCustomer->id.'@'.Tools::getShopDomain();
|
||||
$objCustomer->deleted = 1;
|
||||
if ($objCustomer->update()) {
|
||||
// unset the customer which is processed
|
||||
// not processed customers will be deleted with default process if no errors are there
|
||||
unset($this->boxes[$key]);
|
||||
} else {
|
||||
$this->errors[] = Tools::displayError('Some error ocurred while deleting the Customer with id').': '.$idCustomer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->errors[] = Tools::displayError('Customer id').': '.$idCustomer.' '.Tools::displayError('not found.');
|
||||
}
|
||||
}
|
||||
|
||||
// if all the customers are process above then redirect with success
|
||||
if (!count($this->boxes)) {
|
||||
$this->redirect_after = self::$currentIndex.'&conf=1&token='.$this->token;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$this->errors[] = Tools::displayError('Customers not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
// if errors are there then do not proceed for default process
|
||||
if (count($this->errors)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_setDeletedMode();
|
||||
parent::processBulkDelete();
|
||||
}
|
||||
@@ -966,6 +1030,21 @@ class AdminCustomersControllerCore extends AdminController
|
||||
return parent::processSave();
|
||||
}
|
||||
|
||||
protected function copyFromPost(&$object, $table)
|
||||
{
|
||||
parent::copyFromPost($object, $table);
|
||||
|
||||
$years = Tools::getValue('years');
|
||||
$months = Tools::getValue('months');
|
||||
$days = Tools::getValue('days');
|
||||
|
||||
if ($years != '' && $months != '' && $days != '') {
|
||||
$object->birthday = (int) $years.'-'.(int) $months.'-'.(int) $days;
|
||||
} else {
|
||||
$object->birthday = '0000-00-00';
|
||||
}
|
||||
}
|
||||
|
||||
protected function afterDelete($object, $old_id)
|
||||
{
|
||||
$customer = new Customer($old_id);
|
||||
@@ -1080,10 +1159,11 @@ class AdminCustomersControllerCore extends AdminController
|
||||
public function ajaxProcessSearchCustomers()
|
||||
{
|
||||
$searches = explode(' ', Tools::getValue('customer_search'));
|
||||
$skip_deleted = Tools::getValue('skip_deleted');
|
||||
$customers = array();
|
||||
$searches = array_unique($searches);
|
||||
foreach ($searches as $search) {
|
||||
if (!empty($search) && $results = Customer::searchByName($search, 50)) {
|
||||
if (!empty($search) && $results = Customer::searchByName($search, 50, $skip_deleted)) {
|
||||
foreach ($results as $result) {
|
||||
if ($result['active']) {
|
||||
$customers[$result['id_customer']] = $result;
|
||||
|
||||
@@ -135,8 +135,8 @@ class AdminDashboardControllerCore extends AdminController
|
||||
}
|
||||
|
||||
$forms['net_profit']['fields']['CONF_AVERAGE_PRODUCT_MARGIN'] = array(
|
||||
'title' => $this->l('Average gross margin percentage'),
|
||||
'desc' => $this->l('You should calculate this percentage as follows: ((total sales revenue) - (total operating cost)) / (total sales revenue) * 100. This value is only used to calculate Dashboard approximate gross margin, if you do not specify operating cost for each room type.'),
|
||||
'title' => $this->l('Average gross operating cost percentage'),
|
||||
'desc' => $this->l('This value is only used to calculate Dashboard approximate gross operating cost, if you do not specify operating cost for each room type.'),
|
||||
'validation' => 'isPercentage',
|
||||
'cast' => 'intval',
|
||||
'type' => 'text',
|
||||
@@ -386,7 +386,16 @@ class AdminDashboardControllerCore extends AdminController
|
||||
'extra' => Tools::getValue('extra')
|
||||
);
|
||||
|
||||
die(json_encode(Hook::exec('dashboardData', $params, $id_module, true, true, (int)Tools::getValue('dashboard_use_push'))));
|
||||
// code to be added.
|
||||
$data = Hook::exec('dashboardData', $params, $id_module, true, true, (int)Tools::getValue('dashboard_use_push'));
|
||||
Hook::exec('actionDashboardDataModifier', array(
|
||||
'data' => &$data,
|
||||
'params' => $params,
|
||||
'id_module' => $id_module,
|
||||
'dashboard_use_push' => (int)Tools::getValue('dashboard_use_push')
|
||||
));
|
||||
|
||||
$this->ajaxDie(json_encode($data));
|
||||
}
|
||||
|
||||
public function ajaxProcessSetSimulationMode()
|
||||
|
||||
@@ -403,6 +403,16 @@ class AdminEmployeesControllerCore extends AdminController
|
||||
'title' => $this->l('Save'),
|
||||
);
|
||||
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
)
|
||||
);
|
||||
|
||||
$this->fields_value['passwd'] = false;
|
||||
$this->fields_value['bo_theme_css'] = $obj->bo_theme.'|'.$obj->bo_css;
|
||||
|
||||
|
||||
@@ -216,6 +216,16 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
'title' => $this->l('Save'),
|
||||
);
|
||||
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
)
|
||||
);
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
@@ -544,9 +554,9 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
if ($this->table == 'feature_value' && ($this->display == 'edit' || $this->display == 'add')) {
|
||||
$this->redirect_after = self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&token='.$this->token;
|
||||
} else {
|
||||
$this->redirect_after = self::$currentIndex.'&'.$this->identifier.'=&conf=3&update'.$this->table.'&token='.$this->token;
|
||||
$this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.(int) $object->id.'&conf=3&update'.$this->table.'&token='.$this->token;
|
||||
}
|
||||
} elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && count($this->errors)) {
|
||||
} elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && count($this->errors) && $this->table == 'feature_value') { // enter only if feature is submitted
|
||||
$this->display = 'editFeatureValue';
|
||||
}
|
||||
|
||||
@@ -562,7 +572,7 @@ class AdminFeaturesControllerCore extends AdminController
|
||||
$object = parent::processUpdate();
|
||||
|
||||
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors)) {
|
||||
$this->redirect_after = self::$currentIndex.'&'.$this->identifier.'=&conf=3&update'.$this->table.'&token='.$this->token;
|
||||
$this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.(int) Tools::getValue('id_feature').'&conf=4&update'.$this->table.'&token='.$this->token;
|
||||
}
|
||||
|
||||
return $object;
|
||||
|
||||
@@ -173,7 +173,16 @@ class AdminGendersControllerCore extends AdminController
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
)
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/** @var Gender $obj */
|
||||
|
||||
@@ -126,7 +126,7 @@ class AdminGroupsControllerCore extends AdminController
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
if (empty($this->display)) {
|
||||
if (empty($this->display) && Group::isFeatureActive()) {
|
||||
$this->page_header_toolbar_btn['new_group'] = array(
|
||||
'href' => self::$currentIndex.'&addgroup&token='.$this->token,
|
||||
'desc' => $this->l('Add new group', null, null, false),
|
||||
@@ -148,8 +148,32 @@ class AdminGroupsControllerCore extends AdminController
|
||||
parent::initProcess();
|
||||
}
|
||||
|
||||
public function initContent()
|
||||
{
|
||||
if (!Group::isFeatureActive()) {
|
||||
parent::initContent();
|
||||
|
||||
$content = $this->displayWarning(sprintf(
|
||||
$this->l('The feature Customer Groups has been disabled. You can enable it from %s page.'),
|
||||
'<a href="'.$this->context->link->getAdminLink('AdminPerformance').'#fieldset_2_2" target="_blank">'.$this->l('Advanced Parameters > Performance').'</a>'
|
||||
));
|
||||
|
||||
$this->context->smarty->assign(array(
|
||||
'content' => $content,
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::initContent();
|
||||
}
|
||||
|
||||
public function postProcess()
|
||||
{
|
||||
if (!Group::isFeatureActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($_POST['submitResetcustomer_group'])) {
|
||||
$this->processResetFilters('customer_group');
|
||||
}
|
||||
@@ -175,13 +199,12 @@ class AdminGroupsControllerCore extends AdminController
|
||||
|
||||
protected function renderCustomersList($group)
|
||||
{
|
||||
$genders = array(0 => '?');
|
||||
$genders_icon = array('default' => 'unknown.gif');
|
||||
foreach (Gender::getGenders() as $gender) {
|
||||
/** @var Gender $gender */
|
||||
$genders_icon[$gender->id] = '../genders/'.(int)$gender->id.'.jpg';
|
||||
$genders[$gender->id] = $gender->name;
|
||||
$titles_array = array();
|
||||
$genders = Gender::getGenders($this->context->language->id);
|
||||
foreach ($genders as $gender) {
|
||||
$titles_array[$gender->id_gender] = $gender->name;
|
||||
}
|
||||
|
||||
$this->table = 'customer_group';
|
||||
$this->lang = false;
|
||||
$this->list_id = 'customer_group';
|
||||
@@ -194,7 +217,7 @@ class AdminGroupsControllerCore extends AdminController
|
||||
|
||||
$this->fields_list = (array(
|
||||
'id_customer' => array('title' => $this->l('ID'), 'align' => 'center', 'filter_key' => 'c!id_customer', 'class' => 'fixed-width-xs'),
|
||||
'id_gender' => array('title' => $this->l('Social title'), 'icon' => $genders_icon, 'list' => $genders),
|
||||
'title' => array('title' => $this->l('Social title'), 'filter_key' => 'c!id_gender', 'type' => 'select', 'list' => $titles_array),
|
||||
'firstname' => array('title' => $this->l('First name')),
|
||||
'lastname' => array('title' => $this->l('Last name')),
|
||||
'email' => array('title' => $this->l('Email address'), 'filter_key' => 'c!email', 'orderby' => true),
|
||||
@@ -202,8 +225,9 @@ class AdminGroupsControllerCore extends AdminController
|
||||
'date_add' => array('title' => $this->l('Registration date'), 'type' => 'date', 'class' => 'fixed-width-md', 'align' => 'center'),
|
||||
'active' => array('title' => $this->l('Enabled'), 'align' => 'center', 'class' => 'fixed-width-sm', 'type' => 'bool', 'search' => false, 'orderby' => false, 'filter_key' => 'c!active', 'callback' => 'printOptinIcon')
|
||||
));
|
||||
$this->_select = 'c.*, a.id_group';
|
||||
$this->_select = 'c.*, a.id_group, gl.`name` AS title';
|
||||
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'customer` c ON (a.`id_customer` = c.`id_customer`)';
|
||||
$this->_join .= ' LEFT JOIN '._DB_PREFIX_.'gender_lang gl ON (gl.`id_gender` = c.`id_gender` AND gl.`id_lang` = '.(int) $this->context->language->id.')';
|
||||
$this->_where = 'AND a.`id_group` = '.(int)$group->id.' AND c.`deleted` != 1';
|
||||
$this->_where .= Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c');
|
||||
self::$currentIndex = self::$currentIndex.'&id_group='.(int)$group->id.'&viewgroup';
|
||||
@@ -232,6 +256,15 @@ class AdminGroupsControllerCore extends AdminController
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
),
|
||||
'input' => array(
|
||||
array(
|
||||
'type' => 'text',
|
||||
|
||||
@@ -403,7 +403,16 @@ class AdminImagesControllerCore extends AdminController
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save')
|
||||
)
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
parent::__construct();
|
||||
|
||||
@@ -140,7 +140,6 @@ class AdminInformationControllerCore extends AdminController
|
||||
'upload_max_filesize' => $this->l('In PHP configuration set upload_max_filesize to minimum 16M.'),
|
||||
'max_execution_time' => $this->l('In PHP configuration set max_execution_time to minimum 500.'),
|
||||
'mbstring' => $this->l('PHP Mbstring extension is not enabled.'),
|
||||
'magicquotes' => $this->l('PHP magic quotes option is enabled.'),
|
||||
'dom' => $this->l('PHP DOM extension is not loaded.'),
|
||||
);
|
||||
|
||||
|
||||
@@ -195,10 +195,12 @@ class AdminInvoicesControllerCore extends AdminController
|
||||
);
|
||||
|
||||
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
|
||||
SELECT COUNT( o.id_order ) AS nbOrders, o.current_state as id_order_state
|
||||
SELECT COUNT(DISTINCT(o.id_order)) AS nbOrders, o.current_state as id_order_state
|
||||
FROM `'._DB_PREFIX_.'order_invoice` oi
|
||||
LEFT JOIN `'._DB_PREFIX_.'orders` o ON oi.id_order = o.id_order
|
||||
INNER JOIN `'._DB_PREFIX_.'htl_booking_detail` hbd ON (oi.id_order = hbd.id_order)
|
||||
WHERE o.id_shop IN('.implode(', ', Shop::getContextListShopID()).')
|
||||
'.HotelBranchInformation::addHotelRestriction(false, 'hbd').'
|
||||
AND oi.number > 0
|
||||
GROUP BY o.current_state
|
||||
');
|
||||
@@ -324,4 +326,11 @@ class AdminInvoicesControllerCore extends AdminController
|
||||
|
||||
return $templates;
|
||||
}
|
||||
|
||||
public function setMedia()
|
||||
{
|
||||
parent::setMedia();
|
||||
$this->addJS(_PS_JS_DIR_.'admin/invoices.js');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -262,6 +262,16 @@ class AdminLanguagesControllerCore extends AdminController
|
||||
'title' => $this->l('Save'),
|
||||
);
|
||||
|
||||
$this->fields_form['buttons'] = array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
);
|
||||
|
||||
/** @var Language $obj */
|
||||
if (!($obj = $this->loadObject(true))) {
|
||||
return;
|
||||
|
||||
@@ -45,6 +45,17 @@ class AdminLoginControllerCore extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if ($this->ajax && Tools::getValue('action') == 'checkLoginStatus') {
|
||||
$this->ajaxDie(json_encode(array(
|
||||
'is_logged_in' => $this->context->employee->isLoggedBack(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
public function setMedia()
|
||||
{
|
||||
$this->addJquery();
|
||||
|
||||
@@ -97,6 +97,8 @@ class AdminLogsControllerCore extends AdminController
|
||||
$this->list_no_link = true;
|
||||
$this->_select .= 'CONCAT(e.firstname, \' \', e.lastname) employee';
|
||||
$this->_join .= ' LEFT JOIN '._DB_PREFIX_.'employee e ON (a.id_employee = e.id_employee)';
|
||||
$this->_orderBy = 'a.date_add';
|
||||
$this->_orderWay = 'DESC';
|
||||
$this->_use_found_rows = false;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
@@ -381,7 +381,16 @@ class AdminMetaControllerCore extends AdminController
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save')
|
||||
)
|
||||
),
|
||||
'buttons' => array(
|
||||
'save-and-stay' => array(
|
||||
'title' => $this->l('Save and stay'),
|
||||
'name' => 'submitAdd'.$this->table.'AndStay',
|
||||
'type' => 'submit',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
'icon' => 'process-icon-save',
|
||||
),
|
||||
),
|
||||
);
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ class AdminModulesCatalogControllerCore extends AdminController
|
||||
$this->page_header_toolbar_btn['addons'] = array(
|
||||
'href' => 'https://qloapps.com/addons/',
|
||||
'desc' => $this->l('Explore all Addons'),
|
||||
'imgclass' => 'modules-list',
|
||||
'imgclass' => 'puzzle-piece',
|
||||
'target' => true
|
||||
);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user