Merge branch 'develop' into gli-2852

This commit is contained in:
varun kewlani
2026-06-15 13:52:22 +05:30
37 changed files with 1323 additions and 322 deletions

View File

@@ -107,6 +107,47 @@
}
perfect_access_js_gestion(this, perm, id_tab, tabsize, tabnumber, table);
if (perm == 'kpi') {
$(table + ' .kpi.' + id_tab).prop('checked', !!enabled);
}
$(table + ' tr.kpi-row').each(function() {
var kpiTabId = $(this).data('kpi-parent');
var kpiProfile = $(this).data('kpi-profile');
var $kpiInputs = $(this).find('input.ajaxPower.kpi');
if (!$kpiInputs.length || $kpiInputs.first().data('kpi-editable') != 1) { return; }
// For perm=view, read state directly from action — jQuery 1.11 .attr() doesn't update .prop()
var parentEnabled = (perm == 'view' && (id_tab == kpiTabId || id_tab == -1))
? !!enabled
: $(table + ' input.view.' + kpiTabId).first().is(':checked');
if (!parentEnabled) {
$kpiInputs.prop('checked', false).prop('disabled', true);
} else {
$kpiInputs.prop('disabled', false);
if (perm == 'all' && (id_tab == -1 || id_tab == kpiTabId)) {
$kpiInputs.prop('checked', !!enabled).first().trigger('change');
}
if (perm == 'view' && (id_tab == kpiTabId || id_tab == -1) && !!enabled) {
$kpiInputs.prop('checked', true);
$.ajax({
url: "{$link->getAdminLink('AdminAccess')|addslashes}",
cache: false,
data: {
ajaxMode: '1',
id_tab: kpiTabId,
id_profile: kpiProfile,
perm: 'kpi',
enabled: 1,
submitAddAccess: '1',
action: 'updateAccess',
ajax: '1',
token: '{getAdminToken tab='AdminAccess'}'
}
});
}
}
});
$.ajax({
url: "{$link->getAdminLink('AdminAccess')|addslashes}",
cache: false,
@@ -349,6 +390,32 @@
<input type="checkbox"{if $access_edit == 1} data-rel="{$access[$tab.id_tab]['id_tab']}||{$profile.id_profile}||all||{$tabsize}||{count($tabs)}" class="ajaxPower all {$access[$tab.id_tab]['id_tab']}"{else} class="all {$access[$tab.id_tab]['id_tab']}" disabled="disabled"{/if}{if $result_accesses == 4} checked="checked"{/if}/>
</td>
</tr>
{if !empty($tab.has_kpi)}
<tr class="kpi-row kpi-level-1 child-kpi-{$tab.id_tab}" data-kpi-parent="{$tab.id_tab}" data-kpi-profile="{$profile.id_profile}">
<td>&nbsp; &raquo; {l s='KPI'}</td>
<td>
<input type="checkbox"
class="ajaxPower kpi {$tab.id_tab}"
data-rel="{$tab.id_tab}||{$profile.id_profile}||kpi||{$tabsize}||{count($tabs)}"
data-kpi-editable="{if $access_edit == 1}1{else}0{/if}"
{if $access_edit != 1 || $access[$tab.id_tab].view != 1}disabled="disabled"{/if}
{if isset($access[$tab.id_tab].kpi) && $access[$tab.id_tab].kpi == 1 && $access[$tab.id_tab].view == 1}checked="checked"{/if}
/>
</td>
<td><input type="checkbox" disabled="disabled"/></td>
<td><input type="checkbox" disabled="disabled"/></td>
<td><input type="checkbox" disabled="disabled"/></td>
<td>
<input type="checkbox"
class="ajaxPower kpi {$tab.id_tab}"
data-rel="{$tab.id_tab}||{$profile.id_profile}||kpi||{$tabsize}||{count($tabs)}"
data-kpi-editable="{if $access_edit == 1}1{else}0{/if}"
{if $access_edit != 1 || $access[$tab.id_tab].view != 1}disabled="disabled"{/if}
{if isset($access[$tab.id_tab].kpi) && $access[$tab.id_tab].kpi == 1 && $access[$tab.id_tab].view == 1}checked="checked"{/if}
/>
</td>
</tr>
{/if}
{foreach $tabs AS $child}
{if $child.id_parent === $tab.id_tab}
{if isset($access[$child.id_tab])}
@@ -372,6 +439,32 @@
<input type="checkbox"{if $access_edit == 1} data-rel="{$access[$child.id_tab]['id_tab']}||{$profile.id_profile}||all||{$tabsize}||{count($tabs)}" class="ajaxPower all {$access[$child.id_tab]['id_tab']}"{else} class="all {$access[$child.id_tab]['id_tab']}" disabled="disabled"{/if}{if $result_accesses == 4} checked="checked"{/if}/>
</td>
</tr>
{if !empty($child.has_kpi)}
<tr class="kpi-row kpi-level-2 child-kpi-{$child.id_tab}" data-kpi-parent="{$child.id_tab}" data-kpi-profile="{$profile.id_profile}">
<td>&nbsp; &raquo; {l s='KPI'}</td>
<td>
<input type="checkbox"
class="ajaxPower kpi {$child.id_tab}"
data-rel="{$child.id_tab}||{$profile.id_profile}||kpi||{$tabsize}||{count($tabs)}"
data-kpi-editable="{if $access_edit == 1}1{else}0{/if}"
{if $access_edit != 1 || $access[$child.id_tab].view != 1}disabled="disabled"{/if}
{if isset($access[$child.id_tab].kpi) && $access[$child.id_tab].kpi == 1 && $access[$child.id_tab].view == 1}checked="checked"{/if}
/>
</td>
<td><input type="checkbox" disabled="disabled"/></td>
<td><input type="checkbox" disabled="disabled"/></td>
<td><input type="checkbox" disabled="disabled"/></td>
<td>
<input type="checkbox"
class="ajaxPower kpi {$child.id_tab}"
data-rel="{$child.id_tab}||{$profile.id_profile}||kpi||{$tabsize}||{count($tabs)}"
data-kpi-editable="{if $access_edit == 1}1{else}0{/if}"
{if $access_edit != 1 || $access[$child.id_tab].view != 1}disabled="disabled"{/if}
{if isset($access[$child.id_tab].kpi) && $access[$child.id_tab].kpi == 1 && $access[$child.id_tab].view == 1}checked="checked"{/if}
/>
</td>
</tr>
{/if}
{/if}
{/if}
{/foreach}
@@ -438,4 +531,4 @@
</div>
{/foreach}
</form>
</div>
</div>

View File

@@ -456,7 +456,7 @@
<th><span class="title_box ">{l s='Transaction ID'}</span></th>
<th><span class="title_box ">{l s='Amount'}</span></th>
<th><span class="title_box ">{l s='Invoice'}</span></th>
<th></th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
@@ -468,6 +468,11 @@
<td>{$payment['transaction_id']|escape:'html':'UTF-8'}</td>
<td>{displayPrice price=$payment['real_paid_amount'] currency=$payment['id_currency']}</td>
<td>{if isset($payment['invoice_number'])}{$payment['invoice_number']}{else}--{/if}</td>
{if isset($receipt_management_active) && $receipt_management_active}
<td class="actions">
<a target="_blank" class="btn btn-default" href="{$link->getAdminLink('AdminPdf')}&submitAction=generatePaymentReceipt&id_order_payment_detail={$payment['id_order_payment_detail']}"><i class="icon-file-text"></i> {l s='Receipt'}</a>
</td>
{/if}
<td class="actions">
<a class="open_payment_information btn btn-default" href="#" data-card_number="{if $payment['card_number']}{$payment['card_number']}{else}{l s='Not defined'}{/if}" data-card_brand="{if $payment['card_brand']}{$payment['card_brand']}{else}{l s='Not defined'}{/if}" data-card_expiration="{if $payment['card_expiration']}{$payment['card_expiration']}{else}{l s='Not defined'}{/if}" data-card_holder="{if $payment['card_holder']}{$payment['card_holder']}{else}{l s='Not defined'}{/if}" data-payment_date="{if $payment['date_add']}{$payment['date_add']}{else}{l s='Not defined'}{/if}" data-payment_method="{if $payment['payment_method']}{$payment['payment_method']}{else}{l s='Not defined'}{/if}" data-payment_source="{if $payment_types[$payment['payment_type']]['name']}{$payment_types[$payment['payment_type']]['name']}{else}{l s='Not defined'}{/if}" data-transaction_id="{if $payment['transaction_id']}{$payment['transaction_id']}{else}{l s='Not defined'}{/if}" data-amount="{if $payment['amount']}{displayPrice currency={$payment['id_currency']} price={$payment['amount']}}{else}{l s='Not defined'}{/if}" data-invoice_number="{if isset($payment['invoice_number']) && $payment['invoice_number']}{$payment['invoice_number']}{else}{l s='Not defined'}{/if}"><i class="icon-search"></i> {l s='Details'}</a>
</td>

View File

@@ -81,7 +81,7 @@ class ProfileCore extends ObjectModel
public function add($autodate = true, $null_values = false)
{
if (parent::add($autodate, true)) {
$result = Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'access (SELECT '.(int)$this->id.', id_tab, 0, 0, 0, 0 FROM '._DB_PREFIX_.'tab)');
$result = Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'access (SELECT '.(int)$this->id.', id_tab, 0, 0, 0, 0, 0 FROM '._DB_PREFIX_.'tab)');
$result &= Db::getInstance()->execute('
INSERT INTO '._DB_PREFIX_.'module_access
(`id_profile`, `id_module`, `configure`, `view`, `uninstall`)
@@ -138,6 +138,7 @@ class ProfileCore extends ObjectModel
'add' => 1,
'edit' => 1,
'delete' => 1,
'kpi' => 1,
);
}
} else {
@@ -151,6 +152,7 @@ class ProfileCore extends ObjectModel
$result[$key]['delete'] = (int) $profileAccess['delete'];
$result[$key]['add'] = (int) $profileAccess['add'];
$result[$key]['edit'] = (int) $profileAccess['edit'];
$result[$key]['kpi'] = (int) $profileAccess['kpi'];
}
}

View File

@@ -137,12 +137,12 @@ class TabCore extends ObjectModel
}
/* Query definition */
$query = 'REPLACE INTO `'._DB_PREFIX_.'access` (`id_profile`, `id_tab`, `view`, `add`, `edit`, `delete`) VALUES ';
$query .= '(1, '.(int)$id_tab.', 1, 1, 1, 1),';
$query = 'REPLACE INTO `'._DB_PREFIX_.'access` (`id_profile`, `id_tab`, `view`, `add`, `edit`, `delete`, `kpi`) VALUES ';
$query .= '(1, '.(int)$id_tab.', 1, 1, 1, 1, 1),';
foreach ($profiles as $profile) {
$rights = $profile['id_profile'] == $context->employee->id_profile ? 1 : 0;
$query .= '('.(int)$profile['id_profile'].', '.(int)$id_tab.', '.(int)$rights.', '.(int)$rights.', '.(int)$rights.', '.(int)$rights.'),';
$query .= '('.(int)$profile['id_profile'].', '.(int)$id_tab.', '.(int)$rights.', '.(int)$rights.', '.(int)$rights.', '.(int)$rights.', '.(int)$rights.'),';
}
$query = trim($query, ', ');
return Db::getInstance()->execute($query);
@@ -247,7 +247,7 @@ class TabCore extends ObjectModel
* @return array tabs
*/
protected static $_cache_tabs = array();
public static function getTabs($id_lang, $id_parent = null)
public static function getTabs($id_lang, $id_parent = null, $include_kpi = false)
{
if (!isset(self::$_cache_tabs[$id_lang])) {
self::$_cache_tabs[$id_lang] = array();
@@ -274,10 +274,52 @@ class TabCore extends ObjectModel
foreach (self::$_cache_tabs[$id_lang] as $array_parent) {
$array_all = array_merge($array_all, $array_parent);
}
return $array_all;
$tabs = $array_all;
} else {
$tabs = isset(self::$_cache_tabs[$id_lang][$id_parent]) ? self::$_cache_tabs[$id_lang][$id_parent] : array();
}
return (isset(self::$_cache_tabs[$id_lang][$id_parent]) ? self::$_cache_tabs[$id_lang][$id_parent] : array());
if ($include_kpi) {
$hookKpiClasses = array();
$hookRows = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT SUBSTRING(h.`name`, 7, LENGTH(h.`name`) - 24) AS `class_name`
FROM `'._DB_PREFIX_.'hook` h
INNER JOIN `'._DB_PREFIX_.'hook_module` hm
ON hm.`id_hook` = h.`id_hook`
AND hm.`id_shop` = '.(int)Context::getContext()->shop->id.'
INNER JOIN `'._DB_PREFIX_.'module` m
ON m.`id_module` = hm.`id_module` AND m.`active` = 1
WHERE h.`name` LIKE \'action%KPIListingModifier\''
);
if (is_array($hookRows)) {
foreach ($hookRows as $row) {
$hookKpiClasses[$row['class_name']] = true;
}
}
foreach ($tabs as &$tab) {
if (!empty($tab['module'])) {
$file = _PS_MODULE_DIR_.$tab['module'].'/controllers/admin/'.$tab['class_name'].'Controller.php';
$class_name = $tab['class_name'].'Controller';
} else {
$file = _PS_CONTROLLER_DIR_.'admin/'.$tab['class_name'].'Controller.php';
$class_name = $tab['class_name'].'ControllerCore';
}
if (file_exists($file) && !class_exists($class_name)) {
require_once $file;
}
try {
$objreflect = new ReflectionMethod($class_name, 'renderKpis');
$tab['has_kpi'] = ($objreflect->getDeclaringClass()->getName() === $class_name)
|| isset($hookKpiClasses[$tab['class_name']]);
} catch (ReflectionException $e) {
$tab['has_kpi'] = isset($hookKpiClasses[$tab['class_name']]);
}
}
unset($tab);
}
return $tabs;
}
/**

View File

@@ -2307,7 +2307,9 @@ class AdminControllerCore extends Controller
$this->content .= $this->renderDetails();
} elseif (!$this->ajax) {
$this->content .= $this->renderModulesList();
$this->content .= $this->renderKpis();
if ($this->tabAccess['kpi'] === 1) {
$this->content .= $this->renderKpis();
}
$this->content .= $this->renderList();
$this->content .= $this->renderOptions();

View File

@@ -1905,7 +1905,15 @@ class OrderCore extends ObjectModel
$order_payment_detail->id_order = $this->id;
$order_payment_detail->id_order_payment = (int)$payment->id;
$order_payment_detail->amount = $amount;
$receipt_number = Configuration::get('PS_PAYMENT_RECEIPTS_START_NUMBER', null, null, $this->id_shop);
// If payment start number has been set, you clean the value of this configuration
if ($receipt_number) {
Configuration::updateValue('PS_PAYMENT_RECEIPTS_START_NUMBER', false, false, null, $this->id_shop);
}else{
$receipt_number = OrderPaymentDetail::getLastPaymentReceiptNumber() + 1;
}
$order_payment_detail->receipt_number = $receipt_number;
if ($payment->id_currency == $this->id_currency) {
$this->total_paid_real += $order_payment_detail->amount;
} else {
@@ -1935,6 +1943,8 @@ class OrderCore extends ObjectModel
return false;
}
/**
* Returns the correct product taxes breakdown.
*
@@ -3148,4 +3158,26 @@ class OrderCore extends ObjectModel
return $totalOrder;
}
public function getPaymentsTypes()
{
$module = Module::getInstanceByName('hotelreservationsystem');
return array(
OrderPayment::PAYMENT_TYPE_PAY_AT_HOTEL => array(
'key' => 'PAYMENT_TYPE_PAY_AT_HOTEL',
'value' => OrderPayment::PAYMENT_TYPE_PAY_AT_HOTEL,
'name' => $module->l('Pay at hotel')
),
OrderPayment::PAYMENT_TYPE_ONLINE => array(
'key' => 'PAYMENT_TYPE_ONLINE',
'value' => OrderPayment::PAYMENT_TYPE_ONLINE,
'name' => $module->l('Online')
),
OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT => array(
'key' => 'PAYMENT_TYPE_REMOTE_PAYMENT',
'value' => OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT,
'name' => $module->l('Remote payment')
),
);
}
}

View File

@@ -159,4 +159,5 @@ class OrderPaymentCore extends ObjectModel
{
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);
}
}

View File

@@ -26,6 +26,7 @@ class OrderPaymentDetailCore extends ObjectModel
public $id_order_payment;
public $id_order;
public $amount;
public $receipt_number;
public $date_add;
public static $definition = array(
@@ -35,6 +36,7 @@ class OrderPaymentDetailCore extends ObjectModel
'id_order_payment' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'id_order' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'amount' => array('type' => self::TYPE_FLOAT, 'validate' => 'isNegativePrice', 'required' => true),
'receipt_number' => array('type' => self::TYPE_INT, 'validate' => 'isGenericName', 'size' => 64),
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
)
);
@@ -71,4 +73,49 @@ class OrderPaymentDetailCore extends ObjectModel
WHERE oip.`id_order_invoice` = '.(int)$id_invoice
);
}
public static function getLastPaymentReceiptNumber()
{
$sql = 'SELECT MAX(`receipt_number`) FROM `'._DB_PREFIX_.'order_payment_detail`';
if (Configuration::get('PS_PAYMENT_RECEIPTS_RESET')) {
$sql .= ' WHERE DATE_FORMAT(`date_add`, "%Y") = '.(int)date('Y');
}
return Db::getInstance()->getValue($sql);
}
public static function getPaymentDetailsByPaymentId($id_order_payment)
{
return Db::getInstance()->executeS('
SELECT *
FROM `'._DB_PREFIX_.'order_payment_detail`
WHERE `id_order_payment` = '.(int)$id_order_payment
);
}
public static function getByDateInterval($date_from, $date_to)
{
$payment_list = Db::getInstance()->executeS('
SELECT DISTINCT opd.*
FROM `'._DB_PREFIX_.'order_payment_detail` opd
LEFT JOIN `'._DB_PREFIX_.'orders` o ON (o.`id_order` = opd.`id_order`)
WHERE DATE_ADD(opd.`date_add`, INTERVAL -1 DAY) <= \''.pSQL($date_to).'\'
AND opd.`date_add` >= \''.pSQL($date_from).'\'
AND opd.`receipt_number` > 0
'.Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o').'
ORDER BY opd.`date_add` ASC, opd.`id_order_payment_detail` ASC
');
return ObjectModel::hydrateCollection('OrderPaymentDetail', $payment_list);
}
public function getPaymentReceiptNumberFormated($id_lang, $id_shop = null)
{
$format = '%1$s%2$06d';
if (Configuration::get('PS_PAYMENT_RECEIPTS_USE_YEAR')) {
$format = '%1$s%2$06d/%3$s';
}
return sprintf($format, Configuration::get('PS_PAYMENT_RECEIPTS_PREFIX', (int)$id_lang, null, (int)$id_shop), $this->receipt_number, date('Y', strtotime($this->date_add)));
}
}

View File

@@ -474,8 +474,32 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate
$cart_htl_data[$type_key]['date_diff'][$date_join]['num_rm'] = 1;
$fullDate = (isset($context->controller->show_full_date) && $context->controller->show_full_date && (date('Y-m-d', strtotime($data_v['date_from'])) == date('Y-m-d', strtotime($data_v['date_to'])))) ? true : false;
$cart_htl_data[$type_key]['date_diff'][$date_join]['data_form'] = Tools::displayDate($data_v['date_from'], null, $fullDate);
$cart_htl_data[$type_key]['date_diff'][$date_join]['data_to'] = Tools::displayDate($data_v['date_to'], null, $fullDate);
$display_date_from = $data_v['date_from'];
$display_date_to = $data_v['date_to'];
if ((int)$data_v['id_status'] === HotelBookingDetail::STATUS_CHECKED_OUT) {
if ($data_v['check_in']) {
$display_date_from = $data_v['check_in'];
}
if ($data_v['check_out']) {
$display_date_to = $data_v['check_out'];
}
} elseif ((int)$data_v['id_status'] === HotelBookingDetail::STATUS_CHECKED_IN) {
if ($data_v['check_in']) {
$display_date_from = $data_v['check_in'];
}
if ($data_v['check_out_time']) {
$display_date_to = date('Y-m-d', strtotime($data_v['date_to'])) . ' ' . date('H:i:s', strtotime($data_v['check_out_time']));
}
} else {
if ($data_v['check_in_time']) {
$display_date_from = date('Y-m-d', strtotime($data_v['date_from'])) . ' ' . date('H:i:s', strtotime($data_v['check_in_time']));
}
if ($data_v['check_out_time']) {
$display_date_to = date('Y-m-d', strtotime($data_v['date_to'])) . ' ' . date('H:i:s', strtotime($data_v['check_out_time']));
}
}
$cart_htl_data[$type_key]['date_diff'][$date_join]['data_form'] = Tools::displayDate($display_date_from, null, true);
$cart_htl_data[$type_key]['date_diff'][$date_join]['data_to'] = Tools::displayDate($display_date_to, null, true);
$cart_htl_data[$type_key]['date_diff'][$date_join]['num_days'] = $num_days;
$cart_htl_data[$type_key]['date_diff'][$date_join]['adults'] = $data_v['adults'];
$cart_htl_data[$type_key]['date_diff'][$date_join]['children'] = $data_v['children'];

View File

@@ -0,0 +1,171 @@
<?php
/**
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*/
/**
* @since 1.5
*/
class HTMLTemplatePaymentReceiptCore extends HTMLTemplate
{
public $paymentReceipt;
public $orderPayment;
public $order;
/**
* @param OrderPaymentDetail $paymentReceipt
* @param $smarty
* @throws PrestaShopException
*/
public function __construct(OrderPaymentDetail $paymentReceipt, $smarty, $bulk_mode = false)
{
$this->paymentReceipt = $paymentReceipt;
$this->smarty = $smarty;
$this->date = Tools::displayDate($this->paymentReceipt->date_add);
$id_lang = Context::getContext()->language->id;
$this->orderPayment = new OrderPayment((int)$this->paymentReceipt->id_order_payment);
if (!Validate::isLoadedObject($this->orderPayment)) {
throw new PrestaShopException('Cannot load the payment associated with this payment receipt.');
}
$this->order = new Order((int)$this->paymentReceipt->id_order);
if (!Validate::isLoadedObject($this->order)) {
throw new PrestaShopException('Cannot load the order associated with this payment receipt.');
}
$id_shop = (int)$this->order->id_shop;
$this->shop = new Shop($id_shop);
$this->orderPayment->amount = $this->paymentReceipt->amount;
$this->title = $this->paymentReceipt->getPaymentReceiptNumberFormated($id_lang, $id_shop);
}
/**
* Returns the template's HTML header
*
* @return string HTML header
*/
public function getHeader()
{
$this->assignCommonHeaderData();
$this->smarty->assign(array(
'header' => HTMLTemplatePaymentReceipt::l('Receipt'),
));
return $this->smarty->fetch($this->getTemplate('header'));
}
public function getFooter()
{
$shop_address = $this->getShopAddress();
$id_shop = (int)$this->shop->id;
$this->smarty->assign(array(
'shop_address' => $shop_address,
'shop_fax' => Configuration::get('PS_SHOP_FAX', null, null, $id_shop),
'shop_phone' => Configuration::get('PS_SHOP_PHONE', null, null, $id_shop),
'shop_email' => Configuration::get('PS_SHOP_EMAIL', null, null, $id_shop),
'free_text' => Configuration::get('PS_PAYMENT_RECEIPTS_FREE_TEXT', (int)Context::getContext()->language->id, null, $id_shop)
));
return $this->smarty->fetch($this->getTemplate('footer'));
}
public function getContent()
{
$delivery_address = $invoice_address = new Address((int)$this->order->id_address_invoice);
$formatted_invoice_address = AddressFormat::generateAddress($invoice_address, array(), '<br />', ' ');
$formatted_delivery_address = '';
if ($this->order->id_address_delivery != $this->order->id_address_invoice) {
$delivery_address = new Address((int)$this->order->id_address_delivery);
$formatted_delivery_address = AddressFormat::generateAddress($delivery_address, array(), '<br />', ' ');
}
$formattedHotelAddress = '';
if (Module::isInstalled('hotelreservationsystem')) {
if ($idHotel = HotelBookingDetail::getIdHotelByIdOrder($this->order->id)) {
$objHotelBranchInfo = new HotelBranchInformation((int) $idHotel, Context::getContext()->language->id);
$invoiceAddressPatternRules['avoid'][] = 'lastname';
if ($idHotelAddress = $objHotelBranchInfo->getHotelIdAddress()) {
$objHotelAddress = new Address((int) $idHotelAddress);
$objHotelAddress->firstname = $objHotelBranchInfo->hotel_name;
$formattedHotelAddress = AddressFormat::generateAddress($objHotelAddress, $invoiceAddressPatternRules, '<br />', ' ');
}
}
}
$customer = new Customer((int)$this->order->id_customer);
$getPaymentTypes = $this->order->getPaymentsTypes();
$this->orderPayment->payment_type = isset($getPaymentTypes[$this->orderPayment->payment_type]) ? $getPaymentTypes[$this->orderPayment->payment_type] : null;
$legal_free_text = Configuration::get('PS_PAYMENT_RECEIPTS_LEGAL_FREE_TEXT', (int)Context::getContext()->language->id, null, (int)$this->order->id_shop);
$this->smarty->assign(array(
'order' => $this->order,
'payment_list' => array($this->orderPayment),
'delivery_address' => $formatted_delivery_address,
'invoice_address' => $formatted_invoice_address,
'addresses' => array('invoice' => $invoice_address, 'delivery' => $delivery_address),
'customer' => $customer,
'hotel_address' => $formattedHotelAddress,
'legal_free_text' => $legal_free_text,
));
$smarty_tpls = array(
'style_tab' => $this->smarty->fetch($this->getTemplate('payment-receipt.style-tab')),
'addresses_tab' => $this->smarty->fetch($this->getTemplate('payment-receipt.addresses-tab')),
'payment_info_tab' => $this->smarty->fetch($this->getTemplate('payment-receipt.payment-info-tab')),
);
$this->smarty->assign($smarty_tpls);
return $this->smarty->fetch($this->getTemplate('payment-receipt'));
}
public function getFilename()
{
return 'payment-receipt-'.sprintf('%06d', $this->paymentReceipt->id).'.pdf';
}
public function getBulkFilename()
{
return 'payment-receipts.pdf';
}
protected function getPaymentType($paymentType = null)
{
$paymentTypeName = null;
switch ($paymentType) {
case OrderPayment::PAYMENT_TYPE_PAY_AT_HOTEL:
$paymentTypeName = HTMLTemplatePaymentReceipt::l('Pay at hotel');
break;
case OrderPayment::PAYMENT_TYPE_ONLINE:
$paymentTypeName = HTMLTemplatePaymentReceipt::l('Online');
break;
case OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT:
$paymentTypeName = HTMLTemplatePaymentReceipt::l('Remote payment');
break;
default:
$paymentTypeName = null;
break;
}
return $paymentTypeName;
}
}

View File

@@ -42,6 +42,7 @@ class PDFCore
const TEMPLATE_DELIVERY_SLIP = 'DeliverySlip';
const TEMPLATE_SUPPLY_ORDER_FORM = 'SupplyOrderForm';
const TEMPLATE_BOOKING_VOUCHER = 'BookingVoucher';
const TEMPLATE_PAYMENT_RECEIPT = 'PaymentReceipt';
/**
* @param $objects

View File

@@ -1,22 +1,52 @@
{
"require": {
"php": ">=5.4 <8.0",
"ext-simplexml": "*",
"ext-curl": "*",
"ext-gd": "*",
"ext-zip": "*",
"ext-soap": "*"
},
"name": "webkul/qloapps",
"name": "qloapps/qloapps",
"description": "QloApps is an Open-source and Free hotel reservation system and booking engine. With the help of QloApps, you can launch your hotel booking website without any cost and take & manage online bookings.",
"type": "project",
"homepage": "https://qloapps.com",
"license": "OSL-3.0",
"keywords": [
"qloapps",
"hospitality",
"booking-engine",
"hotel-booking-website",
"hotel-management-system",
"hotel-reservation-system",
"property-management-system",
"cms"
],
"authors": [
{
"name": "webkul",
"email": "support@qloapps.com"
"name": "QloApps",
"email": "support@qloapps.com",
"homepage": "https://qloapps.com"
},
{
"name": "QloApps Community",
"homepage": "https://github.com/Qloapps/QloApps/graphs/contributors"
}
],
"minimum-stability": "dev",
"prefer-stable": true
"support": {
"docs": "https://qloapps.com/docs/",
"email": "support@qloapps.com",
"forum": "https://forums.qloapps.com/",
"source": "https://github.com/Qloapps/QloApps"
},
"require": {
"php": ">8.0 <8.5",
"ext-curl": "*",
"ext-dom": "*",
"ext-gd": "*",
"ext-mcrypt": "*",
"ext-openssl": "*",
"ext-pdo_mysql": "*",
"ext-phar": "*",
"ext-simplexml": "*",
"ext-soap": "*",
"ext-zip": "*"
},
"minimum-stability": "stable",
"prefer-stable": true,
"config": {
"sort-packages": true
}
}

View File

@@ -56,7 +56,7 @@ class AdminAccessControllerCore extends AdminController
{
$current_profile = (int)$this->getCurrentProfileId();
$profiles = Profile::getProfiles($this->context->language->id);
$tabs = Tab::getTabs($this->context->language->id);
$tabs = Tab::getTabs($this->context->language->id, null, true);
$accesses = array();
foreach ($profiles as $profile) {
$accesses[$profile['id_profile']] = Profile::getProfileAccesses($profile['id_profile']);
@@ -214,7 +214,7 @@ class AdminAccessControllerCore extends AdminController
if (Tools::isSubmit('submitAddAccess')) {
$perm = Tools::getValue('perm');
if (!in_array($perm, array('view', 'add', 'edit', 'delete', 'all'))) {
if (!in_array($perm, array('view', 'add', 'edit', 'delete', 'all', 'kpi'))) {
throw new PrestaShopException('permission does not exist');
}

View File

@@ -168,6 +168,10 @@ class AdminDashboardControllerCore extends AdminController
return parent::renderOptions();
}
if ($this->tabAccess['kpi'] === 1) {
$this->content .= $this->renderKpis();
}
// $translations = array(
// 'Calendar' => $this->l('Calendar', 'AdminStatsTab'),
// 'Day' => $this->l('Day', 'AdminStatsTab'),

View File

@@ -470,7 +470,9 @@ class AdminOrdersControllerCore extends AdminController
}
$paymentTypes = array();
foreach ($this->getPaymentsTypes() as $paymentType) {
$objOrder = new Order();
foreach ($objOrder->getPaymentsTypes() as $paymentType) {
if ($paymentType['value'] != OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT) {
$paymentTypes[] = $paymentType;
}
@@ -685,7 +687,7 @@ class AdminOrdersControllerCore extends AdminController
'order' => $objOrder,
'currencies' => $currencies,
'payment_methods' => $payment_methods,
'payment_types' => $this->getPaymentsTypes(),
'payment_types' => $objOrder->getPaymentsTypes(),
'invoices_collection' => $objOrder->getInvoicesCollection(),
'current_id_lang' => $this->context->language->id,
)
@@ -3216,8 +3218,9 @@ class AdminOrdersControllerCore extends AdminController
if (!Validate::isLoadedObject($order = new Order(Tools::getValue('id_order')))) {
return;
}
$this->content .= $this->renderKpis();
if ($this->tabAccess['kpi'] === 1) {
$this->content .= $this->renderKpis();
}
$customer = new Customer($order->id_customer);
$carrier = new Carrier($order->id_carrier);
@@ -3766,8 +3769,9 @@ class AdminOrdersControllerCore extends AdminController
'invoices_collection' => $order->getInvoicesCollection(),
'not_paid_invoices_collection' => $order->getNotPaidInvoicesCollection(),
'payment_methods' => $payment_methods,
'payment_types' => $this->getPaymentsTypes(),
'payment_types' => $order->getPaymentsTypes(),
'invoice_management_active' => Configuration::get('PS_INVOICE', null, null, $order->id_shop),
'receipt_management_active' => Configuration::get('PS_PAYMENT_RECEIPTS', null, null, $order->id_shop),
'display_warehouse' => (int)Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'),
'HOOK_CONTENT_ORDER' => Hook::exec(
'displayAdminOrderContentOrder',
@@ -7276,26 +7280,6 @@ class AdminOrdersControllerCore extends AdminController
return $products;
}
protected function getPaymentsTypes()
{
return array(
OrderPayment::PAYMENT_TYPE_PAY_AT_HOTEL => array(
'key' => 'PAYMENT_TYPE_PAY_AT_HOTEL',
'value' => OrderPayment::PAYMENT_TYPE_PAY_AT_HOTEL,
'name' => $this->l('Pay at hotel')
),
OrderPayment::PAYMENT_TYPE_ONLINE => array(
'key' => 'PAYMENT_TYPE_ONLINE',
'value' => OrderPayment::PAYMENT_TYPE_ONLINE,
'name' => $this->l('Online')
),
OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT => array(
'key' => 'PAYMENT_TYPE_REMOTE_PAYMENT',
'value' => OrderPayment::PAYMENT_TYPE_REMOTE_PAYMENT,
'name' => $this->l('Remote payment')
),
);
}
/**
* @param OrderInvoice $order_invoice

View File

@@ -0,0 +1,192 @@
<?php
/**
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*/
class AdminPaymentReceiptsControllerCore extends AdminControllerCore
{
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
$this->context = Context::getContext();
$this->lang = false;
$this->table = 'order_payment';
$this->fields_options = array(
'general' => array(
'title' => $this->l('Payment receipts options'),
'fields' => array(
'PS_PAYMENT_RECEIPTS' => array(
'title' => $this->l('Enable Receipts'),
'desc' => $this->l('If enabled, receipts will be generated for order payments.'),
'cast' => 'intval',
'type' => 'bool'
),
'PS_PAYMENT_RECEIPTS_PREFIX' => array(
'title' => $this->l('Receipt prefix'),
'desc' => $this->l('Prefix used for receipt name (e.g. #IN00001).'),
'size' => 6,
'type' => 'textLang'
),
'PS_PAYMENT_RECEIPTS_USE_YEAR' => array(
'title' => $this->l('Add current year to receipt number'),
'cast' => 'intval',
'type' => 'bool'
),
'PS_PAYMENT_RECEIPTS_RESET' => array(
'title' => $this->l('Reset Receipt progressive number at beginning of the year'),
'cast' => 'intval',
'type' => 'bool'
),
'PS_PAYMENT_RECEIPTS_START_NUMBER' => array(
'title' => $this->l('Receipt number'),
'desc' => sprintf($this->l('The next receipt will begin with this number, and then increase with each additional receipt. Set to 0 if you want to keep the current number (which is #%s).'), OrderPaymentDetail::getLastPaymentReceiptNumber() + 1),
'size' => 6,
'type' => 'text',
'cast' => 'intval'
),
'PS_PAYMENT_RECEIPTS_LEGAL_FREE_TEXT' => array(
'title' => $this->l('Legal free text'),
'desc' => $this->l('Use this field to display additional text on your receipt, like specific legal information. It will appear below the payment methods summary.'),
'size' => 50,
'type' => 'textareaLang',
),
'PS_PAYMENT_RECEIPTS_FREE_TEXT' => array(
'title' => $this->l('Footer text'),
'desc' => $this->l('This text will appear at the bottom of the receipt, below your company details.'),
'size' => 50,
'type' => 'textLang',
)
),
'submit' => array('title' => $this->l('Save'))
)
);
}
public function initContent()
{
$this->display = 'edit';
$this->initTabModuleList();
$this->initToolbar();
$this->initPageHeaderToolbar();
$this->table = 'order_payment';
$this->content .= $this->initFormByDate();
$this->content .= $this->renderOptions();
$this->context->smarty->assign(array(
'content' => $this->content,
'url_post' => self::$currentIndex.'&token='.$this->token,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'page_header_toolbar_title' => $this->page_header_toolbar_title,
'page_header_toolbar_btn' => $this->page_header_toolbar_btn
));
}
public function initFormByDate()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->l('By date'),
'icon' => 'icon-calendar'
),
'input' => array(
array(
'type' => 'date',
'label' => $this->l('From'),
'name' => 'date_from',
'maxlength' => 10,
'required' => true,
'hint' => $this->l('Format: 2011-12-31 (inclusive).')
),
array(
'type' => 'date',
'label' => $this->l('To'),
'name' => 'date_to',
'maxlength' => 10,
'required' => true,
'hint' => $this->l('Format: 2012-12-31 (inclusive).')
)
),
'submit' => array(
'title' => $this->l('Generate PDF file by date'),
'id' => 'submitPrint',
'icon' => 'process-icon-download-alt'
)
);
$this->fields_value = array(
'date_from' => date('Y-m-d'),
'date_to' => date('Y-m-d')
);
$this->table = 'order_payment';
$this->show_toolbar = false;
$this->show_form_cancel_button = false;
$this->toolbar_title = $this->l('Print PDF invoices');
return parent::renderForm();
}
public function initToolbarTitle()
{
$this->toolbar_title = array_unique($this->breadcrumbs);
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
unset($this->page_header_toolbar_btn['cancel']);
}
public function postProcess()
{
if(Tools::isSubmit('submitAddorder_payment')) {
if (!Validate::isDate(Tools::getValue('date_from'))) {
$this->errors[] = $this->l('Invalid "From" date');
}
if (!Validate::isDate(Tools::getValue('date_to'))) {
$this->errors[] = $this->l('Invalid "To" date');
}
if(Tools::getValue('date_from') > Tools::getValue('date_to')) {
$this->errors[] = $this->l('"From" date must be earlier than "To" date');
}
if (!count($this->errors)) {
if (count(OrderPaymentDetail::getByDateInterval(Tools::getValue('date_from'), Tools::getValue('date_to')))) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminPdf').'&submitAction=generatePaymentReceiptsPDF&date_from='.urlencode(Tools::getValue('date_from')).'&date_to='.urlencode(Tools::getValue('date_to')));
}
$this->errors[] = $this->l('No payment receipt has been found for this period.');
}
}else{
parent::postProcess();
}
}
public function beforeUpdateOptions()
{
if ((int)Tools::getValue('PS_PAYMENT_RECEIPTS_START_NUMBER') != 0 && (int)Tools::getValue('PS_PAYMENT_RECEIPTS_START_NUMBER') <= OrderPaymentDetail::getLastPaymentReceiptNumber()) {
$this->errors[] = $this->l('Invalid receipt number.').OrderPaymentDetail::getLastPaymentReceiptNumber().')';
}
}
}

View File

@@ -102,7 +102,6 @@ class AdminPdfControllerCore extends AdminController
public function processGenerateInvoicesPDF()
{
$order_invoice_collection = OrderInvoice::getByDateInterval(Tools::getValue('date_from'), Tools::getValue('date_to'));
if (!count($order_invoice_collection)) {
die(Tools::displayError('No invoice was found.'));
}
@@ -159,14 +158,38 @@ class AdminPdfControllerCore extends AdminController
$id_supply_order = (int)Tools::getValue('id_supply_order');
$supply_order = new SupplyOrder($id_supply_order);
if (!Validate::isLoadedObject($supply_order)) {
die(Tools::displayError('The supply order cannot be found within your database.'));
}
$this->generatePDF($supply_order, PDF::TEMPLATE_SUPPLY_ORDER_FORM);
}
public function processGeneratePaymentReceiptsPDF()
{
$order_payment_collection = OrderPaymentDetail::getByDateInterval(
Tools::getValue('date_from'),
Tools::getValue('date_to')
);
if (!count($order_payment_collection)) {
die(Tools::displayError('No payment receipt was found.'));
}
$this->generatePDF($order_payment_collection, PDF::TEMPLATE_PAYMENT_RECEIPT);
}
public function processGeneratePaymentReceipt()
{
$idOrderPaymentDetail = (int) Tools::getValue('id_order_payment_detail');
$orderPaymentDetail = new OrderPaymentDetail($idOrderPaymentDetail);
if (!Validate::isLoadedObject($orderPaymentDetail)) {
die(Tools::displayError('The order payment detail cannot be found.'));
}
$this->generatePDF($orderPaymentDetail, PDF::TEMPLATE_PAYMENT_RECEIPT);
}
public function generateDeliverySlipPDFByIdOrder($id_order)
{
$order = new Order((int)$id_order);

View File

@@ -8,6 +8,7 @@ CREATE TABLE `PREFIX_access` (
`add` int(11) NOT NULL,
`edit` int(11) NOT NULL,
`delete` int(11) NOT NULL,
`kpi` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id_profile`,`id_tab`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;
@@ -1514,6 +1515,7 @@ CREATE TABLE `PREFIX_order_payment_detail` (
`id_order_payment` INT(10) unsigned NOT NULL,
`id_order` INT(10) unsigned NOT NULL,
`amount` DECIMAL(10,2) NOT NULL,
`receipt_number` INT(10) NOT NULL,
`date_add` DATETIME NOT NULL,
PRIMARY KEY (`id_order_payment_detail`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;

View File

@@ -133,6 +133,9 @@
</configuration>
<configuration id="PS_INVOICE_PREFIX" name="PS_INVOICE_PREFIX">
<value>#IN</value>
</configuration>
<configuration id="PS_PAYMENT_RECEIPTS_PREFIX" name="PS_PAYMENT_RECEIPTS_PREFIX">
<value>#IN</value>
</configuration>
<configuration id="PS_INVCE_INVOICE_ADDR_RULES" name="PS_INVCE_INVOICE_ADDR_RULES">
<value>{"avoid":[]}</value>
@@ -152,6 +155,9 @@
<configuration id="PS_INVOICE" name="PS_INVOICE">
<value>1</value>
</configuration>
<configuration id="PS_PAYMENT_RECEIPTS" name="PS_PAYMENT_RECEIPTS">
<value>1</value>
</configuration>
<configuration id="PS_PASSWD_TIME_BACK" name="PS_PASSWD_TIME_BACK">
<value>360</value>
</configuration>

View File

@@ -102,6 +102,9 @@
<tab id="Invoices" id_parent="Orders" active="1" hide_host_mode="0">
<class_name>AdminInvoices</class_name>
</tab>
<tab id="Payment_Receipts" id_parent="Orders" active="1" hide_host_mode="0">
<class_name>AdminPaymentReceipts</class_name>
</tab>
<!-- <tab id="Merchandise_Returns" id_parent="Orders" active="1" hide_host_mode="0">
<class_name>AdminReturn</class_name>
</tab> -->

View File

@@ -3,6 +3,9 @@
<configuration id="PS_INVOICE_PREFIX">
<value>#IN</value>
</configuration>
<configuration id="PS_PAYMENT_RECEIPTS_PREFIX" name="PS_PAYMENT_RECEIPTS_PREFIX">
<value>#IN</value>
</configuration>
<configuration id="PS_DELIVERY_PREFIX">
<value>#DE</value>
</configuration>

View File

@@ -32,6 +32,7 @@
<tab id="Attachments" name="Attachments"/>
<tab id="Orders_1" name="Orders"/>
<tab id="Invoices" name="Invoices"/>
<tab id="Payment_Receipts" name="Payment Receipts"/>
<!-- <tab id="Merchandise_Returns" name="Merchandise Returns"/> -->
<tab id="Delivery_Slips" name="Delivery Slips"/>
<tab id="Credit_Slips" name="Credit Slips"/>

View File

@@ -46,7 +46,7 @@ class DashGuestCycle extends Module
public function install()
{
return (parent::install()
&& $this->registerHook('dashboardTop')
&& $this->registerHook('actionAdminDashboardKPIListingModifier')
&& $this->registerHook('dashboardZoneTwo')
&& $this->registerHook('dashboardData')
&& $this->registerHook('actionAdminControllerSetMedia')
@@ -60,9 +60,120 @@ class DashGuestCycle extends Module
}
}
public function hookDashboardTop()
public function hookActionAdminDashboardKPIListingModifier(array $params)
{
return $this->display(__FILE__, 'dashboard-top.tpl');
$idHotel = (int)$this->context->cookie->stats_id_hotel;
$kpiValues = $this->getKpiValues($idHotel);
$kpisData = array(
array(
'id' => 'box-dgc-arrivals',
'color' => 'color1',
'title' => $this->l('Arrivals'),
'tooltip' => $this->l('The number of arrivals scheduled for today.'),
'value' => $kpiValues['box-dgc-arrivals'],
),
array(
'id' => 'box-dgc-departures',
'color' => 'color2',
'title' => $this->l('Departures'),
'tooltip' => $this->l('The number of departures scheduled for today.'),
'value' => $kpiValues['box-dgc-departures'],
),
array(
'id' => 'box-dgc-new-bookings',
'color' => 'color3',
'title' => $this->l('New Bookings'),
'tooltip' => $this->l('The number of new bookings created today so far.'),
'value' => $kpiValues['box-dgc-new-bookings'],
),
array(
'id' => 'box-dgc-occupied',
'color' => 'color4',
'title' => $this->l('Occupied Rooms'),
'tooltip' => $this->l('The count of rooms currently occupied by guests.'),
'value' => $kpiValues['box-dgc-occupied'],
),
array(
'id' => 'box-dgc-messages',
'color' => 'color5',
'title' => $this->l('Guest Messages'),
'tooltip' => $this->l('The number of new messages received from guests today.'),
'value' => $kpiValues['box-dgc-messages'],
),
array(
'id' => 'box-dgc-cancelled',
'color' => 'color6',
'title' => $this->l('Cancelled Bookings'),
'tooltip' => $this->l('The number of bookings cancelled today so far.'),
'value' => $kpiValues['box-dgc-cancelled'],
),
array(
'id' => 'box-dgc-guests',
'color' => 'color1',
'title' => $this->l('Guests (Adults/Children)'),
'tooltip' => $this->l('The number of adults and children scheduled to stay today.'),
'value' => $kpiValues['box-dgc-guests'],
),
);
foreach ($kpisData as $data) {
$helper = new HelperKpi();
$helper->id = $data['id'];
$helper->color = $data['color'];
$helper->title = $data['title'];
$helper->tooltip = $data['tooltip'];
$helper->value = $data['value'];
$params['kpis'][] = $helper;
}
}
private function getKpiValues($idHotel)
{
$dateToday = date('Y-m-d');
if (Configuration::get('PS_DASHBOARD_SIMULATION')) {
$totalArrivals = rand(100, 1000);
$arrived = rand(0, $totalArrivals);
$totalDepartures = rand(100, 1000);
$departed = rand(0, $totalDepartures);
$newBookings = rand(10, 500);
$occupied = rand(10, 500);
$newMessages = rand(0, 20);
$cancelledBookings = rand(0, 20);
$totalAdults = rand(100, 1000);
$children = rand(0, $totalAdults);
} else {
$arrivalsData = AdminStatsController::getArrivalsByDate($dateToday, $idHotel);
$departuresData = AdminStatsController::getDeparturesByDate($dateToday, $idHotel);
$guestsData = AdminStatsController::getGuestsByDate($dateToday, $idHotel);
$arrived = (int) $arrivalsData['arrived'];
$totalArrivals = (int) $arrivalsData['total_arrivals'];
$departed = (int) $departuresData['departed'];
$totalDepartures = (int) $departuresData['total_departures'];
$newBookings = count(AdminStatsController::getNewBookingsInfoByDate($dateToday, $idHotel));
$occupied = (int) AdminStatsController::getDistinctRoomBookingsCount(
date('Y-m-d', strtotime('-1 day')),
$dateToday,
$idHotel,
HotelBookingDetail::STATUS_CHECKED_IN
);
$newMessages = (int) CustomerMessage::getMessagesByDate($dateToday);
$cancelledBookings = (int) AdminStatsController::getCancelledBookingsByDate($dateToday, $idHotel);
$totalAdults = (int) $guestsData['adults'];
$children = (int) $guestsData['children'];
}
return array(
'box-dgc-arrivals' => sprintf('%02d', $arrived).'/'.sprintf('%02d', $totalArrivals),
'box-dgc-departures' => sprintf('%02d', $departed).'/'.sprintf('%02d', $totalDepartures),
'box-dgc-new-bookings' => sprintf('%02d', $newBookings),
'box-dgc-occupied' => sprintf('%02d', $occupied),
'box-dgc-messages' => sprintf('%02d', $newMessages),
'box-dgc-cancelled' => sprintf('%02d', $cancelledBookings),
'box-dgc-guests' => sprintf('%02d', $totalAdults).'/'.sprintf('%02d', $children),
);
}
public function hookDashboardZoneTwo()
@@ -76,37 +187,10 @@ class DashGuestCycle extends Module
$dataTable = array();
$dateToday = date('Y-m-d');
if (Configuration::get('PS_DASHBOARD_SIMULATION')) {
$dataValue['dgc_total_arrivals'] = sprintf('%02d', rand(100, 1000));
$dataValue['dgc_arrived'] = sprintf('%02d', rand(0, $dataValue['dgc_total_arrivals']));
$dataValue['dgc_total_departures'] = sprintf('%02d', rand(100, 1000));
$dataValue['dgc_departed'] = sprintf('%02d', rand(0, $dataValue['dgc_total_departures']));
$dataValue['dgc_new_bookings'] = sprintf('%02d', rand(10, 500));
$dataValue['dgc_occupied'] = sprintf('%02d', rand(10, 500));
$dataValue['dgc_new_messages'] = sprintf('%02d', rand(0, 20));
$dataValue['dgc_cancelled_bookings'] = sprintf('%02d', rand(0, 20));
$dataValue['dgc_guests_adults'] = sprintf('%02d', rand(100, 1000));
$dataValue['dgc_guests_children'] = sprintf('%02d', rand(0, $dataValue['dgc_guests_adults']));
} else {
// set badges data
$arrivalsData = AdminStatsController::getArrivalsByDate($dateToday, $params['id_hotel']);
$departuresData = AdminStatsController::getDeparturesByDate($dateToday, $params['id_hotel']);
$guestsData = AdminStatsController::getGuestsByDate($dateToday, $params['id_hotel']);
$dataValue['dgc_arrived'] = sprintf('%02d', $arrivalsData['arrived']);
$dataValue['dgc_total_arrivals'] = sprintf('%02d', $arrivalsData['total_arrivals']);
$dataValue['dgc_departed'] = sprintf('%02d', $departuresData['departed']);
$dataValue['dgc_total_departures'] = sprintf('%02d', $departuresData['total_departures']);
$dataValue['dgc_new_bookings'] = sprintf('%02d', count(AdminStatsController::getNewBookingsInfoByDate($dateToday, $params['id_hotel'])));
$dataValue['dgc_occupied'] = sprintf('%02d', AdminStatsController::getDistinctRoomBookingsCount(
date('Y-m-d', strtotime('-1 day')),
$dateToday,
$params['id_hotel'],
HotelBookingDetail::STATUS_CHECKED_IN
));
$dataValue['dgc_new_messages'] = sprintf('%02d', CustomerMessage::getMessagesByDate($dateToday));
$dataValue['dgc_cancelled_bookings'] = sprintf('%02d', AdminStatsController::getCancelledBookingsByDate($dateToday, $params['id_hotel']));
$dataValue['dgc_guests_adults'] = sprintf('%02d', $guestsData['adults']);
$dataValue['dgc_guests_children'] = sprintf('%02d', $guestsData['children']);
// KPI box values — updated on every AJAX refresh (demo toggle, date change)
foreach ($this->getKpiValues((int) $params['id_hotel']) as $boxId => $value) {
$dataValue[$boxId . ' .value'] = $value;
}
// set tables data

View File

@@ -20,76 +20,6 @@
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*/
#dashguestcycle {
padding-bottom: 5px;
}
#dashguestcycle .badges-wrapper {
white-space: nowrap;
overflow: auto;
margin: -5px;
margin-bottom: 0px;
padding-bottom: 10px;
font-size: 0;
}
#dashguestcycle .badge-wrapper {
display: inline-block;
width: 14.28%;
min-width: 145px;
padding: 5px;
}
#dashguestcycle .badge-item {
position: relative;
min-width: 135px;
height: 80px;
border-radius: 10px;
background: #FFFFFF;
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.15);
}
#dashguestcycle .badge-strip {
position: absolute;
width: 10px;
height: 100%;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
#dashguestcycle .badge-content-wrapper {
height: 100%;
}
#dashguestcycle .badge-content-wrapper p {
color: #00AFF0;
margin-bottom: 0;
}
#dashguestcycle .title-wrapper, #dashguestcycle .value-wrapper {
display: table;
width: 100%;
height: 50%;
padding: 0 10px;
}
#dashguestcycle .title-wrapper p {
display: table-cell;
vertical-align: middle;
font-weight: normal;
font-size: 13px;
line-height: 15px;
white-space: normal;
}
#dashguestcycle .value-wrapper p {
display: table-cell;
vertical-align: top;
font-weight: bold;
font-size: 24px;
line-height: 30px;
}
#dashguestcycle .tab-content {
max-height: 300px;
overflow-y: auto;
@@ -97,4 +27,107 @@
#dashguestcycle table tbody>tr>td {
padding: 8px 7px;
}
/* ── KPI row container: strip panel chrome ──────────────────────────────── */
.kpi-container {
background: transparent !important;
border: none !important;
box-shadow: none !important;
padding: 0 0 15px !important;
}
.kpi-container .kpis-wrap {
flex-wrap: nowrap !important;
overflow-x: auto;
gap: 8px;
margin: 0 !important;
}
.kpi-container .kpis-wrap .kpi-wrap {
width: 14.28% !important;
min-width: 110px;
padding: 0 !important;
margin-bottom: 0 !important;
}
.kpi-container .box-stats {
height: 80px !important;
background: #fff !important;
border-radius: 10px !important;
overflow: hidden;
font-size: inherit !important;
}
.kpi-container .box-stats .kpi-content {
border: none !important;
border-left: 10px solid !important;
border-radius: 0 !important;
height: 100% !important;
padding: 8px 12px !important;
align-items: center !important;
gap: 0 !important;
}
.kpi-container .box-stats .kpi-content .kpi-data {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
gap: 4px;
}
.kpi-container .box-stats .kpi-content .title-subtitle {
justify-content: center !important;
width: 100%;
}
.kpi-container .box-stats .kpi-content .title-subtitle .title-container .title {
font-size: 13px !important;
font-weight: normal !important;
color: #555 !important;
display: block;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.kpi-container .box-stats .kpi-content .value-container {
width: 100%;
text-align: center;
}
.kpi-container .box-stats .kpi-content .value-container .value {
font-size: 24px !important;
font-weight: bold !important;
min-height: auto !important;
display: block;
text-align: center;
}
.kpi-container .box-stats .kpi-content .arrow {
display: none !important;
}
.kpi-container .box-stats.color1 .kpi-content { border-left-color: #266FFE !important; }
.kpi-container .box-stats.color1 .value { color: #266FFE !important; }
.kpi-container .box-stats.color2 .kpi-content { border-left-color: #72C3F0 !important; }
.kpi-container .box-stats.color2 .value { color: #72C3F0 !important; }
.kpi-container .box-stats.color3 .kpi-content { border-left-color: #56CE56 !important; }
.kpi-container .box-stats.color3 .value { color: #56CE56 !important; }
.kpi-container .box-stats.color4 .kpi-content { border-left-color: #FFC148 !important; }
.kpi-container .box-stats.color4 .value { color: #FFC148 !important; }
.kpi-container .box-stats.color5 .kpi-content { border-left-color: #A569DF !important; }
.kpi-container .box-stats.color5 .value { color: #A569DF !important; }
.kpi-container .box-stats.color6 .kpi-content { border-left-color: #FF4036 !important; }
.kpi-container .box-stats.color6 .value { color: #FF4036 !important; }
.kpi-container .actions-wrap {
display: none !important;
}

View File

@@ -1,143 +0,0 @@
{**
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*}
<div class="row">
<div class="col-xs-12">
<section id="dashguestcycle" class="dashboard-top widget allow_push">
<div class="badges-wrapper">
{hook h="displayDashboardBadgeListBefore"}
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The number of arrivals scheduled for today.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #266FFE;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">{l s="Arrivals" mod='dashguestcycle'}</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_arrived"></span>/<span id="dgc_total_arrivals"></span>
</p>
</div>
</div>
</div>
</div>
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The number of departures scheduled for today.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #72C3F0;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">{l s="Departures" mod='dashguestcycle'}</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_departed"></span>/<span id="dgc_total_departures"></span>
</p>
</div>
</div>
</div>
</div>
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The number of new bookings created today so far.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #56CE56;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">{l s="New Bookings" mod='dashguestcycle'}</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_new_bookings"></span>
</p>
</div>
</div>
</div>
</div>
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The count of rooms that are currently occupied by guests.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #FFC148;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">{l s='Occupied Rooms' mod='dashguestcycle'}</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_occupied"></span>
</p>
</div>
</div>
</div>
</div>
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The number of new messages received from guests today.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #A569DF;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">
{l s="Guest Messages" mod='dashguestcycle'}
</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_new_messages"></span>
</p>
</div>
</div>
</div>
</div>
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The number of bookings cancelled today so far.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #FF4036;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">
{l s="Cancelled Bookings" mod='dashguestcycle'}
</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_cancelled_bookings"></span>
</p>
</div>
</div>
</div>
</div>
<div class="badge-wrapper">
<div class="badge-item label-tooltip" data-toggle="tooltip" data-original-title="{l s='The number of adults and children scheduled to stay today.' mod='dashguestcycle'}">
<div class="badge-strip" style="background-color: #FF809E;"></div>
<div class="badge-content-wrapper">
<div class="title-wrapper">
<p class="text-center">
{l s="Guests (Adults/Children)" mod='dashguestcycle'}
</p>
</div>
<div class="value-wrapper">
<p class="text-center">
<span id="dgc_guests_adults"></span>/<span id="dgc_guests_children"></span>
</p>
</div>
</div>
</div>
</div>
{hook h="displayDashboardBadgeListAfter"}
</div>
</section>
</div>
</div>

View File

@@ -51,7 +51,7 @@ class HotelBranchInformation extends ObjectModel
'fields' => array(
'id_category' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'email' => array('type' => self::TYPE_STRING,'validate' => 'isEmail', 'size' => 255, 'required' => true),
'rating' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
'rating' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'check_in' => array('type' => self::TYPE_STRING, 'required' => true),
'check_out' => array('type' => self::TYPE_STRING, 'required' => true),
'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
@@ -1160,7 +1160,7 @@ class HotelBranchInformation extends ObjectModel
{
// set additional hotel address and restriction fields validations here
if (isset($this->webservice_validation) && $this->webservice_validation) {
if ($this->rating < 1 || $this->rating > 5) {
if ($this->rating && ($this->rating < 1 || $this->rating > 5)) {
$message = Tools::displayError('Rating must be between 1 and 5.');
} elseif (!strtotime($this->check_in)) {
$message = Tools::displayError('Check In time is invalid.');

View File

@@ -391,10 +391,6 @@ class AdminAddHotelController extends ModuleAdminController
$this->errors[] = $this->l('Check Out time must be before Check In time.');
}
if (!$rating) {
$this->errors[] = $this->l('Rating is required field.');
}
if (!$address = trim($address)) {
$this->errors[] = $this->l('Address is required field.');
}

View File

@@ -214,11 +214,11 @@
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3 required" for="hotel_country">{l s='Rating :' mod='hotelreservationsystem'}</label>
<label class="control-label col-sm-3 " for="hotel_country">{l s='Rating :' mod='hotelreservationsystem'}</label>
<div class="col-sm-6">
<div style="width: 195px;">
<select class="form-control" name="hotel_rating" id="hotel_rating" value="">
<option value="">{l s='No star' mod='hotelreservationsystem'}</option>
<option value="0">{l s='No star' mod='hotelreservationsystem'}</option>
<option value="1" {if (isset($smarty.post.hotel_rating) && $smarty.post.hotel_rating == '1') || isset($edit) && $hotel_info['rating'] == '1'}selected{/if}>*</option>
<option value="2" {if (isset($smarty.post.hotel_rating) && $smarty.post.hotel_rating == '2') || isset($edit) && $hotel_info['rating'] == '2'}selected{/if}>**</option>
<option value="3" {if (isset($smarty.post.hotel_rating) && $smarty.post.hotel_rating == '3') || isset($edit) && $hotel_info['rating'] == '3'}selected{/if}>***</option>

View File

@@ -1,5 +1,5 @@
<div class="copyRightWrapper">
<p class="copyRight">
&copy;{if isset($WK_HTL_ESTABLISHMENT_YEAR) && $WK_HTL_ESTABLISHMENT_YEAR} {$WK_HTL_ESTABLISHMENT_YEAR}-{'Y'|date}&nbsp;{/if}<a href="{$base_dir}">&nbsp;{$WK_HTL_CHAIN_NAME}</a>.&nbsp;{l s=' All rights reserved.' mod='hotelreservationsystem'}
&copy;{if isset($WK_HTL_ESTABLISHMENT_YEAR) && $WK_HTL_ESTABLISHMENT_YEAR} {$WK_HTL_ESTABLISHMENT_YEAR}-{'Y'|date}&nbsp;{/if}<a href="{$base_dir}">&nbsp;{$WK_HTL_CHAIN_NAME}</a>.&nbsp;{l s=' All rights reserved. | Powered by' mod='hotelreservationsystem'} <a href="https://qloapps.com/" target="_blank">QloApps</a>
</p>
</div>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>wkfooterlangcurrencyblock</name>
<displayName><![CDATA[Display Language and Currency Block]]></displayName>
<version><![CDATA[1.0.1]]></version>
<description><![CDATA[Contains language and currency block in footer.]]></description>
<author><![CDATA[webkul]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>0</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,49 @@
{*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*}
<table id="addresses-tab" cellspacing="0" cellpadding="0">
<tr>
<!-- <td width="33%"><span class="bold"> </span><br/><br/>
{if isset($order_invoice)}{$order_invoice->shop_address}{/if}
</td> -->
<!-- <td width="33%">{if $delivery_address}<span class="bold">{l s='Delivery Address' pdf='true'}</span><br/><br/>
{$delivery_address}
{/if}
</td> -->
<td width="33%">
{if !empty($hotel_address)}
<span class="bold">{l s='Hotel Detail' pdf='true'}</span><br/><br/>
{$hotel_address}
{/if}
</td>
<td width="33%"></td>
<td width="33%">
<span class="bold">{l s='Customer Detail' pdf='true'}</span><br/><br/>
{if $invoice_address}
{$invoice_address}
{else}
{$customer->firstname} {$customer->lastname}
<br>
{$customer->phone}
{/if}
</td>
</tr>
</table>

View File

@@ -0,0 +1,50 @@
{*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*}
{if isset($payment_list) && $payment_list}
<table class="bordered-table" width="100%" cellpadding="4" cellspacing="0">
<thead>
<tr>
<th class="header" colspan="5">{l s='Payment Details' pdf='true'}</th>
</tr>
<tr class="header left">
<th class="product header-left small ">{l s='Payment Method' pdf='true'}</th>
<th class="product header-left small ">{l s='Payment Type' pdf='true'}</th>
<th class="product header-left small ">{l s='Transaction ID' pdf='true'}</th>
<th class="product header-left small ">{l s='Amount' pdf='true'}</th>
<th class="product header-left small">{l s='Payment Date' pdf='true'}</th>
</tr>
</thead>
<tbody>
{foreach from=$payment_list key=rm_k item=payment}
{cycle values=["color_line_even", "color_line_odd"] assign=bgcolor_class}
<tr class="white {$bgcolor_class}">
<td class="product {if $payment->payment_method|default:'-' == '-'}center{else}left{/if}">{$payment->payment_method|default:'-'}</td>
<td class="product {if $payment->payment_type|default:'-' == '-'}center{else}left{/if}">{$payment->payment_type.name|default:'-'}</td>
<td class="product {if $payment->transaction_id|default:'-' == '-'}center{else}left{/if}">{$payment->transaction_id|default:'-'}</td>
<td class="product {if $payment->amount|default:'-' == '-'}center{else}left{/if}">{displayPrice currency=$payment->id_currency price=$payment->amount}</td>
<td class="product {if $payment->date_add|default:'-' == '-'}center{else}left{/if}">{dateFormat date=$payment->date_add full=true}</td>
</tr>
{/foreach}
</tbody>
</table>
{/if}

View File

@@ -0,0 +1,200 @@
{*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*}
{assign var=color_header value="#F0F0F0"}
{assign var=color_border value="#000000"}
{assign var=color_border_lighter value="#CCCCCC"}
{assign var=color_line_even value="#FFFFFF"}
{assign var=color_line_odd value="#F9F9F9"}
{assign var=font_size_text value="9pt"}
{assign var=font_size_header value="9pt"}
{assign var=font_size_product value="9pt"}
{assign var=height_header value="20px"}
{assign var=table_padding value="4px"}
<style>
table, th, td {
margin: 0!important;
padding: 0!important;
vertical-align: middle;
font-size: {$font_size_text};
white-space: nowrap;
}
table.product {
border: 1px solid {$color_border};
border-collapse: collapse;
}
table#addresses-tab tr td {
font-size: large;
}
table#summary-tab {
padding: {$table_padding};
border: 1px solid {$color_border};
}
table#total-tab {
padding: {$table_padding};
border: 1px solid {$color_border};
}
table#tax-tab {
padding: {$table_padding};
border: 1px solid {$color_border};
}
table#payment-tab {
padding: {$table_padding};
border: 1px solid {$color_border};
}
table.bordered-table td, table.bordered-table th {
border: 1px solid {$color_border_lighter};
margin-bottom: -1px;
}
.border-right-td {
border-right: 1px solid {$color_border_lighter};
}
.pull-right {
float: right;
}
th.product {
border-bottom: 1px solid {$color_border};
}
tr.discount th.header {
border-top: 1px solid {$color_border};
}
tr.product td {
border-bottom: 1px solid {$color_border_lighter};
}
tr.color_line_even {
background-color: {$color_line_even};
}
tr.color_line_odd {
background-color: {$color_line_odd};
}
tr.customization_data td {
}
td.product {
vertical-align: middle;
font-size: {$font_size_product};
}
th.header {
font-size: {$font_size_header};
height: {$height_header};
background-color: {$color_header};
vertical-align: middle;
text-align: center;
font-weight: bold;
}
th.header-right {
font-size: {$font_size_header};
height: {$height_header};
background-color: {$color_header};
vertical-align: middle;
text-align: right;
font-weight: bold;
}
th.header-left {
font-size: {$font_size_header};
height: {$height_header};
background-color: {$color_header};
vertical-align: middle;
text-align: left;
font-weight: bold;
}
th.payment {
background-color: {$color_header};
vertical-align: middle;
font-weight: bold;
}
th.tva {
background-color: {$color_header};
vertical-align: middle;
font-weight: bold;
}
tr.separator td {
border-top: 1px solid #000000;
}
.left {
text-align: left!important;
}
.fright {
float: right;
}
.right {
text-align: right;
}
.center {
text-align: center;
}
.bold {
font-weight: bold;
}
.border {
border: 1px solid black;
}
.no_top_border {
border-top:hidden;
border-bottom:1px solid black;
border-left:1px solid black;
border-right:1px solid black;
}
.grey {
background-color: {$color_header};
}
/* This is used for the border size */
.white {
background-color: #FFFFFF;
}
.big,
tr.big td{
font-size: 110%;
}
.small, table.small th, table.small td {
font-size:small;
}
.tr-border-top td, .tr-border-top th {
border-top:1px solid {$color_border_lighter};
}
</style>

76
pdf/payment-receipt.tpl Normal file
View File

@@ -0,0 +1,76 @@
{*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License version 3.0
* that is bundled with this package in the file LICENSE.md
* It is also available through the world-wide-web at this URL:
* https://opensource.org/license/osl-3-0-php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to support@qloapps.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade this module to a newer
* versions in the future. If you wish to customize this module for your needs
* please refer to https://store.webkul.com/customisation-guidelines for more information.
*
* @author Webkul IN
* @copyright Since 2010 Webkul
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
*}
{$style_tab}
<table width="100%" id="body" border="0" cellpadding="0" cellspacing="0" style="margin:0;">
<!-- Receipt -->
<tr>
<td colspan="12">
{$addresses_tab}
</td>
</tr>
<tr>
<td colspan="12" height="30">&nbsp;</td>
</tr>
<!-- Payment Info -->
<tr>
<td colspan="12">
{$payment_info_tab}
</td>
</tr>
<tr>
<td colspan="12" height="20">&nbsp;</td>
</tr>
<tr>
<td colspan="12" class="left small">
<table>
<tr>
<td>
<p>{$legal_free_text|escape:'html':'UTF-8'|nl2br}</p>
</td>
</tr>
</table>
</td>
</tr>
<!-- Hook -->
{if isset($HOOK_DISPLAY_PDF)}
<tr>
<td colspan="12" height="30">&nbsp;</td>
</tr>
<tr>
<td colspan="12">
{$HOOK_DISPLAY_PDF}
</td>
</tr>
{/if}
</table>