Merge branch 'develop' into standard-product-changes
This commit is contained in:
@@ -48,7 +48,11 @@
|
||||
@include left(1px)
|
||||
@include box-shadow(white 0 0 0 3px inset)
|
||||
|
||||
|
||||
.table.customer_thread, #MeaningStatus
|
||||
.text-success
|
||||
color: #56CE56
|
||||
.text-warning
|
||||
color: #FCC94F
|
||||
|
||||
.message-item-initial
|
||||
h2
|
||||
|
||||
@@ -84,6 +84,11 @@
|
||||
.panel-refund-request .refunded_amount
|
||||
margin-top: 2px
|
||||
|
||||
.order-notes
|
||||
.panel-content
|
||||
max-height: 240px
|
||||
overflow: auto
|
||||
|
||||
.panel-guest_address
|
||||
.panel-heading
|
||||
align-items: center
|
||||
|
||||
@@ -443,3 +443,9 @@
|
||||
@extend .icon-toggle-on
|
||||
.process-icon-toggle-off
|
||||
@extend .icon-toggle-off
|
||||
.process-icon-reply-all
|
||||
@extend .icon-reply-all
|
||||
.process-icon-mail-reply
|
||||
@extend .icon-mail-reply
|
||||
.process-icon-lock
|
||||
@extend .icon-lock
|
||||
|
||||
@@ -25,65 +25,21 @@
|
||||
|
||||
{extends file="helpers/list/list_header.tpl"}
|
||||
|
||||
{block name="leadin"}
|
||||
<div id="CustomerThreadContacts" class="row">
|
||||
{assign var=nb_categories value=count($categories)}
|
||||
{foreach $categories as $key => $val}
|
||||
|
||||
{assign var=total_thread value=0}
|
||||
{assign var=id_customer_thread value=0}
|
||||
|
||||
{foreach $contacts as $tmp => $tmp2}
|
||||
{if $val.id_contact == $tmp2.id_contact}
|
||||
{assign var=total_thread value=$tmp2.total}
|
||||
{assign var=id_customer_thread value=$tmp2.id_customer_thread}
|
||||
{/if}
|
||||
{/foreach}
|
||||
<div class="col-lg-3">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
{$val.name}
|
||||
</div>
|
||||
{if $nb_categories < 6}
|
||||
<p>{$val.description}</p>
|
||||
{/if}
|
||||
{if $total_thread == 0}
|
||||
<span class="message-mail">{l s='No new messages'}</span>
|
||||
{else}
|
||||
<a href="{$currentIndex|escape:'html':'UTF-8'}&token={$token|escape:'html':'UTF-8'}&id_customer_thread={$id_customer_thread}&viewcustomer_thread" class="button">
|
||||
{$total_thread}
|
||||
{if $total_thread > 1}{l s='New messages'}{else}{l s='New message'}{/if}
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
<div class="col-lg-3">
|
||||
<div id="MeaningStatus" class="panel">
|
||||
<div class="panel-heading">
|
||||
{l s='Meaning of status'}
|
||||
</div>
|
||||
{block name="list_filter_items" append}
|
||||
<div class="pull-right col-xs-4 col-sm-3 col-md-2 col-lg-2">
|
||||
<div class="list_availibility_container">
|
||||
<button type="button" class="btn btn-default btn-left btn-block dropdown-toggle" data-toggle="dropdown" data-target="MeaningStatus">
|
||||
<span>{l s='Thread Statuses'}
|
||||
<i class="icon-caret-down pull-right"></i>
|
||||
</button>
|
||||
<div id="MeaningStatus" class="dropdown-menu">
|
||||
<ul class="list-unstyled">
|
||||
<li class="text-success"><i class="icon-circle"></i> {l s='Open'}</li>
|
||||
<li class="text-danger"><i class="icon-circle"></i> {l s='Closed'}</li>
|
||||
<li class="text-warning"><i class="icon-circle"></i> {l s='Pending 1'}</li>
|
||||
<li class="text-warning"><i class="icon-circle"></i> {l s='Pending 2'}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<div id="CustomerService" class="panel">
|
||||
<div class="panel-heading">
|
||||
{l s='Statistics'}
|
||||
</div>
|
||||
<ul class="list-unstyled">
|
||||
{assign var=count value=0}
|
||||
{foreach $params as $key => $val}
|
||||
{assign var=count value=$count+1}
|
||||
<li>{$key} <span class="badge">{$val}</span></li>
|
||||
{/foreach}
|
||||
<li><p><i class="icon-circle text-success"></i> {l s='Open'}</p></li>
|
||||
<li><p><i class="icon-circle text-danger"></i> {l s='Closed'}</p></li>
|
||||
<li><p><i class="icon-circle text-warning"></i> {l s='Pending 1'}</p></li>
|
||||
<li><p><i class="icon-circle text-warning"></i> {l s='Pending 2'}</p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{/block}
|
||||
|
||||
@@ -45,14 +45,15 @@
|
||||
{if !$initial}
|
||||
<h4 class="message-item-heading">
|
||||
<i class="icon-mail-reply text-muted"></i>
|
||||
{if $type == 'customer'}
|
||||
{$message.customer_name|escape:'html':'UTF-8'}
|
||||
{else}
|
||||
{$message.employee_name|escape:'html':'UTF-8'}
|
||||
{/if}
|
||||
{if $type == 'customer'}
|
||||
{$message.customer_name|escape:'html':'UTF-8'}
|
||||
{else}
|
||||
{$message.employee_name|escape:'html':'UTF-8'}
|
||||
{/if}
|
||||
</h4>
|
||||
{/if}
|
||||
<span class="message-date"> <i class="icon-calendar"></i> - {dateFormat date=$message.date_add full=0} - <i class="icon-time"></i> {$message.date_add|substr:11:5}</span>
|
||||
{if $message.private}<span class="badge badge-info">{l s='Private'}</span>{/if}
|
||||
{if isset($message.file_name)} <span class="message-product"> <i class="icon-link"></i> <a href="{$message.file_name|escape:'html':'UTF-8'}" class="_blank">{l s="Attachment"}</a></span>{/if}
|
||||
{if isset($message.product_name)} <span class="message-attachment"> <i class="icon-book"></i> <a href="{$message.product_link|escape:'html':'UTF-8'}" class="_blank">{l s="Room type:"} {$message.product_name|escape:'html':'UTF-8'} </a></span>{/if}
|
||||
<p class="message-item-text">{$message.message|escape:'html':'UTF-8'|nl2br}</p>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
<div class="panel-heading">
|
||||
<i class="icon-comments"></i>
|
||||
{l s="Thread"}: <span class="badge">#{$id_customer_thread|intval}</span>
|
||||
{if isset($next_thread) && $next_thread}
|
||||
<a class="btn btn-default pull-right" href="{$next_thread.href|escape:'html':'UTF-8'}">
|
||||
{$next_thread.name} <i class="icon-forward"></i>
|
||||
{if isset($thread->id_customer) && $thread->id_customer}
|
||||
<a class="pull-right" href="{$link->getAdminLink('AdminCustomers')|escape:'html':'UTF-8'}&id_customer={$customer->id|intval}&viewcustomer&">
|
||||
{$customer->firstname} {$customer->lastname}<small>({$customer->email|escape:'html':'UTF-8'})</small>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -50,24 +50,25 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="message-item-initial media">
|
||||
<a href="{if isset($customer->id)}{$link->getAdminLink('AdminCustomers')|escape:'html':'UTF-8'}&id_customer={$customer->id|intval}&viewcustomer&{else}#{/if}" class="avatar-lg pull-left"><i class="icon-user icon-3x"></i></a>
|
||||
<span class="avatar-md pull-left"><i class="icon-user icon-3x"></i></span>
|
||||
<div class="media-body">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
{if isset($customer->firstname)}
|
||||
{if isset($thread->user_name) && trim($thread->user_name)}
|
||||
<h2>
|
||||
<a href="{$link->getAdminLink('AdminCustomers')|escape:'html':'UTF-8'}&id_customer={$customer->id|intval}&viewcustomer&">
|
||||
{$customer->firstname|escape:'html':'UTF-8'} {$customer->lastname|escape:'html':'UTF-8'} <small>({$customer->email|escape:'html':'UTF-8'})</small>
|
||||
</a>
|
||||
{$thread->user_name|escape:'html':'UTF-8'} <small>({$thread->email|escape:'html':'UTF-8'})</small>
|
||||
</h2>
|
||||
{else}
|
||||
<h2>{$thread->email|escape:'html':'UTF-8'}</h2>
|
||||
{/if}
|
||||
{if isset($thread->phone) && trim($thread->phone) != ''}
|
||||
<p>{l s='Phone:'} {$thread->phone|escape:'html':'UTF-8'}</p>
|
||||
{/if}
|
||||
{if isset($contact) && trim($contact) != ''}
|
||||
<span>{l s="To:"} </span><span class="badge">{$contact|escape:'html':'UTF-8'}</span>
|
||||
<span>{l s='To:'} </span><span class="badge">{$contact|escape:'html':'UTF-8'}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{if isset($customer->firstname)}
|
||||
{if isset($customer->email) && $customer->email == $thread->email}
|
||||
<div class="col-sm-6">
|
||||
<p>
|
||||
{if $count_ok}
|
||||
@@ -116,7 +117,9 @@
|
||||
{l s="Choose a template"}
|
||||
</button>
|
||||
-->
|
||||
<button class="btn btn-default pull-right" name="submitReply"><i class="process-icon-mail-reply"></i> {l s="Send"}</button>
|
||||
<button class="btn btn-default" name="submitReplyAndClose"><i class="process-icon-reply-all"></i> {l s='Reply And Close'}</button>
|
||||
<button class="btn btn-default pull-right" name="submitReply"><i class="process-icon-mail-reply"></i> {l s='Reply And Open'}</button>
|
||||
<button class="btn btn-default pull-right" name="submitReplyAsPrivate"><i class="process-icon-lock"></i> {l s='Add Private Message'}</button>
|
||||
<input type="hidden" name="id_customer_thread" value="{$thread->id|intval}" />
|
||||
<input type="hidden" name="msg_email" value="{$thread->email}" />
|
||||
</div>
|
||||
@@ -180,5 +183,3 @@
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
{**
|
||||
* 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
|
||||
*}
|
||||
|
||||
{extends file="page_header_toolbar.tpl"}
|
||||
|
||||
{block name=pageTitle}
|
||||
{if isset($display) && $display == 'view'}
|
||||
<h2 class="page-title">
|
||||
{if is_array($title)}
|
||||
{$title|end|strip_tags}
|
||||
{else}
|
||||
<span title="{$title}">
|
||||
{$title|strip_tags|truncate:40}
|
||||
</span>
|
||||
{/if}
|
||||
</h2>
|
||||
{else}
|
||||
{$smarty.block.parent}
|
||||
{/if}
|
||||
{/block}
|
||||
@@ -501,13 +501,22 @@
|
||||
{if count($messages)}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th><span class="title_box">{l s='Status'}</span></th>
|
||||
<th class="fixed-width-sm"><span class="title_box">{l s='Status'}</span></th>
|
||||
<th><span class="title_box">{l s='Message'}</span></th>
|
||||
<th><span class="title_box">{l s='Sent on'}</span></th>
|
||||
<th class="fixed-width-lg"><span class="title_box">{l s='Sent on'}</span></th>
|
||||
</thead>
|
||||
{foreach $messages AS $message}
|
||||
<tr>
|
||||
<td>{$message['status']}</td>
|
||||
<td>{if $message['status'] == CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN}
|
||||
{l s='Open'}
|
||||
{elseif $message['status'] == CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED}
|
||||
{l s='Closed'}
|
||||
{elseif $message['status'] == CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1}
|
||||
{l s='Pending 1'}
|
||||
{elseif $message['status'] == CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2}
|
||||
{l s='Pending 2'}
|
||||
{/if}
|
||||
</td>
|
||||
<td>
|
||||
<a href="index.php?tab=AdminCustomerThreads&id_customer_thread={$message.id_customer_thread}&viewcustomer_thread&token={getAdminToken tab='AdminCustomerThreads'}">
|
||||
{$message['message']}...
|
||||
|
||||
@@ -319,7 +319,7 @@
|
||||
id_cart: id_cart,
|
||||
id_customer: id_customer,
|
||||
message: $(this).val()
|
||||
},
|
||||
},
|
||||
success : function(res)
|
||||
{
|
||||
displaySummary(res);
|
||||
@@ -2305,6 +2305,15 @@
|
||||
<textarea name="order_message" id="order_message" rows="3" cols="45"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-lg-12">
|
||||
<span class="col-lg-3"></span>
|
||||
<p class="checkbox col-lg-6">
|
||||
<label class="control-label" for="visibility">
|
||||
<input type="checkbox" name="visibility" id="visibility" value="1" />
|
||||
{l s='Display Message to Customer?'}
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group" {if $order_total <= 0}style="display: none;"{/if}>
|
||||
{if !$PS_CATALOG_MODE}
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
|
||||
@@ -704,13 +704,13 @@
|
||||
</div>
|
||||
|
||||
{* Order Internal notes *}
|
||||
{if (sizeof($messages))}
|
||||
<div class="panel">
|
||||
{if isset($messages) && $messages}
|
||||
<div class="panel order-notes">
|
||||
<div class="panel-heading">
|
||||
<i class="icon-undo"></i> {l s='Order Notes'}
|
||||
<i class="icon-undo"></i> {l s='Order Private Notes'}
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
{foreach from=$messages item=message}
|
||||
{foreach from=$messages item=message name=customerMessage}
|
||||
<div class="message-body">
|
||||
<p class="message-item-text">
|
||||
{$message['message']|escape:'html':'UTF-8'|nl2br}
|
||||
@@ -727,6 +727,7 @@
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
{if !$smarty.foreach.customerMessage.last}<hr/>{/if}
|
||||
{* {if ($message['is_new_for_me'])}
|
||||
<a class="new_message" title="{l s='Mark this message as \'viewed\''}" href="{$smarty.server.REQUEST_URI}&token={$smarty.get.token}&messageReaded={$message['id_message']}">
|
||||
<i class="icon-ok"></i>
|
||||
@@ -1214,7 +1215,11 @@
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<i class="icon-envelope"></i> {l s='Messages'} <span class="badge">{sizeof($customer_thread_message)}</span>
|
||||
<a href="{$link->getAdminLink('AdminCustomerThreads')|escape:'html':'UTF-8'}&id_order={$order->id|intval}" class="pull-right">{l s='Show all messages'}</a>
|
||||
{if $id_customer_thread}
|
||||
<a href="{$link->getAdminLink('AdminCustomerThreads')|escape:'html':'UTF-8'}&viewcustomer_thread&id_customer_thread={$id_customer_thread|intval}" class="pull-right ">{l s='Show all messages'}</a>
|
||||
{else}
|
||||
<a href="{$link->getAdminLink('AdminCustomerThreads')|escape:'html':'UTF-8'}" class="pull-right">{l s='Show all messages'}</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div id="messages">
|
||||
{if $can_edit}
|
||||
|
||||
@@ -194,237 +194,241 @@
|
||||
</script>
|
||||
{block name="updatelist"}
|
||||
{if $new_list_header_design}
|
||||
<div class="list_action_wrapper">
|
||||
<div class="row">
|
||||
{if $fields_optional|count}
|
||||
<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}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if !$simple_header && $show_filters}
|
||||
<div class="col-xs-3 col-xs-offset-{if $fields_optional|count}}5{else}9{/if} col-sm-2 col-sm-offset-{if $fields_optional|count}}7{else}10{/if} col-md-1 col-md-offset-{if $fields_optional|count}9{else}11{/if}">
|
||||
<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>
|
||||
{/if}
|
||||
</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.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`"}
|
||||
{block name="list_action_wrapper"}
|
||||
<div class="list_action_wrapper">
|
||||
<div class="row">
|
||||
{block name="list_filter_items"}
|
||||
{if $fields_optional|count}
|
||||
<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}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if !$simple_header && $show_filters}
|
||||
<div class="col-xs-3 col-sm-2 col-md-1 pull-right">
|
||||
<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>
|
||||
{/if}
|
||||
{/block}
|
||||
</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.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}
|
||||
{/if}
|
||||
{/foreach}
|
||||
{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}
|
||||
{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}
|
||||
{/foreach}
|
||||
{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}
|
||||
{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'}
|
||||
<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'}{else}{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['list'][$params['value']]|replace: ' ' : ''}</span>
|
||||
{$params['title']|escape:'html':'UTF-8'}: <span class="filter_value">{$params['value']|escape:'html':'UTF-8'}</span>
|
||||
<i class="icon-times"></i>
|
||||
</span>
|
||||
{/if}
|
||||
{elseif $params.type == 'bool'}
|
||||
<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'}{else}{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'}
|
||||
{$field_name="`$list_id`Filter_{if isset($params.filter_key)}`$params.filter_key`{else}`$key`{/if}"}
|
||||
<div class="input_range">
|
||||
<input type="text" class="filter form-control" name="{$field_name}[0]" placeholder="{l s='From'}" value="{if isset($smarty.post[$field_name][0]) && $smarty.post[$field_name][0]}{$smarty.post[$field_name][0]}{elseif isset($params.value.0)}{$params.value.0}{/if}">
|
||||
<input type="text" class="filter form-control" name="{$field_name}[1]" placeholder="{l s='To'}" value="{if isset($smarty.post[$field_name][1]) && $smarty.post[$field_name][1]}{$smarty.post[$field_name][1]}{elseif isset($params.value.1)}{$params.value.1}{/if}">
|
||||
</div>
|
||||
{elseif $params.type == 'bool'}
|
||||
{$field_name="`$list_id`Filter_{if isset($params.filter_key)}`$params.filter_key`{else}`$key`{/if}"}
|
||||
<select id="filter_input_{$key}" class="filter center" name="{$field_name}">
|
||||
<option value="">-</option>
|
||||
<option value="1" {if isset($smarty.post.$field_name) && $smarty.post.$field_name == 1} selected="selected"{elseif $params.value == 1} selected="selected" {/if}>{l s='Yes'}</option>
|
||||
<option value="0" {if isset($smarty.post.$field_name) && $smarty.post.$field_name != '' && $smarty.post.$field_name == 0} selected="selected"{elseif $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($smarty.post[$params.name_date][0]) && $smarty.post[$params.name_date][0]}{$smarty.post[$params.name_date][0]}{elseif isset($params.value.0)}{$params.value.0}{/if}">
|
||||
<span class="input-group-addon">
|
||||
<i class="icon-calendar"></i>
|
||||
</span>
|
||||
{/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'}
|
||||
{$field_name="`$list_id`Filter_{if isset($params.filter_key)}`$params.filter_key`{else}`$key`{/if}"}
|
||||
<div class="input_range">
|
||||
<input type="text" class="filter form-control" name="{$field_name}[0]" placeholder="{l s='From'}" value="{if isset($smarty.post[$field_name][0]) && $smarty.post[$field_name][0]}{$smarty.post[$field_name][0]}{elseif isset($params.value.0)}{$params.value.0}{/if}">
|
||||
<input type="text" class="filter form-control" name="{$field_name}[1]" placeholder="{l s='To'}" value="{if isset($smarty.post[$field_name][1]) && $smarty.post[$field_name][1]}{$smarty.post[$field_name][1]}{elseif isset($params.value.1)}{$params.value.1}{/if}">
|
||||
</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($smarty.post[$params.name_date][1]) && $smarty.post[$params.name_date][1]}{$smarty.post[$params.name_date][1]}{elseif 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',
|
||||
onClose: function() {
|
||||
let dateFrom = $('#local_{$params.id_date}_0').val().trim();
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
|
||||
if ((dateFrom && dateTo) && (dateFrom >= dateTo)) {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate());
|
||||
|
||||
$('#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());
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
{elseif $params.type == 'select'}
|
||||
{$field_name="`$list_id`Filter_`$params.filter_key`"}
|
||||
{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" multiple name="{$field_name}[]" {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($smarty.post.$field_name) && $smarty.post.$field_name && in_array($option_value, $smarty.post.$field_name)} selected="selected"{elseif isset($params.value) && $params.value}{if in_array($option_value, $params.value)} selected="selected"{/if}{/if}>{$option_display}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
{elseif $params.type == 'bool'}
|
||||
{$field_name="`$list_id`Filter_{if isset($params.filter_key)}`$params.filter_key`{else}`$key`{/if}"}
|
||||
<select id="filter_input_{$key}" class="filter center" name="{$field_name}">
|
||||
<option value="">-</option>
|
||||
<option value="1" {if isset($smarty.post.$field_name) && $smarty.post.$field_name == 1} selected="selected"{elseif $params.value == 1} selected="selected" {/if}>{l s='Yes'}</option>
|
||||
<option value="0" {if isset($smarty.post.$field_name) && $smarty.post.$field_name != '' && $smarty.post.$field_name == 0} selected="selected"{elseif $params.value == 0 && $params.value != ''} selected="selected" {/if}>{l s='No'}</option>
|
||||
</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}" name="{$field_name}" {if isset($params.width)} style="width:{$params.width}px"{/if}>
|
||||
<option value="" {if $params.value == ''} selected="selected" {/if}>-</option>
|
||||
{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($smarty.post[$params.name_date][0]) && $smarty.post[$params.name_date][0]}{$smarty.post[$params.name_date][0]}{elseif 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($smarty.post[$params.name_date][1]) && $smarty.post[$params.name_date][1]}{$smarty.post[$params.name_date][1]}{elseif 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',
|
||||
onClose: function() {
|
||||
let dateFrom = $('#local_{$params.id_date}_0').val().trim();
|
||||
let dateTo = $('#local_{$params.id_date}_1').val().trim();
|
||||
|
||||
if ((dateFrom && dateTo) && (dateFrom >= dateTo)) {
|
||||
let objDateToMin = $.datepicker.parseDate('yy-mm-dd', dateFrom);
|
||||
objDateToMin.setDate(objDateToMin.getDate());
|
||||
|
||||
$('#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());
|
||||
|
||||
$('#local_{$params.id_date}_1').datepicker('option', 'minDate', objDateToMin);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
{elseif $params.type == 'select'}
|
||||
{$field_name="`$list_id`Filter_`$params.filter_key`"}
|
||||
{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" multiple name="{$field_name}[]" {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($smarty.post.$field_name) && $smarty.post.$field_name != '' && $smarty.post.$field_name == $option_value} selected="selected"{elseif (string)$option_display === (string)$params.value || (string)$option_value === (string)$params.value} selected="selected"{/if}>{$option_display}</option>
|
||||
<option value="{$option_value}" {if isset($smarty.post.$field_name) && $smarty.post.$field_name && in_array($option_value, $smarty.post.$field_name)} selected="selected"{elseif 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}" name="{$field_name}" {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 isset($smarty.post.$field_name) && $smarty.post.$field_name != '' && $smarty.post.$field_name == $option_value} selected="selected"{elseif (string)$option_display === (string)$params.value || (string)$option_value === (string)$params.value} selected="selected"{/if}>{$option_display}</option>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</select>
|
||||
{/if}
|
||||
{/if}
|
||||
{else}
|
||||
{$field_name="`$list_id`Filter_{if isset($params.filter_key)}`$params.filter_key`{else}`$key`{/if}"}
|
||||
<input type="text" id="filter_input_{$key}" class="filter" name="{$field_name}" value="{if isset($smarty.post.$field_name) && $smarty.post.$field_name}{$smarty.post.$field_name}{else}{$params.value|escape:'html':'UTF-8'}{/if}" {if isset($params.width) && $params.width != 'auto'} style="width:{$params.width}px"{/if} />
|
||||
{/if}
|
||||
{else}
|
||||
{$field_name="`$list_id`Filter_{if isset($params.filter_key)}`$params.filter_key`{else}`$key`{/if}"}
|
||||
<input type="text" id="filter_input_{$key}" class="filter" name="{$field_name}" value="{if isset($smarty.post.$field_name) && $smarty.post.$field_name}{$smarty.post.$field_name}{else}{$params.value|escape:'html':'UTF-8'}{/if}" {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}
|
||||
{/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>
|
||||
</div>
|
||||
{/block}
|
||||
{/if}
|
||||
{/block}
|
||||
<div class="panel col-lg-12">
|
||||
|
||||
@@ -32,6 +32,7 @@ class CustomerMessageCore extends ObjectModel
|
||||
public $message;
|
||||
public $file_name;
|
||||
public $ip_address;
|
||||
public $id_product;
|
||||
public $user_agent;
|
||||
public $private;
|
||||
public $date_add;
|
||||
@@ -51,6 +52,7 @@ class CustomerMessageCore extends ObjectModel
|
||||
'id_employee' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'id_customer_thread' => array('type' => self::TYPE_INT),
|
||||
'ip_address' => array('type' => self::TYPE_STRING, 'validate' => 'isIp2Long', 'size' => 15),
|
||||
'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'message' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'required' => true, 'size' => 16777216),
|
||||
'file_name' => array('type' => self::TYPE_STRING),
|
||||
'user_agent' => array('type' => self::TYPE_STRING),
|
||||
@@ -72,7 +74,7 @@ class CustomerMessageCore extends ObjectModel
|
||||
),
|
||||
);
|
||||
|
||||
public static function getMessagesByOrderId($id_order, $private = true)
|
||||
public static function getMessagesByOrderId($id_order, $private = null, $limit = false)
|
||||
{
|
||||
return Db::getInstance()->executeS('
|
||||
SELECT cm.*,
|
||||
@@ -89,29 +91,33 @@ class CustomerMessageCore extends ObjectModel
|
||||
LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e
|
||||
ON e.`id_employee` = cm.`id_employee`
|
||||
WHERE ct.id_order = '.(int)$id_order.'
|
||||
'.(!$private ? 'AND cm.`private` = 0' : '').'
|
||||
'.(!is_null($private) ? 'AND cm.`private` = '.(int) $private : '').'
|
||||
GROUP BY cm.id_customer_message
|
||||
ORDER BY cm.date_add DESC
|
||||
');
|
||||
ORDER BY cm.date_add DESC'.
|
||||
(($limit) ? ' LIMIT '.(int) $limit: ' ')
|
||||
);
|
||||
}
|
||||
|
||||
public static function getTotalCustomerMessages($where = null)
|
||||
{
|
||||
$sql = 'SELECT COUNT(*)
|
||||
FROM '._DB_PREFIX_.'customer_message cm
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer_thread` ct ON (cm.`id_customer_thread` = ct.`id_customer_thread`) ';
|
||||
if (is_null($where)) {
|
||||
return (int)Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM '._DB_PREFIX_.'customer_message
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer_thread` ct ON (cm.`id_customer_thread` = ct.`id_customer_thread`)
|
||||
WHERE 1'.Shop::addSqlRestriction()
|
||||
);
|
||||
} else {
|
||||
return (int)Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM '._DB_PREFIX_.'customer_message cm
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer_thread` ct ON (cm.`id_customer_thread` = ct.`id_customer_thread`)
|
||||
WHERE '.$where.Shop::addSqlRestriction()
|
||||
$where = ' 1 ';
|
||||
}
|
||||
|
||||
$employee = Context::getContext()->employee;
|
||||
if (!$employee->isSuperAdmin()) {
|
||||
$where .= (($acsHtls = HotelBranchInformation::getProfileAccessedHotels($employee->id_profile, 1, 1)) ?
|
||||
' AND ct.`id_order` IN (SELECT `id_order` FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE `id_hotel` IN ('.implode(',', $acsHtls).')) ' :
|
||||
' AND ct.`id_order` = 0 '
|
||||
);
|
||||
}
|
||||
|
||||
return (int)Db::getInstance()->getValue(
|
||||
$sql.' WHERE '.$where.Shop::addSqlRestriction()
|
||||
);
|
||||
}
|
||||
|
||||
public function delete()
|
||||
|
||||
@@ -30,15 +30,23 @@ class CustomerThreadCore extends ObjectModel
|
||||
public $id_shop;
|
||||
public $id_lang;
|
||||
public $id_contact;
|
||||
public $id_employee;
|
||||
public $id_customer;
|
||||
public $id_order;
|
||||
public $id_product;
|
||||
public $user_name;
|
||||
public $phone;
|
||||
public $subject;
|
||||
public $status;
|
||||
public $email;
|
||||
public $token;
|
||||
public $date_add;
|
||||
public $date_upd;
|
||||
|
||||
const QLO_CUSTOMER_THREAD_STATUS_OPEN = 1;
|
||||
const QLO_CUSTOMER_THREAD_STATUS_PENDING1 = 2;
|
||||
const QLO_CUSTOMER_THREAD_STATUS_PENDING2 = 3;
|
||||
const QLO_CUSTOMER_THREAD_STATUS_CLOSED = 4;
|
||||
|
||||
/**
|
||||
* @see ObjectModel::$definition
|
||||
*/
|
||||
@@ -48,10 +56,13 @@ class CustomerThreadCore extends ObjectModel
|
||||
'fields' => array(
|
||||
'id_lang' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
|
||||
'id_contact' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
|
||||
'user_name' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'),
|
||||
'phone' => array('type' => self::TYPE_STRING, 'validate' => 'isPhoneNumber', 'size' => 32),
|
||||
'subject' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml'),
|
||||
'id_shop' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'id_customer' =>array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'id_employee' =>array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'id_order' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'email' => array('type' => self::TYPE_STRING, 'validate' => 'isEmail', 'size' => 254),
|
||||
'token' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true),
|
||||
'status' => array('type' => self::TYPE_STRING),
|
||||
@@ -158,15 +169,38 @@ class CustomerThreadCore extends ObjectModel
|
||||
return Db::getInstance()->executeS($sql);
|
||||
}
|
||||
|
||||
public static function getIdCustomerThreadByEmailAndIdOrder($email, $id_order, $id_contact = false)
|
||||
public static function getIdCustomerThreadByEmailAndIdOrder($email, $id_order, $id_contact = false, $query = false)
|
||||
{
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT a.`id_customer_thread`
|
||||
FROM `'._DB_PREFIX_.'customer_thread` a
|
||||
WHERE a.`email` = \''.pSQL($email).'\'
|
||||
AND a.`id_shop` = '.(int)Context::getContext()->shop->id.'
|
||||
AND a.`id_order` = '.(int)$id_order.' '.
|
||||
(($id_contact) ? ' AND a.`id_contact`='.(int) $id_contact : ' ').
|
||||
(($query) ? $query : ' ')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static function getIdCustomerThreadByIdOrder($idOrder)
|
||||
{
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT cm.id_customer_thread
|
||||
FROM '._DB_PREFIX_.'customer_thread cm
|
||||
WHERE cm.email = \''.pSQL($email).'\'
|
||||
AND cm.id_shop = '.(int)Context::getContext()->shop->id.'
|
||||
AND cm.id_order = '.(int)$id_order.' '.
|
||||
(($id_contact) ? ' AND cm.id_contact='.(int) $id_contact : ' ')
|
||||
WHERE cm.id_shop = '.(int)Context::getContext()->shop->id.'
|
||||
AND cm.id_order = '.(int)$idOrder
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static function getIdCustomerThreadByToken($token)
|
||||
{
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT cm.id_customer_thread
|
||||
FROM '._DB_PREFIX_.'customer_thread cm
|
||||
WHERE cm.id_shop = '.(int)Context::getContext()->shop->id.'
|
||||
AND token = \''.pSQL($token).'\''
|
||||
);
|
||||
}
|
||||
|
||||
@@ -176,7 +210,8 @@ class CustomerThreadCore extends ObjectModel
|
||||
SELECT cl.*, COUNT(*) as total, (
|
||||
SELECT id_customer_thread
|
||||
FROM '._DB_PREFIX_.'customer_thread ct2
|
||||
WHERE status = "open" AND ct.id_contact = ct2.id_contact
|
||||
WHERE status = '.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN.'
|
||||
AND ct.id_contact = ct2.id_contact
|
||||
'.Shop::addSqlRestriction().'
|
||||
ORDER BY date_upd ASC
|
||||
LIMIT 1
|
||||
@@ -184,7 +219,7 @@ class CustomerThreadCore extends ObjectModel
|
||||
FROM '._DB_PREFIX_.'customer_thread ct
|
||||
LEFT JOIN '._DB_PREFIX_.'contact_lang cl
|
||||
ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)Context::getContext()->language->id.')
|
||||
WHERE ct.status = "open"
|
||||
WHERE ct.status = '.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN.'
|
||||
AND ct.id_contact IS NOT NULL
|
||||
AND cl.id_contact IS NOT NULL
|
||||
'.Shop::addSqlRestriction().'
|
||||
@@ -194,19 +229,19 @@ class CustomerThreadCore extends ObjectModel
|
||||
|
||||
public static function getTotalCustomerThreads($where = null)
|
||||
{
|
||||
$sql = 'SELECT COUNT(*) FROM '._DB_PREFIX_.'customer_thread ';
|
||||
if (is_null($where)) {
|
||||
return (int)Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM '._DB_PREFIX_.'customer_thread
|
||||
WHERE 1 '.Shop::addSqlRestriction()
|
||||
);
|
||||
} else {
|
||||
return (int)Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM '._DB_PREFIX_.'customer_thread
|
||||
WHERE '.$where.Shop::addSqlRestriction()
|
||||
$where = ' 1 ';
|
||||
}
|
||||
|
||||
$employee = Context::getContext()->employee;
|
||||
if (!$employee->isSuperAdmin()) {
|
||||
$where .= (($acsHtls = HotelBranchInformation::getProfileAccessedHotels($employee->id_profile, 1, 1)) ?
|
||||
' AND `id_order` IN (SELECT `id_order` FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE `id_hotel` IN ('.implode(',', $acsHtls).')) ' :
|
||||
' AND `id_order` = 0 '
|
||||
);
|
||||
}
|
||||
return (int)Db::getInstance()->getValue($sql.' WHERE '.$where.Shop::addSqlRestriction());
|
||||
}
|
||||
|
||||
public static function getMessageCustomerThreads($id_customer_thread)
|
||||
@@ -234,7 +269,7 @@ class CustomerThreadCore extends ObjectModel
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT id_customer_thread
|
||||
FROM '._DB_PREFIX_.'customer_thread ct
|
||||
WHERE ct.status = "open"
|
||||
WHERE ct.status = '.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN.'
|
||||
AND ct.date_upd = (
|
||||
SELECT date_add FROM '._DB_PREFIX_.'customer_message
|
||||
WHERE (id_employee IS NULL OR id_employee = 0)
|
||||
|
||||
@@ -88,7 +88,7 @@ class MessageCore extends ObjectModel
|
||||
* @param bool $private return WITH private messages
|
||||
* @return array Messages
|
||||
*/
|
||||
public static function getMessagesByOrderId($id_order, $private = false, Context $context = null)
|
||||
public static function getMessagesByOrderId($id_order, $private = null, Context $context = null)
|
||||
{
|
||||
if (!Validate::isBool($private)) {
|
||||
die(Tools::displayError());
|
||||
@@ -108,7 +108,7 @@ class MessageCore extends ObjectModel
|
||||
AND mr.`id_employee` = '.(isset($context->employee) ? (int)$context->employee->id : '\'\'').'
|
||||
LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e ON e.`id_employee` = m.`id_employee`
|
||||
WHERE id_order = '.(int)$id_order.'
|
||||
'.(!$private ? ' AND m.`private` = 0' : '').'
|
||||
'.(!is_null($private) ? ' AND m.`private` = '.(int) $private : '').'
|
||||
GROUP BY m.id_message
|
||||
ORDER BY m.date_add DESC
|
||||
');
|
||||
|
||||
@@ -716,7 +716,7 @@ abstract class PaymentModuleCore extends Module
|
||||
$customer_thread->id_order = (int)$order->id;
|
||||
$customer_thread->id_lang = (int)$this->context->language->id;
|
||||
$customer_thread->email = $this->context->customer->email;
|
||||
$customer_thread->status = 'open';
|
||||
$customer_thread->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$customer_thread->token = Tools::passwdGen(12);
|
||||
$customer_thread->add();
|
||||
|
||||
@@ -724,7 +724,7 @@ abstract class PaymentModuleCore extends Module
|
||||
$customer_message->id_customer_thread = $customer_thread->id;
|
||||
$customer_message->id_employee = 0;
|
||||
$customer_message->message = $update_message->message;
|
||||
$customer_message->private = 0;
|
||||
$customer_message->private = !Tools::getValue('visibility');
|
||||
|
||||
if (!$customer_message->add()) {
|
||||
$this->errors[] = Tools::displayError('An error occurred while saving message');
|
||||
|
||||
@@ -1063,11 +1063,12 @@ class ProductCore extends ObjectModel
|
||||
}
|
||||
|
||||
if (!$this->booking_product) {
|
||||
$objHotelRoomTypeBedType = new HotelRoomTypeBedType();
|
||||
$objHotelRoomTypeBedType->deleteRoomTypeBedTypes(false, $this->id);
|
||||
if (!$this->deleteServiceInfo()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$objHotelRoomTypeBedType = new HotelRoomTypeBedType();
|
||||
$objHotelRoomTypeBedType->deleteRoomTypeBedTypes(false, $this->id);
|
||||
}
|
||||
|
||||
Hook::exec('actionProductDelete', array('id_product' => (int)$this->id, 'product' => $this));
|
||||
|
||||
@@ -2679,7 +2679,7 @@ class WebserviceSpecificManagementBookingsCore Extends ObjectModel implements We
|
||||
$message = strip_tags($remark, '<br>');
|
||||
$saveMessage = true;
|
||||
$idCart = Cart::getCartIdByOrderId($objOrder->id);
|
||||
if ($customerMessages = Message::getMessagesByOrderId($objOrder->id, true)) {
|
||||
if ($customerMessages = Message::getMessagesByOrderId($objOrder->id, false)) {
|
||||
foreach ($customerMessages as $customerMessage) {
|
||||
if ($customerMessage['message'] == $message) {
|
||||
$saveMessage = false;
|
||||
@@ -3499,7 +3499,7 @@ class WebserviceSpecificManagementBookingsCore Extends ObjectModel implements We
|
||||
}
|
||||
|
||||
$params['associations']['remarks'] = array();
|
||||
if ($customerMessages = Message::getMessagesByOrderId($objOrder->id, true)) {
|
||||
if ($customerMessages = Message::getMessagesByOrderId($objOrder->id)) {
|
||||
foreach ($customerMessages as $customerMessage) {
|
||||
$message = $customerMessage['message'];
|
||||
$params['associations']['remarks'][] = $message;
|
||||
|
||||
@@ -51,10 +51,22 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
}
|
||||
|
||||
$icon_array = array(
|
||||
'open' => array('class' => 'icon-circle text-success', 'alt' => $this->l('Open')),
|
||||
'closed' => array('class' => 'icon-circle text-danger', 'alt' => $this->l('Closed')),
|
||||
'pending1' => array('class' => 'icon-circle text-warning', 'alt' => $this->l('Pending 1')),
|
||||
'pending2' => array('class' => 'icon-circle text-warning', 'alt' => $this->l('Pending 2')),
|
||||
CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN => array(
|
||||
'class' => 'icon-circle text-success',
|
||||
'alt' => $this->l('Open')
|
||||
),
|
||||
CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED => array(
|
||||
'class' => 'icon-circle text-danger',
|
||||
'alt' => $this->l('Closed')
|
||||
),
|
||||
CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1 => array(
|
||||
'class' => 'icon-circle text-warning',
|
||||
'alt' => $this->l('Pending 1')
|
||||
),
|
||||
CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2 => array(
|
||||
'class' => 'icon-circle text-warning',
|
||||
'alt' => $this->l('Pending 2')
|
||||
),
|
||||
);
|
||||
|
||||
$status_array = array();
|
||||
@@ -67,7 +79,9 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$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)';
|
||||
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->access_where = ' WHERE IF(a.`id_order`, hbd.`id_hotel` IN ('.implode(',', $acsHtls).'), 1)';
|
||||
} else {
|
||||
$this->access_where = ' WHERE a.`id_order` = 0';
|
||||
}
|
||||
|
||||
$this->fields_list = array(
|
||||
@@ -79,25 +93,41 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'customer' => array(
|
||||
'title' => $this->l('Customer'),
|
||||
'filter_key' => 'customer',
|
||||
'callback' => 'getCustomerLink',
|
||||
'tmpTableFilter' => true,
|
||||
),
|
||||
'email' => array(
|
||||
'title' => $this->l('Email'),
|
||||
'filter_key' => 'a!email',
|
||||
),
|
||||
'phone' => array(
|
||||
'title' => $this->l('Phone'),
|
||||
'filter_key' => 'a!phone',
|
||||
'optional' => true,
|
||||
'visible_default' => true,
|
||||
),
|
||||
'contact' => array(
|
||||
'title' => $this->l('Type'),
|
||||
'title' => $this->l('Contact'),
|
||||
'type' => 'select',
|
||||
'list' => $contact_array,
|
||||
'filter_key' => 'cl!id_contact',
|
||||
'filter_type' => 'int',
|
||||
),
|
||||
'subject' => array(
|
||||
'title' => $this->l('Title'),
|
||||
'filter_key' => 'a!subject',
|
||||
'tmpTableFilter' => true,
|
||||
'maxlength' => 30,
|
||||
'optional' => true,
|
||||
'visible_default' => true,
|
||||
),
|
||||
'language' => array(
|
||||
'title' => $this->l('Language'),
|
||||
'type' => 'select',
|
||||
'list' => $language_array,
|
||||
'filter_key' => 'l!id_lang',
|
||||
'filter_type' => 'int',
|
||||
'optional' => true,
|
||||
),
|
||||
'status' => array(
|
||||
'title' => $this->l('Status'),
|
||||
@@ -112,29 +142,42 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'title' => $this->l('Employee'),
|
||||
'filter_key' => 'employee',
|
||||
'tmpTableFilter' => true,
|
||||
'optional' => true,
|
||||
'hint' => $this->l('The first employee to reply becomes responsible. They can then forward the message to another employee if needed.')
|
||||
),
|
||||
'last_employee' => array(
|
||||
'title' => $this->l('Last Reply by'),
|
||||
'filter_key' => 'employee',
|
||||
'tmpTableFilter' => true,
|
||||
'optional' => true,
|
||||
),
|
||||
'messages' => array(
|
||||
'title' => $this->l('Messages'),
|
||||
'filter_key' => 'messages',
|
||||
'tmpTableFilter' => true,
|
||||
'maxlength' => 40,
|
||||
'maxlength' => 30,
|
||||
'optional' => true,
|
||||
),
|
||||
'private' => array(
|
||||
'title' => $this->l('Private'),
|
||||
'type' => 'select',
|
||||
'filter_key' => 'private',
|
||||
'has_private' => array(
|
||||
'title' => $this->l('Has Private'),
|
||||
'type' => 'bool',
|
||||
'havingFilter' => true,
|
||||
'filter_key' => 'has_private',
|
||||
'align' => 'center',
|
||||
'cast' => 'intval',
|
||||
'callback' => 'printOptinIcon',
|
||||
'list' => array(
|
||||
'0' => $this->l('No'),
|
||||
'1' => $this->l('Yes')
|
||||
)
|
||||
),
|
||||
'date_upd' => array(
|
||||
'title' => $this->l('Last message'),
|
||||
'havingFilter' => true,
|
||||
'type' => 'datetime',
|
||||
'optional' => true,
|
||||
),
|
||||
'id_order' => array(
|
||||
'title' => $this->l('ID Order'),
|
||||
'filter_key' => 'a!id_order',
|
||||
'optional' => true,
|
||||
'visible_default' => false,
|
||||
'displayed' => false,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -147,22 +190,71 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
);
|
||||
|
||||
$this->shopLinkType = 'shop';
|
||||
$arr = array();
|
||||
if ($contacts = Contact::getContacts($this->context->language->id)) {
|
||||
foreach ($contacts as $contact) {
|
||||
$arr[] = array('email_message' => $contact['id_contact'], 'name' => $contact['name']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->fields_options = array(
|
||||
'contact' => array(
|
||||
'title' => $this->l('Contact options'),
|
||||
'fields' => array(
|
||||
'PS_CUSTOMER_SERVICE_FILE_UPLOAD' => array(
|
||||
'title' => $this->l('Allow file uploading'),
|
||||
'hint' => $this->l('Allow customers to upload files using the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
'title' => $this->l('Contact options'),
|
||||
'fields' => array(
|
||||
'PS_CUSTOMER_SERVICE_SIGNATURE' => array(
|
||||
'title' => $this->l('Default message'),
|
||||
'hint' => $this->l('Please fill out the message fields that appear by default when you answer a thread on the customer service page.'),
|
||||
'type' => 'textareaLang',
|
||||
'lang' => true
|
||||
)
|
||||
'title' => $this->l('Default message'),
|
||||
'hint' => $this->l('Please fill out the message fields that appear by default when you answer a thread on the customer service page.'),
|
||||
'type' => 'textareaLang',
|
||||
'lang' => true
|
||||
),
|
||||
'PS_MAIL_EMAIL_MESSAGE' => array(
|
||||
'title' => $this->l('Send messages from order page to'),
|
||||
'desc' => $this->l('Where customers send messages from the order page.'),
|
||||
'validation' => 'isUnsignedId',
|
||||
'type' => 'select',
|
||||
'cast' => 'intval',
|
||||
'identifier' => 'email_message',
|
||||
'list' => $arr
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_DISPLAY_CONTACT' => array(
|
||||
'title' => $this->l('Select contact on contact page'),
|
||||
'hint' => $this->l('Allow guest to select the contact while sending message from the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_CONTACT' => array(
|
||||
'title' => $this->l('Send messages from contact page to'),
|
||||
'desc' => $this->l('Where customers send messages from the Contact page.'),
|
||||
'validation' => 'isUnsignedId',
|
||||
'type' => 'select',
|
||||
'cast' => 'intval',
|
||||
'identifier' => 'email_message',
|
||||
'list' => $arr
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_DISPLAY_NAME' => array(
|
||||
'title' => $this->l('Display name on contact page'),
|
||||
'hint' => $this->l('Display name field on contact page.'),
|
||||
'type' => 'bool',
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_REQUIRED_NAME' => array(
|
||||
'title' => $this->l('Set name as required'),
|
||||
'hint' => $this->l('Set name as required while submitting message from the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_DISPLAY_PHONE' => array(
|
||||
'title' => $this->l('Display phone on contact page'),
|
||||
'hint' => $this->l('Display phone field on contact page.'),
|
||||
'type' => 'bool',
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_REQUIRED_PHONE' => array(
|
||||
'title' => $this->l('Set phone as required'),
|
||||
'hint' => $this->l('Set phone as required while submitting message from the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_FILE_UPLOAD' => array(
|
||||
'title' => $this->l('Allow file uploading'),
|
||||
'hint' => $this->l('Allow customers to upload files using the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
@@ -242,6 +334,25 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
);
|
||||
|
||||
parent::__construct();
|
||||
$this->_new_list_header_design = true;
|
||||
$this->list_no_link = true;
|
||||
}
|
||||
|
||||
public function getCustomerLink($customer, $tr)
|
||||
{
|
||||
if ($tr['id_customer']) {
|
||||
return '<a href="'.$this->context->link->getAdminLink('AdminCustomers').'&viewcustomer&id_customer='.$tr['id_customer'].'">'.$customer.' (#'.$tr['id_customer'].')</a>';
|
||||
}
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
public function setMedia()
|
||||
{
|
||||
parent::setMedia();
|
||||
if (!$this->display || $this->display == 'list') {
|
||||
$this->addJS(_PS_JS_DIR_.'admin/customer_thread.js');
|
||||
}
|
||||
}
|
||||
|
||||
public function renderList()
|
||||
@@ -253,7 +364,8 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$this->addRowAction('delete');
|
||||
|
||||
$this->_select = '
|
||||
CONCAT(c.`firstname`," ",c.`lastname`) as customer, cl.`name` as contact, l.`name` as language, group_concat(message) as messages, cm.private,
|
||||
IF(a.`user_name`="", CONCAT(c.`firstname`," ",c.`lastname`), a.`user_name`) AS customer, cl.`name` as contact, l.`name` as language, group_concat(message) as messages,
|
||||
cm.private, IF(COUNT(CASE WHEN cm.`private` = 1 THEN 1 END), 1, 0) AS `has_private`,
|
||||
(
|
||||
SELECT IFNULL(CONCAT(LEFT(e.`firstname`, 1),". ",e.`lastname`), "--")
|
||||
FROM `'._DB_PREFIX_.'customer_message` cm2
|
||||
@@ -262,9 +374,12 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
WHERE cm2.id_employee > 0
|
||||
AND cm2.`id_customer_thread` = a.`id_customer_thread`
|
||||
ORDER BY cm2.`date_add` DESC LIMIT 1
|
||||
) as employee';
|
||||
) AS last_employee,
|
||||
IFNULL(CONCAT(LEFT(emp.`firstname`, 1),". ",emp.`lastname`), "--") AS employee';
|
||||
|
||||
$this->_join = '
|
||||
LEFT JOIN `'._DB_PREFIX_.'employee` emp
|
||||
ON emp.`id_employee` = a.`id_employee`
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer` c
|
||||
ON c.`id_customer` = a.`id_customer`
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer_message` cm
|
||||
@@ -274,33 +389,10 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
LEFT JOIN `'._DB_PREFIX_.'contact_lang` cl
|
||||
ON (cl.`id_contact` = a.`id_contact` AND cl.`id_lang` = '.(int)$this->context->language->id.')';
|
||||
|
||||
if ($id_order = Tools::getValue('id_order')) {
|
||||
$this->_where .= ' AND id_order = '.(int)$id_order;
|
||||
}
|
||||
|
||||
$this->_group = 'GROUP BY cm.id_customer_thread';
|
||||
$this->_orderBy = 'id_customer_thread';
|
||||
$this->_orderWay = 'DESC';
|
||||
|
||||
$contacts = CustomerThread::getContacts();
|
||||
|
||||
$categories = Contact::getCategoriesContacts();
|
||||
|
||||
$params = array(
|
||||
$this->l('Total threads') => $all = CustomerThread::getTotalCustomerThreads(),
|
||||
$this->l('Threads pending') => $pending = CustomerThread::getTotalCustomerThreads('status LIKE "%pending%"'),
|
||||
$this->l('Total number of customer messages') => CustomerMessage::getTotalCustomerMessages('id_employee = 0'),
|
||||
$this->l('Total number of employee messages') => CustomerMessage::getTotalCustomerMessages('id_employee != 0'),
|
||||
$this->l('Unread threads') => $unread = CustomerThread::getTotalCustomerThreads('status = "open"'),
|
||||
$this->l('Closed threads') => $all - ($unread + $pending)
|
||||
);
|
||||
|
||||
$this->tpl_list_vars = array(
|
||||
'contacts' => $contacts,
|
||||
'categories' => $categories,
|
||||
'params' => $params
|
||||
);
|
||||
|
||||
return parent::renderList();
|
||||
}
|
||||
|
||||
@@ -323,6 +415,13 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
if (Tools::isSubmit('submitOptionsCustomerService')) {
|
||||
unset($this->fields_options['general']);
|
||||
$this->processUpdateOptions();
|
||||
if (!Tools::getValue('PS_CUSTOMER_SERVICE_DISPLAY_NAME')) {
|
||||
Configuration::updateValue('PS_CUSTOMER_SERVICE_REQUIRED_NAME', 0);
|
||||
}
|
||||
|
||||
if (!Tools::getValue('PS_CUSTOMER_SERVICE_DISPLAY_PHONE')) {
|
||||
Configuration::updateValue('PS_CUSTOMER_SERVICE_REQUIRED_PHONE', 0);
|
||||
}
|
||||
} else if (Tools::isSubmit('submitOptionsIMAPConfig')) {
|
||||
unset($this->fields_options['contact']);
|
||||
$this->processUpdateOptions();
|
||||
@@ -334,6 +433,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
}
|
||||
|
||||
if ($id_customer_thread = (int)Tools::getValue('id_customer_thread')) {
|
||||
$ct = new CustomerThread($id_customer_thread);
|
||||
if (($id_contact = (int)Tools::getValue('id_contact'))) {
|
||||
Db::getInstance()->execute('
|
||||
UPDATE '._DB_PREFIX_.'customer_thread
|
||||
@@ -342,14 +442,13 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
);
|
||||
}
|
||||
if ($id_status = (int)Tools::getValue('setstatus')) {
|
||||
$status_array = array(1 => 'open', 2 => 'closed', 3 => 'pending1', 4 => 'pending2');
|
||||
Db::getInstance()->execute('
|
||||
UPDATE '._DB_PREFIX_.'customer_thread
|
||||
SET status = "'.$status_array[$id_status].'"
|
||||
SET status = "'.(int) $id_status.'"
|
||||
WHERE id_customer_thread = '.(int)$id_customer_thread.' LIMIT 1
|
||||
');
|
||||
}
|
||||
if (isset($_POST['id_employee_forward'])) {
|
||||
if ($id_employee = (int) Tools::getValue('id_employee_forward')) {
|
||||
$messages = Db::getInstance()->getRow('
|
||||
SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name,
|
||||
CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname
|
||||
@@ -363,7 +462,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
LEFT OUTER JOIN '._DB_PREFIX_.'customer c
|
||||
ON (c.email = ct.email)
|
||||
WHERE ct.id_customer_thread = '.(int)Tools::getValue('id_customer_thread').'
|
||||
ORDER BY cm.date_add DESC
|
||||
ORDER BY cm.id_employee, cm.private, cm.date_add DESC
|
||||
');
|
||||
$output = $this->displayMessage($messages, true, (int)Tools::getValue('id_employee_forward'));
|
||||
$cm = new CustomerMessage();
|
||||
@@ -395,7 +494,10 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$employee->firstname.' '.$employee->lastname,
|
||||
$current_employee->email,
|
||||
$current_employee->firstname.' '.$current_employee->lastname,
|
||||
null, null, _PS_MAIL_DIR_, true)) {
|
||||
null, null, _PS_MAIL_DIR_, true)
|
||||
) {
|
||||
$ct->id_employee = $employee->id;
|
||||
$ct->save();
|
||||
$cm->id_employee = (int)$employee->id;
|
||||
$cm->private = 1;
|
||||
$cm->message = $this->l('Message forwarded to').' '.$employee->firstname.' '.$employee->lastname."\n".$this->l('Comment:').' '.$message;
|
||||
@@ -424,13 +526,14 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$this->errors[] = '<div class="alert error">'.Tools::displayError('The email address is invalid.').'</div>';
|
||||
}
|
||||
}
|
||||
if (Tools::isSubmit('submitReply')) {
|
||||
$ct = new CustomerThread($id_customer_thread);
|
||||
|
||||
if (Tools::isSubmit('submitReply') || Tools::isSubmit('submitReplyAndClose')) {
|
||||
ShopUrl::cacheMainDomainForShop((int)$ct->id_shop);
|
||||
|
||||
$cm = new CustomerMessage();
|
||||
$cm->id_employee = (int)$this->context->employee->id;
|
||||
if (!$ct->id_employee) {
|
||||
$ct->id_employee = $this->context->employee->id;
|
||||
}
|
||||
$cm->id_customer_thread = $ct->id;
|
||||
$cm->ip_address = (int)ip2long(Tools::getRemoteAddr());
|
||||
$cm->message = Tools::getValue('reply_message');
|
||||
@@ -446,15 +549,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$file_attachment['mime'] = $_FILES['joinFile']['type'];
|
||||
}
|
||||
$customer = new Customer($ct->id_customer);
|
||||
$params = array(
|
||||
'{reply}' => Tools::nl2br(Tools::getValue('reply_message')),
|
||||
'{link}' => Tools::url(
|
||||
$this->context->link->getPageLink('contact', true, (int)$ct->id_lang, null, false, $ct->id_shop),
|
||||
'id_customer_thread='.(int)$ct->id.'&token='.$ct->token
|
||||
),
|
||||
'{firstname}' => $customer->firstname,
|
||||
'{lastname}' => $customer->lastname
|
||||
);
|
||||
|
||||
//#ct == id_customer_thread #tc == token of thread <== used in the synchronization imap
|
||||
$contact = new Contact((int)$ct->id_contact, (int)$ct->id_lang);
|
||||
|
||||
@@ -466,13 +561,80 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$from_email = null;
|
||||
}
|
||||
|
||||
if ($ct->id_order) {
|
||||
$link = Tools::url(
|
||||
$this->context->link->getPageLink('order-detail', true, (int)$ct->id_lang, null, false, $ct->id_shop),
|
||||
'id_order='.$ct->id_order
|
||||
);
|
||||
$objOrder = new Order($ct->id_order);
|
||||
$message = $cm->message;
|
||||
if (Configuration::get('PS_MAIL_TYPE', null, null, $objOrder->id_shop) != Mail::TYPE_TEXT) {
|
||||
$message = Tools::nl2br($cm->message);
|
||||
}
|
||||
|
||||
$objCustomer = new Customer($objOrder->id_customer);
|
||||
$idShop = $objOrder->id_shop;
|
||||
$params = array(
|
||||
'{lastname}' => $objCustomer->lastname,
|
||||
'{firstname}' => $objCustomer->firstname,
|
||||
'{id_order}' => $objOrder->id,
|
||||
'{order_name}' => $objOrder->getUniqReference(),
|
||||
'{message}' => $message
|
||||
);
|
||||
$toEmail = $objCustomer->email;
|
||||
$toName = $objCustomer->firstname.' '.$objCustomer->lastname;
|
||||
$title = Mail::l('New message regarding your booking', (int)$objOrder->id_lang);
|
||||
$template = 'order_merchant_comment';
|
||||
$idLang = $objOrder->id_lang;
|
||||
} else {
|
||||
$link = Tools::url(
|
||||
$this->context->link->getPageLink('contact', true, (int)$ct->id_lang, null, false, $ct->id_shop),
|
||||
'token='.$ct->token
|
||||
);
|
||||
$headingText = $this->l('Hi').' '.$ct->user_name.',';
|
||||
$idShop = $ct->id_shop;
|
||||
$params = array(
|
||||
'{reply}' => Tools::nl2br(Tools::getValue('reply_message')),
|
||||
'{link}' => $link,
|
||||
'{headingtext}' => $headingText,
|
||||
'{contact_name}' => $contact->name,
|
||||
);
|
||||
if (!empty(trim($ct->subject))) {
|
||||
$params['{subject}'] = $ct->subject;
|
||||
}
|
||||
|
||||
$idLang = $ct->id_lang;
|
||||
$toEmail = Tools::getValue('msg_email');
|
||||
$toName = null;
|
||||
$template = 'reply_msg';
|
||||
$title = Mail::l('An answer to your message is available', $ct->id_lang);
|
||||
if ($customer->id) {
|
||||
$headingText .= ' '.$customer->firstname.' '.$customer->lastname;
|
||||
}
|
||||
$headingText .= ',';
|
||||
}
|
||||
|
||||
if (Mail::Send(
|
||||
(int)$ct->id_lang,
|
||||
'reply_msg',
|
||||
sprintf(Mail::l('An answer to your message is available #ct%1$s #tc%2$s', $ct->id_lang), $ct->id, $ct->token),
|
||||
$params, Tools::getValue('msg_email'), null, $from_email, $from_name, $file_attachment, null,
|
||||
_PS_MAIL_DIR_, true, $ct->id_shop)) {
|
||||
$ct->status = 'closed';
|
||||
(int) $idLang,
|
||||
$template,
|
||||
$title,
|
||||
$params,
|
||||
$toEmail,
|
||||
$toName,
|
||||
$from_email,
|
||||
$from_name,
|
||||
$file_attachment,
|
||||
null,
|
||||
_PS_MAIL_DIR_,
|
||||
true,
|
||||
$idShop
|
||||
)) {
|
||||
if (Tools::isSubmit('submitReplyAndClose')) {
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED;
|
||||
} else {
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
}
|
||||
|
||||
$ct->update();
|
||||
}
|
||||
Tools::redirectAdmin(
|
||||
@@ -481,6 +643,24 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
} else {
|
||||
$this->errors[] = Tools::displayError('An error occurred. Your message was not sent. Please contact your system administrator.');
|
||||
}
|
||||
} else if (Tools::isSubmit('submitReplyAsPrivate')) {
|
||||
if (!$ct->id_employee) {
|
||||
$ct->id_employee = $this->context->employee->id;
|
||||
$ct->update();
|
||||
}
|
||||
ShopUrl::cacheMainDomainForShop((int)$ct->id_shop);
|
||||
$cm = new CustomerMessage();
|
||||
$cm->id_employee = (int)$this->context->employee->id;
|
||||
$cm->id_customer_thread = $ct->id;
|
||||
$cm->ip_address = (int)ip2long(Tools::getRemoteAddr());
|
||||
$cm->message = Tools::getValue('reply_message');
|
||||
$cm->private = 1;
|
||||
$cm->read = 1;
|
||||
if (($error = $cm->validateField('message', $cm->message, null, array(), true)) !== true) {
|
||||
$this->errors[] = $error;
|
||||
} elseif (!$cm->add()) {
|
||||
$this->errors[] = Tools::displayError('Some error occured while saving the message');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,19 +719,34 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$time = time();
|
||||
$kpis = array();
|
||||
|
||||
$all = CustomerThread::getTotalCustomerThreads();
|
||||
$pending = (int)AdminStatsController::getPendingMessages();
|
||||
$open = CustomerThread::getTotalCustomerThreads('status='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN);
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color1';
|
||||
$helper->title = $this->l('Total threads');
|
||||
$helper->tooltip = $this->l('Total number of threads.');
|
||||
$helper->value = $all;
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-pending-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color1';
|
||||
$helper->title = $this->l('Pending Discussion Threads', null, null, false);
|
||||
$helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=pending_messages';
|
||||
$helper->color = 'color2';
|
||||
$helper->title = $this->l('Threads pending', null, null, false);
|
||||
$helper->value = $pending + $open;
|
||||
$helper->tooltip = $this->l('Total number of threads having "open", "pending 1" and "pending 2" statuses.');
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-age';
|
||||
$helper->icon = 'icon-time';
|
||||
$helper->color = 'color2';
|
||||
$helper->color = 'color3';
|
||||
$helper->title = $this->l('Average Response Time', null, null, false);
|
||||
$helper->tooltip = $this->l('The average response time.');
|
||||
$helper->subtitle = $this->l('30 days', null, null, false);
|
||||
$helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=avg_msg_response_time';
|
||||
$this->kpis[] = $helper;
|
||||
@@ -559,12 +754,79 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-messages-per-thread';
|
||||
$helper->icon = 'icon-copy';
|
||||
$helper->color = 'color3';
|
||||
$helper->title = $this->l('Messages per Thread', null, null, false);
|
||||
$helper->color = 'color4';
|
||||
$helper->title = $this->l('Average Messages per Thread', null, null, false);
|
||||
$helper->subtitle = $this->l('30 day', null, null, false);
|
||||
$helper->tooltip = $this->l('The average number of messages in each thread.');
|
||||
$helper->source = $this->context->link->getAdminLink('AdminStats').'&ajax=1&action=getKpi&kpi=messages_per_thread';
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-pending-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color1';
|
||||
$helper->title = $this->l('Customer messages', null, null, false);
|
||||
$helper->tooltip = $this->l('Total number of messages sent by customers.');
|
||||
$helper->value = (int) CustomerMessage::getTotalCustomerMessages('cm.`id_employee` = 0');
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-pending-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color4';
|
||||
$helper->title = $this->l('Employee messages', null, null, false);
|
||||
$helper->tooltip = $this->l('Total number of messages sent by employees.');
|
||||
$helper->value = (int) CustomerMessage::getTotalCustomerMessages('cm.`id_employee` != 0');
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-pending-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color2';
|
||||
$helper->title = $this->l('Unread threads', null, null, false);
|
||||
$helper->tooltip = $this->l('Total number of messages having open status.');
|
||||
$helper->value = (int) $open;
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-pending-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color3';
|
||||
$helper->title = $this->l('Closed threads', null, null, false);
|
||||
$helper->value = (int) ($all - ($open + $pending));
|
||||
$helper->tooltip = $this->l('Total number of messages having closed status.');
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$contacts = CustomerThread::getContacts();
|
||||
$categories = Contact::getCategoriesContacts();
|
||||
if ($contacts) {
|
||||
$contacts = array_column($contacts, null, 'id_contact');
|
||||
}
|
||||
|
||||
if ($categories) {
|
||||
foreach ($categories as $idContact => $category) {
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-pending-messages';
|
||||
$helper->icon = 'icon-envelope';
|
||||
$helper->color = 'color'.(($idContact+1)%3 ? ($idContact+1)%3 : '4');
|
||||
$helper->title = $category['name'];
|
||||
if (isset($contacts[$category['id_contact']])) {
|
||||
$helper->href = self::$currentIndex.'&token='.$this->token.'&id_customer_thread='.$contacts[$category['id_contact']]['id_customer_thread'].'&viewcustomer_thread';
|
||||
if ($contacts[$category['id_contact']]['total'] > 1) {
|
||||
$helper->value = $contacts[$category['id_contact']]['total'].' '.$this->l('New messages');
|
||||
} else {
|
||||
$helper->value = $contacts[$category['id_contact']]['total'].' '.$this->l('New message');
|
||||
}
|
||||
} else {
|
||||
$helper->value = $this->l('No new messages');
|
||||
}
|
||||
|
||||
$helper->tooltip = $this->l('Total number of messages sent to').' '.$category['name'];
|
||||
$this->kpis[] = $helper;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::renderKpis();
|
||||
}
|
||||
|
||||
@@ -603,64 +865,54 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
$next_thread = CustomerThread::getNextThread((int)$thread->id);
|
||||
|
||||
$contacts = Contact::getContacts($this->context->language->id);
|
||||
|
||||
$actions = array();
|
||||
|
||||
if ($next_thread) {
|
||||
$next_thread = array(
|
||||
'href' => self::$currentIndex.'&id_customer_thread='.(int)$next_thread.'&viewcustomer_thread&token='.$this->token,
|
||||
'name' => $this->l('Reply to the next unanswered message in this thread')
|
||||
);
|
||||
}
|
||||
|
||||
if ($thread->status != 'closed') {
|
||||
$actions['closed'] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=2&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
if ($thread->status != CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED) {
|
||||
$actions[CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED.'&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
'label' => $this->l('Mark as "handled"'),
|
||||
'name' => 'setstatus',
|
||||
'value' => 2
|
||||
'value' => CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED
|
||||
);
|
||||
} else {
|
||||
$actions['open'] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
$actions[CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN.'&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
'label' => $this->l('Re-open'),
|
||||
'name' => 'setstatus',
|
||||
'value' => 1
|
||||
'value' => CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN
|
||||
);
|
||||
}
|
||||
|
||||
if ($thread->status != 'pending1') {
|
||||
$actions['pending1'] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=3&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
if ($thread->status != CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1) {
|
||||
$actions[CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1.'&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
'label' => $this->l('Mark as "pending 1" (will be answered later)'),
|
||||
'name' => 'setstatus',
|
||||
'value' => 3
|
||||
'value' => CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1
|
||||
);
|
||||
} else {
|
||||
$actions['pending1'] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
$actions[CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN.'&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
'label' => $this->l('Disable pending status'),
|
||||
'name' => 'setstatus',
|
||||
'value' => 1
|
||||
'value' => CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN
|
||||
);
|
||||
}
|
||||
|
||||
if ($thread->status != 'pending2') {
|
||||
$actions['pending2'] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=4&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
if ($thread->status != CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2) {
|
||||
$actions[CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2.'&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
'label' => $this->l('Mark as "pending 2" (will be answered later)'),
|
||||
'name' => 'setstatus',
|
||||
'value' => 4
|
||||
'value' => CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2
|
||||
);
|
||||
} else {
|
||||
$actions['pending2'] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
$actions[CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2] = array(
|
||||
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN.'&id_customer_thread='.(int)Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||
'label' => $this->l('Disable pending status'),
|
||||
'name' => 'setstatus',
|
||||
'value' => 1
|
||||
'value' => CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN
|
||||
);
|
||||
}
|
||||
|
||||
@@ -701,6 +953,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
$this->context->smarty->assign('display', 'view');
|
||||
$this->tpl_view_vars = array(
|
||||
'id_customer_thread' => $id_customer_thread,
|
||||
'thread' => $thread,
|
||||
@@ -710,7 +963,6 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'messages' => $messages,
|
||||
'first_message' => $first_message,
|
||||
'contact' => $contact,
|
||||
'next_thread' => $next_thread,
|
||||
'orders' => isset($orders) ? $orders : false,
|
||||
'customer' => isset($customer) ? $customer : false,
|
||||
'products' => isset($products) ? $products : false,
|
||||
@@ -721,10 +973,6 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'timeline_items' => $timeline_items,
|
||||
);
|
||||
|
||||
if ($next_thread) {
|
||||
$this->tpl_view_vars['next_thread'] = $next_thread;
|
||||
}
|
||||
|
||||
return parent::renderView();
|
||||
}
|
||||
|
||||
@@ -737,10 +985,22 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
|
||||
$content = '';
|
||||
if (!$message['private']) {
|
||||
$content .= $this->l('Message to: ').' <span class="badge">'.(!$message['id_employee'] ? $message['subject'] : $message['customer_name']).'</span><br/>';
|
||||
$customerName = false;
|
||||
if (!$message['id_customer']) {
|
||||
$customerName = $message['user_name'];
|
||||
} else if ($message['customer_name']) {
|
||||
$customerName = $message['customer_name'];
|
||||
}
|
||||
|
||||
if ($message['id_employee'] && $customerName) {
|
||||
$content .= $this->l('Message to: ').' <span class="badge">'.($customerName).'</span><br/><br/>';
|
||||
}
|
||||
} else {
|
||||
$content .= '<span class="label label-info">'.$this->l('Private').'</span><br/><br/>';
|
||||
}
|
||||
|
||||
if (Validate::isLoadedObject($product)) {
|
||||
$content .= '<br/>'.$this->l('Room type: ').'<span class="label label-info">'.$product->name.'</span><br/><br/>';
|
||||
$content .= $this->l('Room type: ').'<span class="label label-info">'.$product->name.'</span><br/><br/>';
|
||||
}
|
||||
$content .= Tools::safeOutput($message['message']);
|
||||
|
||||
@@ -778,6 +1038,22 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
public function initToolbarTitle()
|
||||
{
|
||||
parent::initToolbarTitle();
|
||||
switch ($this->display) {
|
||||
case 'view':
|
||||
if (!($thread = $this->loadObject())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($thread->id) {
|
||||
$this->toolbar_title[] = sprintf($this->l('Title: %1$s'), $thread->subject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function displayMessage($message, $email = false, $id_employee = null)
|
||||
{
|
||||
$tpl = $this->createTemplate('message.tpl');
|
||||
@@ -1079,7 +1355,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$ct->id_contact = $id_contact;
|
||||
$ct->id_lang = (int)Configuration::get('PS_LANG_DEFAULT');
|
||||
$ct->id_shop = $this->context->shop->id; //new customer threads for unrecognized mails are not shown without shop id
|
||||
$ct->status = 'open';
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$ct->token = Tools::passwdGen(12);
|
||||
$ct->add();
|
||||
} else {
|
||||
|
||||
@@ -80,25 +80,11 @@ class AdminEmailsControllerCore extends AdminController
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
||||
foreach (Contact::getContacts($this->context->language->id) as $contact) {
|
||||
$arr[] = array('email_message' => $contact['id_contact'], 'name' => $contact['name']);
|
||||
}
|
||||
|
||||
$this->fields_options = array(
|
||||
'email' => array(
|
||||
'title' => $this->l('Email'),
|
||||
'icon' => 'icon-envelope',
|
||||
'fields' => array(
|
||||
'PS_MAIL_EMAIL_MESSAGE' => array(
|
||||
'title' => $this->l('Send email to'),
|
||||
'desc' => $this->l('Where customers send messages from the order page.'),
|
||||
'validation' => 'isUnsignedId',
|
||||
'type' => 'select',
|
||||
'cast' => 'intval',
|
||||
'identifier' => 'email_message',
|
||||
'list' => $arr
|
||||
),
|
||||
'fields' => array(
|
||||
'PS_MAIL_METHOD' => array(
|
||||
'title' => '',
|
||||
'validation' => 'isGenericName',
|
||||
|
||||
@@ -1722,13 +1722,17 @@ class AdminOrdersControllerCore extends AdminController
|
||||
$id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder($customer->email, $order->id);
|
||||
if (!$id_customer_thread) {
|
||||
$customer_thread = new CustomerThread();
|
||||
$customer_thread->id_contact = 0;
|
||||
$customer_thread->id_contact = (int)Configuration::get('PS_MAIL_EMAIL_MESSAGE');
|
||||
$customer_thread->id_customer = (int)$order->id_customer;
|
||||
$customer_thread->user_name = $customer->firstname.' '.$customer->lastname;
|
||||
$customer_thread->phone = $customer->phone;
|
||||
$customer_thread->subject = $order->reference;
|
||||
$customer_thread->id_employee = (int)$this->context->employee->id;
|
||||
$customer_thread->id_shop = (int)$this->context->shop->id;
|
||||
$customer_thread->id_order = (int)$order->id;
|
||||
$customer_thread->id_lang = (int)$this->context->language->id;
|
||||
$customer_thread->email = $customer->email;
|
||||
$customer_thread->status = 'open';
|
||||
$customer_thread->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$customer_thread->token = Tools::passwdGen(12);
|
||||
$customer_thread->add();
|
||||
} else {
|
||||
@@ -1761,7 +1765,7 @@ class AdminOrdersControllerCore extends AdminController
|
||||
if (@Mail::Send(
|
||||
(int)$order->id_lang,
|
||||
'order_merchant_comment',
|
||||
Mail::l('New message regarding your order', (int)$order->id_lang),
|
||||
Mail::l('New message regarding your booking', (int)$order->id_lang),
|
||||
$varsTpl,
|
||||
$customer->email,
|
||||
$customer->firstname.' '.$customer->lastname,
|
||||
@@ -2820,13 +2824,15 @@ class AdminOrdersControllerCore extends AdminController
|
||||
$helper->value = $objOrder->source;
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
$objCustomerThread = new CustomerThread();
|
||||
$idCustomerThread = $objCustomerThread->getIdCustomerThreadByIdOrder($objOrder->id);
|
||||
$helper = new HelperKpi();
|
||||
$helper->id = 'box-messages';
|
||||
$helper->icon = 'icon-comments';
|
||||
$helper->color = 'color2';
|
||||
$helper->title = $this->l('Messages');
|
||||
$helper->tooltip = $this->l('Messages is the number of customer messages for this order.');
|
||||
$helper->href = $this->context->link->getAdminLink('AdminCustomerThreads').'&id_order='.$objOrder->id;
|
||||
$helper->href = $this->context->link->getAdminLink('AdminCustomerThreads').((int) $idCustomerThread ? '&viewcustomer_thread&id_customer_thread='.(int) $idCustomerThread : '');
|
||||
$helper->value = count(CustomerThread::getCustomerMessages($objOrder->id_customer, null, $objOrder->id, CustomerMessage::QLO_CUSTOMER_MESSAGE_BY_CUSTOMER));
|
||||
$this->kpis[] = $helper;
|
||||
|
||||
@@ -3474,10 +3480,28 @@ class AdminOrdersControllerCore extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
$objCustomerThread = new CustomerThread();
|
||||
$messages = Message::getMessagesByOrderId($order->id, true);
|
||||
if ($customerMessages = CustomerMessage::getMessagesByOrderId($order->id, true)) {
|
||||
foreach ($messages as $messageKey => $message) {
|
||||
foreach ($customerMessages as $customerMessageKey => $customerMessage) {
|
||||
if (strcmp($message['message'], $customerMessage['message']) == 0) {
|
||||
unset($messages[$messageKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$messages = array_merge($customerMessages, $messages);
|
||||
usort($messages, function ($a, $b) {
|
||||
return strtotime($a['date_add']) < strtotime($b['date_add']);
|
||||
});
|
||||
}
|
||||
|
||||
// send hotel standalone and standalone products
|
||||
$objProduct = new Product();
|
||||
$hotelStandaloneProducts = $objProduct->getServiceProducts(null, Product::SELLING_PREFERENCE_HOTEL_STANDALONE);
|
||||
$standaloneProducts = $objProduct->getServiceProducts(null, Product::SELLING_PREFERENCE_STANDALONE);
|
||||
|
||||
$this->tpl_view_vars = array(
|
||||
'hotelStandaloneProducts' => $hotelStandaloneProducts,
|
||||
'standaloneProducts' => $standaloneProducts,
|
||||
@@ -3527,8 +3551,9 @@ class AdminOrdersControllerCore extends AdminController
|
||||
'discounts' => $order->getCartRules(),
|
||||
'total_paid' => $order->getTotalPaid(),
|
||||
'customer_thread_message' => CustomerThread::getCustomerMessages($order->id_customer, null, $order->id),
|
||||
'id_customer_thread' => $objCustomerThread->getIdCustomerThreadByIdOrder($order->id),
|
||||
'orderMessages' => OrderMessage::getOrderMessages($order->id_lang),
|
||||
'messages' => Message::getMessagesByOrderId($order->id, true),
|
||||
'messages' => $messages,
|
||||
'carrier' => new Carrier($order->id_carrier),
|
||||
'history' => $history,
|
||||
'order_payment_detail' => $order_payment_detail,
|
||||
|
||||
@@ -3000,8 +3000,6 @@ class AdminProductsControllerCore extends AdminController
|
||||
$objRoomType = new HotelRoomType();
|
||||
$objRoomType->id_product = $product->id;
|
||||
$objRoomType->id_hotel = $id_hotel;
|
||||
$idBedTypes = Tools::getValue('id_bed_types', array());
|
||||
$objRoomType->id_bed_types = json_encode($idBedTypes);
|
||||
$objRoomType->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,7 +499,14 @@ class AdminStatsControllerCore extends AdminStatsTabController
|
||||
|
||||
public static function getPendingMessages()
|
||||
{
|
||||
return CustomerThread::getTotalCustomerThreads('status LIKE "%pending%" OR status = "open"'.Shop::addSqlRestriction());
|
||||
$pendingStatuses = array(
|
||||
CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2,
|
||||
CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1
|
||||
);
|
||||
|
||||
return CustomerThread::getTotalCustomerThreads(
|
||||
'`status` IN ('.implode(',', $pendingStatuses).')'.Shop::addSqlRestriction()
|
||||
);
|
||||
}
|
||||
|
||||
public static function getAverageMessageResponseTime($date_from, $date_to, $return_seconds = false)
|
||||
@@ -530,13 +537,23 @@ class AdminStatsControllerCore extends AdminStatsTabController
|
||||
|
||||
public static function getMessagesPerThread($date_from, $date_to)
|
||||
{
|
||||
$accessWhere = '';
|
||||
$employee = Context::getContext()->employee;
|
||||
if (!$employee->isSuperAdmin()) {
|
||||
$idProfile = $employee->id_profile;
|
||||
if ($acsHtls = HotelBranchInformation::getProfileAccessedHotels($idProfile, 1, 1)) {
|
||||
$accessWhere = ' AND ct.`id_order` IN (SELECT `id_order` FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE `id_hotel` IN ('.implode(',', $acsHtls).'))';
|
||||
} else {
|
||||
$accessWhere = ' AND ct.`id_order` = 0 ';
|
||||
}
|
||||
}
|
||||
|
||||
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
|
||||
SELECT COUNT(*) as messages
|
||||
FROM `'._DB_PREFIX_.'customer_thread` ct
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer_message` cm ON (ct.id_customer_thread = cm.id_customer_thread)
|
||||
WHERE ct.`date_add` BETWEEN "'.pSQL($date_from).' 00:00:00" AND "'.pSQL($date_to).' 23:59:59"
|
||||
'.Shop::addSqlRestriction().'
|
||||
AND status = "closed"
|
||||
'.Shop::addSqlRestriction().$accessWhere.'
|
||||
GROUP BY ct.id_customer_thread');
|
||||
$threads = $messages = 0;
|
||||
foreach ($result as $row) {
|
||||
|
||||
@@ -39,16 +39,40 @@ class ContactControllerCore extends FrontController
|
||||
$saveContactKey = $this->context->cookie->contactFormKey;
|
||||
$extension = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
|
||||
$file_attachment = Tools::fileAttachment('fileUpload');
|
||||
$message = Tools::getValue('message'); // Html entities is not usefull, iscleanHtml check there is no bad html tags.
|
||||
$message = trim(Tools::getValue('message')); // Html entities is not usefull, iscleanHtml check there is no bad html tags.
|
||||
$url = Tools::getValue('url');
|
||||
$phone = Tools::getValue('phone');
|
||||
$subject = trim(Tools::getValue('subject'));
|
||||
$userName = Tools::getValue('user_name');
|
||||
$id_contact = (int)Tools::getValue('id_contact');
|
||||
$objCustomerThread = new CustomerThread();
|
||||
$id_customer_thread = (int)$objCustomerThread->getIdCustomerThreadByToken(Tools::getValue('token'));
|
||||
$nameRequired = Configuration::get('PS_CUSTOMER_SERVICE_REQUIRED_NAME');
|
||||
$phoneRequired = Configuration::get('PS_CUSTOMER_SERVICE_REQUIRED_PHONE');
|
||||
if (!Configuration::get('PS_CUSTOMER_SERVICE_DISPLAY_CONTACT')) {
|
||||
$id_contact = (int) Configuration::get('PS_CUSTOMER_SERVICE_CONTACT');
|
||||
}
|
||||
|
||||
if (!($from = trim(Tools::getValue('from'))) || !Validate::isEmail($from)) {
|
||||
$this->errors[] = Tools::displayError('Invalid email address.');
|
||||
} elseif (!$message) {
|
||||
$this->errors[] = Tools::displayError('The message cannot be blank.');
|
||||
} elseif (!Validate::isCleanHtml($message)) {
|
||||
$this->errors[] = Tools::displayError('Invalid message');
|
||||
} elseif (!($id_contact = (int)Tools::getValue('id_contact')) || !(Validate::isLoadedObject($contact = new Contact($id_contact, $this->context->language->id)))) {
|
||||
$this->errors[] = Tools::displayError('Please select a subject from the list provided. ');
|
||||
} elseif (!$id_customer_thread && !$subject) {
|
||||
$this->errors[] = Tools::displayError('The title cannot be blank.');
|
||||
} elseif (!$id_customer_thread && !Validate::isCleanHtml($subject)) {
|
||||
$this->errors[] = Tools::displayError('Invalid subject$subject');
|
||||
} else if (!$id_customer_thread && $nameRequired && !trim($userName)) {
|
||||
$this->errors[] = Tools::displayError('Name is required.');
|
||||
} else if (!$id_customer_thread && trim($nameRequired) && !Validate::isGenericName($userName)) {
|
||||
$this->errors[] = Tools::displayError('Invalid name.');
|
||||
} else if (!$id_customer_thread && $phoneRequired && !trim($phone)) {
|
||||
$this->errors[] = Tools::displayError('Phone is required.');
|
||||
} else if (!$id_customer_thread && trim($phone) && !Validate::isPhoneNumber($phone)) {
|
||||
$this->errors[] = Tools::displayError('Invalid Phone number.');
|
||||
} elseif (!Validate::isLoadedObject($contact = new Contact($id_contact, $this->context->language->id))) {
|
||||
$this->errors[] = Tools::displayError('Please choose who to send the message to.');
|
||||
} elseif (!empty($file_attachment['name']) && $file_attachment['error'] != 0) {
|
||||
$this->errors[] = Tools::displayError('An error occurred during the file-upload process.');
|
||||
} elseif (!empty($file_attachment['name']) && !in_array(Tools::strtolower(substr($file_attachment['name'], -4)), $extension) && !in_array(Tools::strtolower(substr($file_attachment['name'], -5)), $extension)) {
|
||||
@@ -71,44 +95,15 @@ class ContactControllerCore extends FrontController
|
||||
$id_order = (int) $order->id_customer === (int) $customer->id ? $id_order : 0;
|
||||
}
|
||||
|
||||
if (!((
|
||||
($id_customer_thread = (int)Tools::getValue('id_customer_thread'))
|
||||
&& (int)Db::getInstance()->getValue('
|
||||
SELECT cm.id_customer_thread FROM '._DB_PREFIX_.'customer_thread cm
|
||||
WHERE cm.id_customer_thread = '.(int)$id_customer_thread.' AND cm.id_shop = '.(int)$this->context->shop->id.' AND token = \''.pSQL(Tools::getValue('token')).'\'')
|
||||
) || (
|
||||
$id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder($from, $id_order, $id_contact)
|
||||
))) {
|
||||
$fields = Db::getInstance()->executeS('
|
||||
SELECT cm.id_customer_thread, cm.id_contact, cm.id_customer, cm.id_order, cm.id_product, cm.email
|
||||
FROM '._DB_PREFIX_.'customer_thread cm
|
||||
WHERE email = \''.pSQL($from).'\' AND cm.id_shop = '.(int)$this->context->shop->id.' AND ('.
|
||||
($customer->id ? 'id_customer = '.(int)$customer->id.' OR ' : '').'
|
||||
id_order = '.(int)$id_order.')');
|
||||
$score = 0;
|
||||
foreach ($fields as $key => $row) {
|
||||
$tmp = 0;
|
||||
if ((int)$row['id_customer'] && $row['id_customer'] != $customer->id && $row['email'] != $from) {
|
||||
continue;
|
||||
}
|
||||
if ($row['id_order'] != 0 && $id_order != $row['id_order']) {
|
||||
continue;
|
||||
}
|
||||
if ($row['email'] == $from) {
|
||||
$tmp += 4;
|
||||
}
|
||||
if ($row['id_contact'] == $id_contact) {
|
||||
$tmp++;
|
||||
}
|
||||
if (Tools::getValue('id_product') != 0 && $row['id_product'] == Tools::getValue('id_product')) {
|
||||
$tmp += 2;
|
||||
}
|
||||
if ($tmp >= 5 && $tmp >= $score) {
|
||||
$score = $tmp;
|
||||
$id_customer_thread = $row['id_customer_thread'];
|
||||
}
|
||||
}
|
||||
if (!$id_customer_thread) {
|
||||
$id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder(
|
||||
$from,
|
||||
$id_order,
|
||||
$id_contact,
|
||||
' AND a.`status` !='. CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED
|
||||
);
|
||||
}
|
||||
|
||||
$old_message = Db::getInstance()->getValue('
|
||||
SELECT cm.message FROM '._DB_PREFIX_.'customer_message cm
|
||||
LEFT JOIN '._DB_PREFIX_.'customer_thread cc on (cm.id_customer_thread = cc.id_customer_thread)
|
||||
@@ -123,36 +118,31 @@ class ContactControllerCore extends FrontController
|
||||
if ($contact->customer_service) {
|
||||
if ((int)$id_customer_thread) {
|
||||
$ct = new CustomerThread($id_customer_thread);
|
||||
$ct->status = 'open';
|
||||
$ct->id_lang = (int)$this->context->language->id;
|
||||
$ct->id_contact = (int)$id_contact;
|
||||
$ct->id_order = (int)$id_order;
|
||||
if ($id_product = (int)Tools::getValue('id_product')) {
|
||||
$ct->id_product = $id_product;
|
||||
}
|
||||
$ct->update();
|
||||
} else {
|
||||
$ct = new CustomerThread();
|
||||
if (isset($customer->id)) {
|
||||
$ct->id_customer = (int)$customer->id;
|
||||
}
|
||||
$ct->id_shop = (int)$this->context->shop->id;
|
||||
$ct->id_order = (int)$id_order;
|
||||
if ($id_product = (int)Tools::getValue('id_product')) {
|
||||
$ct->id_product = $id_product;
|
||||
}
|
||||
$ct->id_contact = (int)$id_contact;
|
||||
$ct->id_lang = (int)$this->context->language->id;
|
||||
$ct->phone = $phone;
|
||||
$ct->user_name = $userName;
|
||||
$ct->subject = $subject;
|
||||
$ct->email = $from;
|
||||
$ct->status = 'open';
|
||||
$ct->token = Tools::passwdGen(12);
|
||||
$ct->add();
|
||||
}
|
||||
|
||||
if ($ct->id) {
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$ct->id_lang = (int)$this->context->language->id;
|
||||
$ct->id_contact = (int)$id_contact;
|
||||
|
||||
if ($ct->save()) {
|
||||
$cm = new CustomerMessage();
|
||||
$cm->id_customer_thread = $ct->id;
|
||||
$cm->message = $message;
|
||||
if ($id_product = (int)Tools::getValue('id_product')) {
|
||||
$cm->id_product = $id_product;
|
||||
}
|
||||
if (isset($file_attachment['rename']) && !empty($file_attachment['rename']) && rename($file_attachment['tmp_name'], _PS_UPLOAD_DIR_.basename($file_attachment['rename']))) {
|
||||
$cm->file_name = $file_attachment['rename'];
|
||||
@chmod(_PS_UPLOAD_DIR_.basename($file_attachment['rename']), 0664);
|
||||
@@ -168,33 +158,22 @@ class ContactControllerCore extends FrontController
|
||||
}
|
||||
|
||||
if (!count($this->errors)) {
|
||||
$var_list = array(
|
||||
'{order_name}' => '-',
|
||||
'{attached_file}' => '-',
|
||||
'{message}' => Tools::nl2br(stripslashes($message)),
|
||||
'{email}' => $from,
|
||||
'{product_name}' => '',
|
||||
);
|
||||
$smartyMailVars['message'] = Tools::nl2br(stripslashes($message));
|
||||
$smartyMailVars['email'] = $ct->email;
|
||||
$smartyMailVars['subject'] = $ct->subject;
|
||||
$smartyMailVars['phone'] = $ct->phone;
|
||||
$smartyMailVars['user_name'] = $ct->user_name;
|
||||
|
||||
if (isset($file_attachment['name'])) {
|
||||
$var_list['{attached_file}'] = $file_attachment['name'];
|
||||
}
|
||||
|
||||
$id_product = (int)Tools::getValue('id_product');
|
||||
|
||||
if (isset($ct) && Validate::isLoadedObject($ct) && $ct->id_order) {
|
||||
$order = new Order((int)$ct->id_order);
|
||||
$var_list['{order_name}'] = $order->getUniqReference();
|
||||
$var_list['{id_order}'] = (int)$order->id;
|
||||
}
|
||||
|
||||
if ($id_product) {
|
||||
$product = new Product((int)$id_product);
|
||||
if (Validate::isLoadedObject($product) && isset($product->name[Context::getContext()->language->id])) {
|
||||
$var_list['{product_name}'] = $product->name[Context::getContext()->language->id];
|
||||
}
|
||||
$smartyMailVars['attached_file'] = $file_attachment['name'];
|
||||
}
|
||||
|
||||
$contact_content_txt = $this->getEmailTemplateContent('contact_content_txt.tpl', Mail::TYPE_TEXT, $smartyMailVars);
|
||||
$contact_content_html = $this->getEmailTemplateContent('contact_content_html.tpl', Mail::TYPE_TEXT, $smartyMailVars);
|
||||
$var_list = array(
|
||||
'{contact_content_txt}' => $contact_content_txt,
|
||||
'{contact_content_html}' => $contact_content_html,
|
||||
);
|
||||
if (!empty($contact->email)) {
|
||||
Mail::Send(
|
||||
$this->context->language->id,
|
||||
@@ -226,6 +205,30 @@ class ContactControllerCore extends FrontController
|
||||
}
|
||||
}
|
||||
|
||||
protected function getEmailTemplateContent($template_name, $mail_type, $var)
|
||||
{
|
||||
$email_configuration = Configuration::get('PS_MAIL_TYPE');
|
||||
if ($email_configuration != $mail_type && $email_configuration != Mail::TYPE_BOTH) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$pathToFindEmail = array(
|
||||
_PS_THEME_DIR_.'mails'.DIRECTORY_SEPARATOR.$this->context->language->iso_code.DIRECTORY_SEPARATOR.$template_name,
|
||||
_PS_THEME_DIR_.'mails'.DIRECTORY_SEPARATOR.'en'.DIRECTORY_SEPARATOR.$template_name,
|
||||
_PS_MAIL_DIR_.$this->context->language->iso_code.DIRECTORY_SEPARATOR.$template_name,
|
||||
_PS_MAIL_DIR_.'en'.DIRECTORY_SEPARATOR.$template_name,
|
||||
);
|
||||
|
||||
foreach ($pathToFindEmail as $path) {
|
||||
if (Tools::file_exists_cache($path)) {
|
||||
$this->context->smarty->assign($var);
|
||||
return $this->context->smarty->fetch($path);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function setMedia()
|
||||
{
|
||||
parent::setMedia();
|
||||
@@ -259,27 +262,30 @@ class ContactControllerCore extends FrontController
|
||||
|
||||
$email = Tools::safeOutput(Tools::getValue('from',
|
||||
((isset($this->context->cookie) && isset($this->context->cookie->email) && Validate::isEmail($this->context->cookie->email)) ? $this->context->cookie->email : '')));
|
||||
$customerName = isset($this->context->customer) ? $this->context->customer->firstname.' '.$this->context->customer->lastname : '';
|
||||
$customerPhone = isset($this->context->customer) ? $this->context->customer->phone: '';
|
||||
$this->context->smarty->assign(array(
|
||||
'errors' => $this->errors,
|
||||
'email' => $email,
|
||||
'customerName' => $customerName,
|
||||
'customerPhone' => $customerPhone,
|
||||
'fileupload' => Configuration::get('PS_CUSTOMER_SERVICE_FILE_UPLOAD'),
|
||||
'max_upload_size' => (int)Tools::getMaxUploadSize()
|
||||
));
|
||||
|
||||
if (($id_customer_thread = (int)Tools::getValue('id_customer_thread')) && $token = Tools::getValue('token')) {
|
||||
$customer_thread = Db::getInstance()->getRow('
|
||||
if ($token = Tools::getValue('token')) {
|
||||
if ($customer_thread = Db::getInstance()->getRow('
|
||||
SELECT cm.*
|
||||
FROM '._DB_PREFIX_.'customer_thread cm
|
||||
WHERE cm.id_customer_thread = '.(int)$id_customer_thread.'
|
||||
AND cm.id_shop = '.(int)$this->context->shop->id.'
|
||||
WHERE cm.id_shop = '.(int)$this->context->shop->id.'
|
||||
AND token = \''.pSQL($token).'\'
|
||||
');
|
||||
|
||||
$order = new Order((int)$customer_thread['id_order']);
|
||||
if (Validate::isLoadedObject($order)) {
|
||||
$customer_thread['reference'] = $order->getUniqReference();
|
||||
')) {
|
||||
$order = new Order((int)$customer_thread['id_order']);
|
||||
if (Validate::isLoadedObject($order)) {
|
||||
$customer_thread['reference'] = $order->getUniqReference();
|
||||
}
|
||||
$this->context->smarty->assign('customerThread', $customer_thread);
|
||||
}
|
||||
$this->context->smarty->assign('customerThread', $customer_thread);
|
||||
}
|
||||
|
||||
$objShop = new Shop();
|
||||
@@ -330,6 +336,11 @@ class ContactControllerCore extends FrontController
|
||||
'contacts' => Contact::getContacts($this->context->language->id),
|
||||
'message' => html_entity_decode(Tools::getValue('message')),
|
||||
'contactKey' => $contactKey,
|
||||
'contactNameRequired' => Configuration::get('PS_CUSTOMER_SERVICE_REQUIRED_NAME'),
|
||||
'displayContactName' => Configuration::get('PS_CUSTOMER_SERVICE_DISPLAY_NAME'),
|
||||
'contactPhoneRequired' => Configuration::get('PS_CUSTOMER_SERVICE_REQUIRED_PHONE'),
|
||||
'displayContactPhone' => Configuration::get('PS_CUSTOMER_SERVICE_DISPLAY_PHONE'),
|
||||
'allowContactSelection' => Configuration::get('PS_CUSTOMER_SERVICE_DISPLAY_CONTACT')
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -493,7 +493,7 @@ class OrderDetailControllerCore extends FrontController
|
||||
'deliveryAddressFormatedValues' => $deliveryAddressFormatedValues,
|
||||
'deliveryState' => (Validate::isLoadedObject($addressDelivery) && $addressDelivery->id_state) ? new State($addressDelivery->id_state) : false,
|
||||
'is_guest' => false,
|
||||
'messages' => CustomerMessage::getMessagesByOrderId((int) $order->id, false),
|
||||
'messages' => CustomerMessage::getMessagesByOrderId((int) $order->id),
|
||||
'CUSTOMIZE_FILE' => Product::CUSTOMIZE_FILE,
|
||||
'CUSTOMIZE_TEXTFIELD' => Product::CUSTOMIZE_TEXTFIELD,
|
||||
'isRecyclable' => Configuration::get('PS_RECYCLABLE_PACK'),
|
||||
@@ -758,26 +758,32 @@ class OrderDetailControllerCore extends FrontController
|
||||
$id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder($this->context->customer->email, $order->id);
|
||||
$id_product = (int)Tools::getValue('id_product');
|
||||
$cm = new CustomerMessage();
|
||||
$objCustomer = new Customer($order->id_customer);
|
||||
if (!$id_customer_thread) {
|
||||
$ct = new CustomerThread();
|
||||
$ct->id_contact = 0;
|
||||
$ct->id_contact = (int)Configuration::get('PS_MAIL_EMAIL_MESSAGE');
|
||||
$ct->id_customer = (int)$order->id_customer;
|
||||
$ct->user_name = $objCustomer->firstname.' '.$objCustomer->lastname;
|
||||
$ct->subject = $order->reference;
|
||||
$ct->phone = $objCustomer->phone;
|
||||
$ct->id_shop = (int)$this->context->shop->id;
|
||||
if ($id_product && $order->orderContainProduct($id_product)) {
|
||||
$ct->id_product = $id_product;
|
||||
}
|
||||
$ct->id_order = (int)$order->id;
|
||||
$ct->id_lang = (int)$this->context->language->id;
|
||||
$ct->email = $this->context->customer->email;
|
||||
$ct->status = 'open';
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$ct->token = Tools::passwdGen(12);
|
||||
$ct->add();
|
||||
} else {
|
||||
$ct = new CustomerThread((int)$id_customer_thread);
|
||||
$ct->status = 'open';
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$ct->update();
|
||||
}
|
||||
|
||||
if ($id_product && $order->orderContainProduct($id_product)) {
|
||||
$cm->id_product = $id_product;
|
||||
}
|
||||
|
||||
$cm->user_agent = $_SERVER['HTTP_USER_AGENT'];
|
||||
$cm->id_customer_thread = $ct->id;
|
||||
$cm->message = $msgText;
|
||||
$cm->ip_address = (int)ip2long($_SERVER['REMOTE_ADDR']);
|
||||
@@ -829,7 +835,7 @@ class OrderDetailControllerCore extends FrontController
|
||||
// send message html in json
|
||||
$response['status'] = true;
|
||||
|
||||
$message = CustomerMessage::getMessagesByOrderId($order->id, false)[0];
|
||||
$message = CustomerMessage::getMessagesByOrderId($order->id)[0];
|
||||
$this->context->smarty->assign(array('message' => $message));
|
||||
$response['message_html'] = $this->context->smarty->fetch(_PS_THEME_DIR_.'_partials/order-message.tpl');
|
||||
} else {
|
||||
@@ -887,4 +893,4 @@ class OrderDetailControllerCore extends FrontController
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,6 +634,7 @@ CREATE TABLE `PREFIX_customer_message` (
|
||||
`id_customer_thread` int(11) DEFAULT NULL,
|
||||
`id_employee` int(10) unsigned DEFAULT NULL,
|
||||
`message` MEDIUMTEXT NOT NULL,
|
||||
`id_product` int(10) unsigned DEFAULT NULL,
|
||||
`file_name` varchar(18) DEFAULT NULL,
|
||||
`ip_address` varchar(16) DEFAULT NULL,
|
||||
`user_agent` varchar(128) DEFAULT NULL,
|
||||
@@ -658,9 +659,12 @@ CREATE TABLE `PREFIX_customer_thread` (
|
||||
`id_lang` int(10) unsigned NOT NULL,
|
||||
`id_contact` int(10) unsigned NOT NULL,
|
||||
`id_customer` int(10) unsigned DEFAULT NULL,
|
||||
`id_employee` int(10) unsigned DEFAULT NULL,
|
||||
`id_order` int(10) unsigned DEFAULT NULL,
|
||||
`id_product` int(10) unsigned DEFAULT NULL,
|
||||
`status` enum('open','closed','pending1','pending2') NOT NULL DEFAULT 'open',
|
||||
`user_name` VARCHAR(128) DEFAULT NULL,
|
||||
`phone` VARCHAR(32) DEFAULT NULL,
|
||||
`subject` TEXT DEFAULT NULL,
|
||||
`status` INT(10) NOT NULL DEFAULT 1,
|
||||
`email` varchar(128) NOT NULL,
|
||||
`token` varchar(12) DEFAULT NULL,
|
||||
`date_add` datetime NOT NULL,
|
||||
@@ -670,8 +674,7 @@ CREATE TABLE `PREFIX_customer_thread` (
|
||||
KEY `id_lang` (`id_lang`),
|
||||
KEY `id_contact` (`id_contact`),
|
||||
KEY `id_customer` (`id_customer`),
|
||||
KEY `id_order` (`id_order`),
|
||||
KEY `id_product` (`id_product`)
|
||||
KEY `id_order` (`id_order`)
|
||||
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION;
|
||||
|
||||
CREATE TABLE `PREFIX_order_customer_guest_detail` (
|
||||
|
||||
@@ -955,6 +955,21 @@
|
||||
</configuration>
|
||||
<configuration id="PS_BACKDATE_ORDER_EMPLOYEES" name="PS_BACKDATE_ORDER_EMPLOYEES">
|
||||
<value>0</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_REQUIRED_NAME" name="PS_CUSTOMER_SERVICE_REQUIRED_NAME">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_DISPLAY_NAME" name="PS_CUSTOMER_SERVICE_DISPLAY_NAME">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_REQUIRED_PHONE" name="PS_CUSTOMER_SERVICE_REQUIRED_PHONE">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_DISPLAY_PHONE" name="PS_CUSTOMER_SERVICE_DISPLAY_PHONE">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_DISPLAY_CONTACT" name="PS_CUSTOMER_SERVICE_DISPLAY_CONTACT">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_STANDARD_PRODUCT_ORDER_ADDRESS_PREFRENCE" name="PS_STANDARD_PRODUCT_ORDER_ADDRESS_PREFRENCE">
|
||||
<value>0</value>
|
||||
|
||||
57
js/admin/customer_thread.js
Normal file
57
js/admin/customer_thread.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright since 2010 Webkul.
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* All right is reserved,
|
||||
* Please go through this link for complete license : https://store.webkul.com/license.html
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade this module to newer
|
||||
* versions in the future. If you wish to customize this module for your
|
||||
* needs please refer to https://store.webkul.com/customisation-guidelines/ for more information.
|
||||
*
|
||||
* @author Webkul IN <support@webkul.com>
|
||||
* @copyright Since 2010 Webkul IN
|
||||
* @license https://store.webkul.com/license.html
|
||||
*/
|
||||
|
||||
$(document).ready(function() {
|
||||
if ($('#PS_CUSTOMER_SERVICE_DISPLAY_CONTACT_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_CONTACT"]').closest('.form-group').hide();
|
||||
}
|
||||
|
||||
if (!$('#PS_CUSTOMER_SERVICE_DISPLAY_NAME_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_REQUIRED_NAME"]').closest('.form-group').hide();
|
||||
}
|
||||
|
||||
if (!$('#PS_CUSTOMER_SERVICE_DISPLAY_PHONE_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_REQUIRED_PHONE"]').closest('.form-group').hide();
|
||||
}
|
||||
|
||||
$(document).on('change', '[name="PS_CUSTOMER_SERVICE_DISPLAY_CONTACT"]', function() {
|
||||
if ($('#PS_CUSTOMER_SERVICE_DISPLAY_CONTACT_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_CONTACT"]').closest('.form-group').hide();
|
||||
} else {
|
||||
$('[name="PS_CUSTOMER_SERVICE_CONTACT"]').closest('.form-group').show();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', '[name="PS_CUSTOMER_SERVICE_DISPLAY_NAME"]', function() {
|
||||
if ($('#PS_CUSTOMER_SERVICE_DISPLAY_NAME_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_REQUIRED_NAME"]').closest('.form-group').show();
|
||||
} else {
|
||||
$('[name="PS_CUSTOMER_SERVICE_REQUIRED_NAME"]').closest('.form-group').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', '[name="PS_CUSTOMER_SERVICE_DISPLAY_PHONE"]', function() {
|
||||
if ($('#PS_CUSTOMER_SERVICE_DISPLAY_PHONE_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_REQUIRED_PHONE"]').closest('.form-group').show();
|
||||
} else {
|
||||
$('[name="PS_CUSTOMER_SERVICE_REQUIRED_PHONE"]').closest('.form-group').hide();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -66,37 +66,33 @@
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Message from a {shop_name} customer</span>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span style="color:#777">
|
||||
<span style="color:#333"><strong>Customer e-mail address: <a href="mailto:{email}" style="color:#337ff1">{email}</a></strong></span><br /><br />
|
||||
<span style="color:#333"><strong>Customer message:</strong></span> {message}<br /><br />
|
||||
<span style="color:#333"><strong>Attached file:</strong></span> {attached_file}
|
||||
</span>
|
||||
</font>
|
||||
</td>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Message from a {shop_name} customer</span>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span style="color:#777">
|
||||
{contact_content_html}
|
||||
</span>
|
||||
</font>
|
||||
</td>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
|
||||
[/{shop_url}]
|
||||
[/{shop_url}]
|
||||
|
||||
Message from a {shop_name} customer
|
||||
Message from a {shop_name} customer
|
||||
|
||||
CUSTOMER E-MAIL ADDRESS: {email}
|
||||
|
||||
CUSTOMER MESSAGE: {message}
|
||||
|
||||
ORDER ID: {order_name}
|
||||
|
||||
ATTACHED FILE: {attached_file}
|
||||
{contact_content_txt}
|
||||
|
||||
{shop_name} [/{shop_url}] powered by Webkul(tm)
|
||||
[https://webkul.com]
|
||||
[https://webkul.com]
|
||||
|
||||
|
||||
15
mails/en/contact_content_html.tpl
Normal file
15
mails/en/contact_content_html.tpl
Normal file
@@ -0,0 +1,15 @@
|
||||
{if isset($user_name) && $user_name}
|
||||
<span style="color:#333"><strong>Name:</strong> {$user_name}</span><br /><br />
|
||||
{/if}
|
||||
{if isset($email) && $email}
|
||||
<span style="color:#333"><strong>E-mail: <a href="mailto:{$email}" style="color:#337ff1">{$email}</a></strong></span><br /><br />
|
||||
{/if}
|
||||
{if isset($subject) && $subject}
|
||||
<span style="color:#333"><strong>Title:</strong> {$subject}</span><br /><br />
|
||||
{/if}
|
||||
{if isset($message) && $message}
|
||||
<span style="color:#333"><strong>Customer message:</strong></span><br />{$message}<br/><br />
|
||||
{/if}
|
||||
{if isset($attached_file) && $attached_file}
|
||||
<span style="color:#333"><strong>Attached file:</strong></span> {$attached_file}
|
||||
{/if}
|
||||
18
mails/en/contact_content_txt.tpl
Normal file
18
mails/en/contact_content_txt.tpl
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
{if isset($user_name) && $user_name}
|
||||
Name: {$user_name}
|
||||
{/if}
|
||||
{if isset($email) && $email}
|
||||
E-mail: {$email}
|
||||
{/if}
|
||||
{if isset($subject) && $subject}
|
||||
Title: {$subject}
|
||||
{/if}
|
||||
|
||||
{if isset($message) && $message}
|
||||
Customer message:</strong></span><br />{$message}<br/><br />
|
||||
{/if}
|
||||
{if isset($attached_file) && $attached_file}
|
||||
Attached file:</strong></span> {$attached_file}
|
||||
{/if}
|
||||
|
||||
@@ -4,51 +4,51 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
||||
<title>Message from {shop_name}</title>
|
||||
|
||||
|
||||
<style> @media only screen and (max-width: 300px){
|
||||
|
||||
|
||||
<style> @media only screen and (max-width: 300px){
|
||||
body {
|
||||
width:218px !important;
|
||||
margin:auto !important;
|
||||
}
|
||||
.table {width:195px !important;margin:auto !important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}
|
||||
span.title{font-size:20px !important;line-height: 23px !important}
|
||||
span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}
|
||||
span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}
|
||||
td.box p{font-size: 12px !important;font-weight: bold !important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
}
|
||||
.table-recap{width: 200px!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
.address{display: block !important;margin-bottom: 10px !important;}
|
||||
.space_address{display: none !important;}
|
||||
.space_address{display: none !important;}
|
||||
}
|
||||
@media only screen and (min-width: 301px) and (max-width: 500px) {
|
||||
@media only screen and (min-width: 301px) and (max-width: 500px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
.table {width:285px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
}
|
||||
.table-recap{width: 295px !important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
|
||||
|
||||
}
|
||||
@media only screen and (min-width: 501px) and (max-width: 768px) {
|
||||
body {width:478px!important;margin:auto!important;}
|
||||
.table {width:450px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
}
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px;margin:auto!important;}
|
||||
.table {width:450px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
|
||||
}
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
|
||||
.table-recap{width: 295px!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center!important;}
|
||||
.address{display: block !important;margin-bottom: 10px !important;}
|
||||
.space_address{display: none !important;}
|
||||
.space_address{display: none !important;}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -66,39 +66,36 @@
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Hi {firstname} {lastname},</span>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<p data-html-only="1" style="border-bottom:1px solid #D6D4D4;margin:3px 0 7px;text-transform:uppercase;font-weight:500;font-size:18px;padding-bottom:10px">
|
||||
Message from a customer </p>
|
||||
<span style="color:#777">
|
||||
You have received a new message regarding order with the reference <span style="color:#333"><strong>{order_name}</strong></span>.<br /><br />
|
||||
<span style="color:#333"><strong>Customer:</strong></span> {firstname} {lastname} ({email})<br /><br />
|
||||
{message}
|
||||
</span>
|
||||
</font>
|
||||
</td>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Message from a customer</span>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span style="color:#777">
|
||||
You have received a new message regarding booking with the reference <span style="color:#333"><strong>{order_name}</strong></span>.<br /><br />
|
||||
<span style="color:#333"><strong>Name:</strong></span> {firstname} {lastname} <br /><br />
|
||||
<span style="color:#333"><strong>E-mail: <a href="mailto:{email}" style="color:#337ff1">{email}</a></strong></span><br /><br />
|
||||
<span style="color:#333"><strong>Customer message:</strong></span><br />{message}<br/><br />
|
||||
</span>
|
||||
</font>
|
||||
</td>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
|
||||
[/{shop_url}]
|
||||
[/{shop_url}]
|
||||
|
||||
Hi {firstname} {lastname},
|
||||
Hi {firstname} {lastname},
|
||||
|
||||
You have received a new message regarding order with the reference
|
||||
You have received a new message regarding booking with the reference
|
||||
{order_name}.
|
||||
|
||||
CUSTOMER: {firstname} {lastname} ({email})
|
||||
NAME: {firstname} {lastname}
|
||||
|
||||
{message}
|
||||
E-mail: {email}
|
||||
|
||||
Customer message:
|
||||
{message}
|
||||
|
||||
{shop_name} [/{shop_url}] powered by Webkul(tm)
|
||||
[https://webkul.com]
|
||||
[https://webkul.com]
|
||||
|
||||
|
||||
@@ -4,51 +4,51 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
||||
<title>Message from {shop_name}</title>
|
||||
|
||||
|
||||
<style> @media only screen and (max-width: 300px){
|
||||
|
||||
|
||||
<style> @media only screen and (max-width: 300px){
|
||||
body {
|
||||
width:218px !important;
|
||||
margin:auto !important;
|
||||
}
|
||||
.table {width:195px !important;margin:auto !important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}
|
||||
span.title{font-size:20px !important;line-height: 23px !important}
|
||||
span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}
|
||||
span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}
|
||||
td.box p{font-size: 12px !important;font-weight: bold !important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
}
|
||||
.table-recap{width: 200px!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
.address{display: block !important;margin-bottom: 10px !important;}
|
||||
.space_address{display: none !important;}
|
||||
.space_address{display: none !important;}
|
||||
}
|
||||
@media only screen and (min-width: 301px) and (max-width: 500px) {
|
||||
@media only screen and (min-width: 301px) and (max-width: 500px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
.table {width:285px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
}
|
||||
.table-recap{width: 295px !important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
|
||||
|
||||
}
|
||||
@media only screen and (min-width: 501px) and (max-width: 768px) {
|
||||
body {width:478px!important;margin:auto!important;}
|
||||
.table {width:450px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
}
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px;margin:auto!important;}
|
||||
.table {width:450px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
|
||||
}
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
|
||||
.table-recap{width: 295px!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center!important;}
|
||||
.address{display: block !important;margin-bottom: 10px !important;}
|
||||
.space_address{display: none !important;}
|
||||
.space_address{display: none !important;}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -66,38 +66,37 @@
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Hi {firstname} {lastname},</span>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<p data-html-only="1" style="border-bottom:1px solid #D6D4D4;margin:3px 0 7px;text-transform:uppercase;font-weight:500;font-size:18px;padding-bottom:10px">
|
||||
Message from {shop_name} </p>
|
||||
<span style="color:#777">
|
||||
You have received a new message from <span style="color:#333"><strong>{shop_name}</strong></span> regarding order with the reference <span style="color:#333"><strong>{order_name}</strong></span>.<br /><br />
|
||||
<span style="color:#333"><strong>Message:</strong></span> {message}
|
||||
</span>
|
||||
</font>
|
||||
</td>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Hi {firstname} {lastname},</span>
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<p data-html-only="1" style="border-bottom:1px solid #D6D4D4;margin:3px 0 7px;text-transform:uppercase;font-weight:500;font-size:18px;padding-bottom:10px">
|
||||
Message from {shop_name}
|
||||
</p>
|
||||
<span style="color:#777">
|
||||
You have received a new message from <span style="color:#333"><strong>{shop_name}</strong></span> regarding booking with the reference <span style="color:#333"><strong>{order_name}</strong></span>.<br /><br />
|
||||
<span style="color:#333"><strong>Message:</strong></span><br>{message}
|
||||
</span>
|
||||
</font>
|
||||
</td>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
[/{shop_url}]
|
||||
[/{shop_url}]
|
||||
|
||||
Hi {firstname} {lastname},
|
||||
Hi {firstname} {lastname},
|
||||
|
||||
You have received a new message from {shop_name} regarding order with
|
||||
You have received a new message from {shop_name} regarding booking with
|
||||
the reference {order_name}.
|
||||
|
||||
MESSAGE: {message}
|
||||
MESSAGE:
|
||||
{message}
|
||||
|
||||
{shop_name} [/{shop_url}] powered by Webkul(tm)
|
||||
[https://webkul.com]
|
||||
[https://webkul.com]
|
||||
|
||||
|
||||
@@ -4,51 +4,51 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
||||
<title>Message from {shop_name}</title>
|
||||
|
||||
|
||||
<style> @media only screen and (max-width: 300px){
|
||||
|
||||
|
||||
<style> @media only screen and (max-width: 300px){
|
||||
body {
|
||||
width:218px !important;
|
||||
margin:auto !important;
|
||||
}
|
||||
.table {width:195px !important;margin:auto !important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto !important;display: block !important;}
|
||||
span.title{font-size:20px !important;line-height: 23px !important}
|
||||
span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}
|
||||
span.subtitle{font-size: 14px !important;line-height: 18px !important;padding-top:10px !important;display:block !important;}
|
||||
td.box p{font-size: 12px !important;font-weight: bold !important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
}
|
||||
.table-recap{width: 200px!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
.address{display: block !important;margin-bottom: 10px !important;}
|
||||
.space_address{display: none !important;}
|
||||
.space_address{display: none !important;}
|
||||
}
|
||||
@media only screen and (min-width: 301px) and (max-width: 500px) {
|
||||
@media only screen and (min-width: 301px) and (max-width: 500px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
.table {width:285px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
.table-recap table, .table-recap thead, .table-recap tbody, .table-recap th, .table-recap td, .table-recap tr {
|
||||
display: block !important;
|
||||
}
|
||||
.table-recap{width: 295px !important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center !important;}
|
||||
|
||||
|
||||
}
|
||||
@media only screen and (min-width: 501px) and (max-width: 768px) {
|
||||
body {width:478px!important;margin:auto!important;}
|
||||
.table {width:450px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
}
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px;margin:auto!important;}
|
||||
.table {width:450px!important;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
|
||||
}
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body {width:308px!important;margin:auto!important;}
|
||||
.table {width:285px;margin:auto!important;}
|
||||
.logo, .titleblock, .linkbelow, .box, .footer, .space_footer{width:auto!important;display: block!important;}
|
||||
|
||||
.table-recap{width: 295px!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center!important;}
|
||||
.table-recap tr td, .conf_body td{text-align:center!important;}
|
||||
.address{display: block !important;margin-bottom: 10px !important;}
|
||||
.space_address{display: none !important;}
|
||||
.space_address{display: none !important;}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -66,31 +66,34 @@
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">Hi {firstname} {lastname},</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="linkbelow" style="padding:7px 0">
|
||||
<span>{reply}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="linkbelow" style="padding:7px 0">
|
||||
<span>
|
||||
Please do not reply directly to this email, we will not receive it. <br>
|
||||
In order to reply, please use the following link: <a href="{link}" target="_blank" style="color:#337ff1">{link}</a> </span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" class="titleblock" style="padding:7px 0">
|
||||
<span class="title" style="font-weight:500;font-size:28px;text-transform:uppercase;line-height:33px">{headingtext}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="box" style="border:1px solid #D6D4D4;background-color:#f8f8f8;padding:7px 0">
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td width="10" style="padding:7px 0"> </td>
|
||||
<td style="padding:7px 0">
|
||||
<font size="2" face="Open-sans, sans-serif" color="#555454">
|
||||
<p data-html-only="1" style="border-bottom:1px solid #D6D4D4;margin:3px 0 7px;text-transform:uppercase;font-weight:500;font-size:18px;padding-bottom:10px">
|
||||
Message from {contact_name}</p><br/
|
||||
<span><span style="color:#333"><strong>Title:</strong></span> {subject}</span></br><br/>
|
||||
<span><span style="color:#333"><strong>Message:</strong></span> <br/>{reply}</span>
|
||||
<br/><br/>
|
||||
<span>
|
||||
Please do not reply directly to this email, we will not receive it. <br>
|
||||
In order to reply, you can <a href="{link}" target="_blank" style="color:#337ff1">click here</a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
|
||||
[/{shop_url}]
|
||||
[/{shop_url}]
|
||||
|
||||
Hi {firstname} {lastname},
|
||||
{headingtext},
|
||||
|
||||
{reply}
|
||||
Title: {subject}
|
||||
|
||||
Please do not reply directly to this email, we will not receive it.
|
||||
Message:
|
||||
{reply}
|
||||
|
||||
In order to reply, please use the following link: {link} [/{link}]
|
||||
Please do not reply directly to this email, we will not receive it.
|
||||
|
||||
In order to reply, you can click here [/{link}].
|
||||
|
||||
{shop_name} [/{shop_url}] powered by Webkul(tm)
|
||||
[https://webkul.com]
|
||||
[https://webkul.com]
|
||||
|
||||
|
||||
@@ -70,25 +70,56 @@
|
||||
{/if}
|
||||
<div class="col-sm-6 {if !(isset($gblHtlAddress) && $gblHtlAddress) && !(isset($gblHtlPhone) && $gblHtlPhone) && !(isset($gblHtlEmail) && $gblHtlEmail)} col-sm-offset-3 {/if}">
|
||||
{block name='contact_form_content'}
|
||||
{if isset($customerThread.token)}
|
||||
<form action="{$link->getPageLink('contact', null, null, array('token' => $customerThread.token))}" method="post" class="contact-form-box" enctype="multipart/form-data">
|
||||
{else}
|
||||
<form action="{$link->getPageLink('contact')}" method="post" class="contact-form-box" enctype="multipart/form-data">
|
||||
{if isset($customerThread.id_contact) && $customerThread.id_contact && $contacts|count}
|
||||
{assign var=flag value=true}
|
||||
{foreach from=$contacts item=contact}
|
||||
{if $contact.id_contact == $customerThread.id_contact}
|
||||
<input type="text" class="form-control" id="contact_name" name="contact_name" value="{$contact.name|escape:'html':'UTF-8'}" readonly="readonly" />
|
||||
<input type="hidden" name="id_contact" value="{$contact.id_contact|intval}" />
|
||||
{$flag=false}
|
||||
{/if}
|
||||
{if isset($displayContactName) && $displayContactName}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="user_name" class="control-label">
|
||||
{l s='Name'}{if isset($contactNameRequired) && $contactNameRequired}*{/if}
|
||||
</label>
|
||||
<input class="form-control contact_input" type="text" id="user_name" name="user_name" value="{if isset($smarty.post.user_name)}{$smarty.post.user_name}{elseif isset($customerThread.user_name)}{$customerThread.user_name|escape:'html':'UTF-8'}{elseif isset($customerName)}{$customerName}{/if}" {if isset($customerThread.user_name)} readonly{/if}/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="Email" class="control-label">
|
||||
{l s='Email'}*
|
||||
</label>
|
||||
{if isset($customerThread.email)}
|
||||
<input class="form-control contact_input" type="email" id="email" name="from" value="{if isset($customerThread.email)}{$customerThread.email|escape:'html':'UTF-8'}" readonly="readonly"{/if} />
|
||||
{else}
|
||||
<input class="form-control contact_input validate" type="email" id="email" name="from" data-validate="isEmail" value="{if isset($smarty.post.email)}{$smarty.post.email}{else}{$email|escape:'html':'UTF-8'}{/if}" />
|
||||
{/if}
|
||||
{/foreach}
|
||||
{if $flag && isset($contacts.0.id_contact)}
|
||||
<input type="text" class="form-control" id="contact_name" name="contact_name" value="{$contacts.0.name|escape:'html':'UTF-8'}" readonly="readonly" />
|
||||
<input type="hidden" name="id_contact" value="{$contacts.0.id_contact|intval}" />
|
||||
{/if}
|
||||
{else}
|
||||
</div>
|
||||
</div>
|
||||
{if isset($displayContactPhone) && $displayContactPhone}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="phone" class="control-label">
|
||||
{l s='Phone'}{if isset($contactPhoneRequired) && $contactPhoneRequired}*{/if}
|
||||
</label>
|
||||
<input class="form-control contact_input" type="text" id="phone" name="phone" value="{if isset($smarty.post.phone)}{$smarty.post.phone}{else if isset($customerThread.phone)}{$customerThread.phone|escape:'html':'UTF-8'}{elseif isset($customerPhone)}{$customerPhone}{/if}" {if isset($customerThread.phone)}readonly="readonly"{/if}/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="subject" class="control-label">
|
||||
{l s='Title'}*
|
||||
</label>
|
||||
<input class="form-control contact_input" type="text" id="subject" name="subject" value="{if isset($smarty.post.subject)}{$smarty.post.subject}{else if isset($customerThread.subject)}{$customerThread.subject|escape:'html':'UTF-8'}{/if}" {if isset($customerThread.subject)}readonly="readonly"{/if}/>
|
||||
</div>
|
||||
</div>
|
||||
{if !isset($customerThread.id_contact) && isset($allowContactSelection) && $allowContactSelection}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="message" class="control-label">
|
||||
{l s='Subject'}
|
||||
{l s='Send To'}*
|
||||
</label>
|
||||
<div class="dropdown">
|
||||
<button class="form-control contact_type_input" type="button" data-toggle="dropdown">
|
||||
@@ -112,23 +143,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{elseif isset($customerThread.id_contact) && isset($allowContactSelection) && $allowContactSelection}
|
||||
<input type="hidden" id="id_contact" name="id_contact" value="{$customerThread.id_contact|escape:'html':'UTF-8'}"/>
|
||||
{/if}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="price" class="control-label">
|
||||
{l s='Email'}
|
||||
</label>
|
||||
{if isset($customerThread.email)}
|
||||
<input class="form-control contact_input" type="email" id="email" name="from" value="{$customerThread.email|escape:'html':'UTF-8'}" readonly="readonly" />
|
||||
{else}
|
||||
<input class="form-control contact_input validate" type="email" id="email" name="from" data-validate="isEmail" value="{$email|escape:'html':'UTF-8'}" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="message" class="control-label">
|
||||
{l s='Message/Query'}
|
||||
{l s='Message/Query'}*
|
||||
</label>
|
||||
<textarea class="form-control contact_textarea" id="message" name="message">{if isset($message)}{$message|escape:'html':'UTF-8'|stripslashes}{/if}</textarea>
|
||||
</div>
|
||||
@@ -144,6 +165,9 @@
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group">
|
||||
{l s='* Required fields'}
|
||||
</div>
|
||||
{hook h='displayGDPRConsent' moduleName='contactform'}
|
||||
{hook h='displayContactFormFieldsAfter'}
|
||||
<div class="form-group">
|
||||
|
||||
@@ -200,13 +200,13 @@
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
height: 47px;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 5px;
|
||||
padding: 10px;
|
||||
}
|
||||
.contact_textarea {
|
||||
color: #9a9a9a;
|
||||
height: 150px !important;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 5px;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -606,7 +606,7 @@
|
||||
color: #55c65e;
|
||||
}
|
||||
|
||||
#sendOrderMessage {
|
||||
#sendOrderMessage, .select-room-type .card-subheader {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@@ -1121,4 +1121,4 @@
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
/* Guest Tracking page styles - end */
|
||||
/* Guest Tracking page styles - end */
|
||||
|
||||
@@ -596,6 +596,9 @@
|
||||
<form action="{$link->getPageLink('order-detail', true)|escape:'html':'UTF-8'}" method="post" class="std" id="sendOrderMessage">
|
||||
<div class="form-group select-room-type">
|
||||
<label for="id_product">{l s='Room Type'}</label>
|
||||
<p class="card-subheader text-muted">
|
||||
{l s='To add a comment about a room type, please select one first.'}
|
||||
</p>
|
||||
|
||||
<select name="id_product" class="form-control">
|
||||
<option value="0">{l s='-- Choose --'}</option>
|
||||
|
||||
Reference in New Issue
Block a user