Updated the flow of customer message and customer service
This commit is contained in:
@@ -48,7 +48,22 @@
|
||||
@include left(1px)
|
||||
@include box-shadow(white 0 0 0 3px inset)
|
||||
|
||||
.submitReply
|
||||
i[class^="icon-"]
|
||||
display: block
|
||||
width: 30px
|
||||
height: 30px
|
||||
margin: 0 auto
|
||||
font-size: 28px
|
||||
background: transparent
|
||||
background-size: 26px
|
||||
background-position: center
|
||||
|
||||
.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
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<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}
|
||||
{$total_thread}
|
||||
{if $total_thread > 1}{l s='New messages'}{else}{l s='New message'}{/if}
|
||||
</a>
|
||||
{/if}
|
||||
@@ -64,10 +64,10 @@
|
||||
{l s='Meaning of status'}
|
||||
</div>
|
||||
<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>
|
||||
<li><i class="icon-circle text-success"></i> {l s='Open'}</li>
|
||||
<li><i class="icon-circle text-danger"></i> {l s='Closed'}</li>
|
||||
<li><i class="icon-circle text-warning"></i> {l s='Pending 1'}</li>
|
||||
<li><i class="icon-circle text-warning"></i> {l s='Pending 2'}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -78,12 +78,12 @@
|
||||
</div>
|
||||
<ul class="list-unstyled">
|
||||
{assign var=count value=0}
|
||||
{foreach $params as $key => $val}
|
||||
{foreach $stats as $key => $stat}
|
||||
{assign var=count value=$count+1}
|
||||
<li>{$key} <span class="badge">{$val}</span></li>
|
||||
<li>{$stat.title} <span class="badge">{$stat.val}</span></li>
|
||||
{/foreach}
|
||||
</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,11 +30,6 @@
|
||||
<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>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="well">
|
||||
<form action="{$link->getAdminLink('AdminCustomerThreads')|escape:'html':'UTF-8'}&viewcustomer_thread&id_customer_thread={$id_customer_thread|intval}" method="post" enctype="multipart/form-data" class="form-horizontal">
|
||||
@@ -116,7 +111,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="submitReply btn btn-default pull-right" name="submitReply"><i class="icon-mail-reply"></i> {l s="Send"}</button>
|
||||
<button class="submitReply btn btn-default pull-right" name="submitReplyAndClose"><i class="icon-reply-all"></i> {l s='Reply And Close'}</button>
|
||||
<button class="submitReply btn btn-default pull-right" name="submitReplyAsPrivate"><i class="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 +177,3 @@
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
|
||||
|
||||
|
||||
@@ -282,6 +282,10 @@
|
||||
})
|
||||
$('#order_message').live('change', function(e) {
|
||||
e.preventDefault();
|
||||
let visibility = 0;
|
||||
if ($('#visibility').prop('checked')) {
|
||||
visibility = 1;
|
||||
}
|
||||
$.ajax({
|
||||
type:"POST",
|
||||
url: "{$link->getAdminLink('AdminCarts')|addslashes}",
|
||||
@@ -294,8 +298,9 @@
|
||||
action: "updateOrderMessage",
|
||||
id_cart: id_cart,
|
||||
id_customer: id_customer,
|
||||
message: $(this).val()
|
||||
},
|
||||
message: $(this).val(),
|
||||
visibility: visibility
|
||||
},
|
||||
success : function(res)
|
||||
{
|
||||
displaySummary(res);
|
||||
@@ -2170,6 +2175,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,7 +704,7 @@
|
||||
|
||||
{* Order Internal notes *}
|
||||
{if (sizeof($messages))}
|
||||
<div class="panel">
|
||||
<div class="panel order-notes">
|
||||
<div class="panel-heading">
|
||||
<i class="icon-undo"></i> {l s='Order Notes'}
|
||||
</div>
|
||||
@@ -1153,7 +1153,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}
|
||||
|
||||
@@ -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 = true, $limit = false)
|
||||
{
|
||||
return Db::getInstance()->executeS('
|
||||
SELECT cm.*,
|
||||
@@ -91,8 +93,9 @@ class CustomerMessageCore extends ObjectModel
|
||||
WHERE ct.id_order = '.(int)$id_order.'
|
||||
'.(!$private ? 'AND cm.`private` = 0' : '').'
|
||||
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)
|
||||
|
||||
@@ -32,13 +32,20 @@ class CustomerThreadCore extends ObjectModel
|
||||
public $id_contact;
|
||||
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 +55,12 @@ 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_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 +167,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).'\''
|
||||
);
|
||||
}
|
||||
|
||||
@@ -234,7 +266,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)
|
||||
|
||||
@@ -699,7 +699,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();
|
||||
|
||||
@@ -707,7 +707,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');
|
||||
|
||||
@@ -587,6 +587,7 @@ class AdminCartsControllerCore extends AdminController
|
||||
$message->message = $message_content;
|
||||
$message->id_cart = (int)$this->context->cart->id;
|
||||
$message->id_customer = (int)$this->context->cart->id_customer;
|
||||
$message->private = !Tools::getValue('visibility');
|
||||
$message->save();
|
||||
}
|
||||
} elseif (Validate::isLoadedObject($message)) {
|
||||
@@ -598,7 +599,7 @@ class AdminCartsControllerCore extends AdminController
|
||||
|
||||
public function ajaxProcessUpdateCurrency()
|
||||
{
|
||||
if ($this->tabAccess['edit'] === '1') {
|
||||
if ($this->tabAccess['edit'] === '1' || $this->tabAccess['add'] === '1') {
|
||||
$currency = new Currency((int)Tools::getValue('id_currency'));
|
||||
if (Validate::isLoadedObject($currency) && !$currency->deleted && $currency->active) {
|
||||
$this->context->cart->id_currency = (int)$currency->id;
|
||||
|
||||
@@ -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,12 +93,19 @@ 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'),
|
||||
'type' => 'select',
|
||||
@@ -92,12 +113,21 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'filter_key' => 'cl!id_contact',
|
||||
'filter_type' => 'int',
|
||||
),
|
||||
'subject' => array(
|
||||
'title' => $this->l('Subject'),
|
||||
'filter_key' => 'a!subject',
|
||||
'tmpTableFilter' => true,
|
||||
'maxlength' => 40,
|
||||
'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'),
|
||||
@@ -118,9 +148,10 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'filter_key' => 'messages',
|
||||
'tmpTableFilter' => true,
|
||||
'maxlength' => 40,
|
||||
'optional' => true,
|
||||
),
|
||||
'private' => array(
|
||||
'title' => $this->l('Private'),
|
||||
'title' => $this->l('Has Private'),
|
||||
'type' => 'select',
|
||||
'filter_key' => 'private',
|
||||
'align' => 'center',
|
||||
@@ -135,6 +166,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'title' => $this->l('Last message'),
|
||||
'havingFilter' => true,
|
||||
'type' => 'datetime',
|
||||
'optional' => true,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -147,22 +179,61 @@ 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('Allow file uploading'),
|
||||
'hint' => $this->l('Allow customers to upload files using the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
'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
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_CONTACT_ALLOW' => array(
|
||||
'title' => $this->l('Allow guest to select contact'),
|
||||
'hint' => $this->l('Allow guest to select the contact while submitting message from the contact page.'),
|
||||
'type' => 'bool'
|
||||
),
|
||||
'PS_CUSTOMER_SERVICE_EMAIL_MESSAGE' => array(
|
||||
'title' => $this->l('Send email 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_NAME_REQUIRED' => 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_PHONE_REQUIRED' => 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_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
|
||||
)
|
||||
),
|
||||
'submit' => array(
|
||||
'title' => $this->l('Save'),
|
||||
@@ -242,6 +313,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 +343,7 @@ 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,
|
||||
(
|
||||
SELECT IFNULL(CONCAT(LEFT(e.`firstname`, 1),". ",e.`lastname`), "--")
|
||||
FROM `'._DB_PREFIX_.'customer_message` cm2
|
||||
@@ -274,10 +364,6 @@ 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';
|
||||
@@ -286,19 +372,42 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
|
||||
$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)
|
||||
$stats = array(
|
||||
array(
|
||||
'title' => $this->l('Total threads'),
|
||||
'val' => $all = CustomerThread::getTotalCustomerThreads(),
|
||||
),
|
||||
array(
|
||||
'title' => $this->l('Threads pending'),
|
||||
'val' => $pending = CustomerThread::getTotalCustomerThreads(
|
||||
'status='.(int) CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING1.'
|
||||
OR status='.(int) CustomerThread::QLO_CUSTOMER_THREAD_STATUS_PENDING2
|
||||
),
|
||||
),
|
||||
array(
|
||||
'title' => $this->l('Total number of customer messages'),
|
||||
'val' => CustomerMessage::getTotalCustomerMessages('id_employee = 0'),
|
||||
),
|
||||
array(
|
||||
'title' => $this->l('Total number of employee messages'),
|
||||
'val' => CustomerMessage::getTotalCustomerMessages('id_employee != 0'),
|
||||
),
|
||||
array(
|
||||
'title' => $this->l('Unread threads'),
|
||||
'val' => $unread = CustomerThread::getTotalCustomerThreads(
|
||||
'status='.CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN
|
||||
),
|
||||
),
|
||||
array(
|
||||
'title' => $this->l('Closed threads'),
|
||||
'val' => $all - ($unread + $pending),
|
||||
),
|
||||
);
|
||||
|
||||
$this->tpl_list_vars = array(
|
||||
'contacts' => $contacts,
|
||||
'categories' => $categories,
|
||||
'params' => $params
|
||||
'stats' => $stats
|
||||
);
|
||||
|
||||
return parent::renderList();
|
||||
@@ -342,10 +451,9 @@ 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
|
||||
');
|
||||
}
|
||||
@@ -363,7 +471,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.date_add, cm.id_employee, cm.private DESC
|
||||
');
|
||||
$output = $this->displayMessage($messages, true, (int)Tools::getValue('id_employee_forward'));
|
||||
$cm = new CustomerMessage();
|
||||
@@ -395,7 +503,8 @@ 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)
|
||||
) {
|
||||
$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,7 +533,7 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$this->errors[] = '<div class="alert error">'.Tools::displayError('The email address is invalid.').'</div>';
|
||||
}
|
||||
}
|
||||
if (Tools::isSubmit('submitReply')) {
|
||||
if (Tools::isSubmit('submitReply') || Tools::isSubmit('submitReplyAndClose')) {
|
||||
$ct = new CustomerThread($id_customer_thread);
|
||||
|
||||
ShopUrl::cacheMainDomainForShop((int)$ct->id_shop);
|
||||
@@ -446,14 +555,26 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
$file_attachment['mime'] = $_FILES['joinFile']['type'];
|
||||
}
|
||||
$customer = new Customer($ct->id_customer);
|
||||
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
|
||||
);
|
||||
} 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');
|
||||
if ($customer->id) {
|
||||
$headingText .= ' '.$customer->firstname.' '.$customer->lastname;
|
||||
}
|
||||
$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
|
||||
'{link}' => $link,
|
||||
'{headingtext}' => $headingText
|
||||
);
|
||||
//#ct == id_customer_thread #tc == token of thread <== used in the synchronization imap
|
||||
$contact = new Contact((int)$ct->id_contact, (int)$ct->id_lang);
|
||||
@@ -471,8 +592,12 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
||||
'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';
|
||||
_PS_MAIL_DIR_, true, $ct->id_shop)
|
||||
) {
|
||||
if (Tools::isSubmit('submitReplyAndClose')) {
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_CLOSED;
|
||||
}
|
||||
|
||||
$ct->update();
|
||||
}
|
||||
Tools::redirectAdmin(
|
||||
@@ -481,7 +606,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')) {
|
||||
$ct = new CustomerThread($id_customer_thread);
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return parent::postProcess();
|
||||
@@ -603,64 +745,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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -710,7 +842,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 +852,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 +864,15 @@ 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/>';
|
||||
if ($message['id_employee']) {
|
||||
$content .= $this->l('Message to: ').' <span class="badge">'.($message['customer_name']).'</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']);
|
||||
|
||||
@@ -1079,7 +1211,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',
|
||||
|
||||
@@ -1424,7 +1424,7 @@ class AdminOrdersControllerCore extends AdminController
|
||||
$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 {
|
||||
@@ -3036,6 +3036,13 @@ class AdminOrdersControllerCore extends AdminController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$objCustomerThread = new CustomerThread();
|
||||
$messages = Message::getMessagesByOrderId($order->id, true);
|
||||
if ($customerMessages = CustomerMessage::getMessagesByOrderId($order->id, true)) {
|
||||
$messages = array_merge($messages, $customerMessages);
|
||||
}
|
||||
|
||||
$this->tpl_view_vars = array(
|
||||
'guestFormattedAddress' => $guestFormattedAddress,
|
||||
'idOrderAddressInvoice' => $idOrderAddressInvoice,
|
||||
@@ -3080,8 +3087,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,
|
||||
|
||||
@@ -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_NAME_REQUIRED');
|
||||
$phoneRequired = Configuration::get('PS_CUSTOMER_SERVICE_PHONE_REQUIRED');
|
||||
if (!Configuration::get('PS_CUSTOMER_SERVICE_CONTACT_ALLOW')) {
|
||||
$id_contact = (int) Configuration::get('PS_CUSTOMER_SERVICE_EMAIL_MESSAGE');
|
||||
}
|
||||
|
||||
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 subject 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 select a subject from the list provided.');
|
||||
} 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,13 +118,10 @@ class ContactControllerCore extends FrontController
|
||||
if ($contact->customer_service) {
|
||||
if ((int)$id_customer_thread) {
|
||||
$ct = new CustomerThread($id_customer_thread);
|
||||
$ct->status = 'open';
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_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();
|
||||
@@ -137,14 +129,13 @@ class ContactControllerCore extends FrontController
|
||||
$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->phone = $phone;
|
||||
$ct->user_name = $userName;
|
||||
$ct->subject = $subject;
|
||||
$ct->id_contact = (int)$id_contact;
|
||||
$ct->id_lang = (int)$this->context->language->id;
|
||||
$ct->email = $from;
|
||||
$ct->status = 'open';
|
||||
$ct->status = CustomerThread::QLO_CUSTOMER_THREAD_STATUS_OPEN;
|
||||
$ct->token = Tools::passwdGen(12);
|
||||
$ct->add();
|
||||
}
|
||||
@@ -153,6 +144,9 @@ class ContactControllerCore extends FrontController
|
||||
$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);
|
||||
@@ -266,21 +260,21 @@ class ContactControllerCore extends FrontController
|
||||
'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);
|
||||
}
|
||||
|
||||
// Send Hotel location information
|
||||
$gblHtlAddress = Configuration::get('WK_HOTEL_GLOBAL_ADDRESS');
|
||||
$gblHtlPhone = Configuration::get('WK_HOTEL_GLOBAL_CONTACT_NUMBER');
|
||||
@@ -320,6 +314,9 @@ 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_NAME_REQUIRED'),
|
||||
'contactPhoneRequired' => Configuration::get('PS_CUSTOMER_SERVICE_PHONE_REQUIRED'),
|
||||
'allowContactSelection' => Configuration::get('PS_CUSTOMER_SERVICE_CONTACT_ALLOW')
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -695,21 +695,23 @@ class OrderDetailControllerCore extends FrontController
|
||||
$ct->id_contact = 0;
|
||||
$ct->id_customer = (int)$order->id_customer;
|
||||
$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']);
|
||||
@@ -819,4 +821,4 @@ class OrderDetailControllerCore extends FrontController
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,6 +633,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,8 +659,10 @@ CREATE TABLE `PREFIX_customer_thread` (
|
||||
`id_contact` int(10) unsigned NOT NULL,
|
||||
`id_customer` 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,
|
||||
|
||||
@@ -946,6 +946,15 @@
|
||||
</configuration>
|
||||
<configuration id="PS_BACKDATE_ORDER_EMPLOYEES" name="PS_BACKDATE_ORDER_EMPLOYEES">
|
||||
<value>0</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_NAME_REQUIRED" name="PS_CUSTOMER_SERVICE_NAME_REQUIRED">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_PHONE_REQUIRED" name="PS_CUSTOMER_SERVICE_PHONE_REQUIRED">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
<configuration id="PS_CUSTOMER_SERVICE_CONTACT_ALLOW" name="PS_CUSTOMER_SERVICE_CONTACT_ALLOW">
|
||||
<value>1</value>
|
||||
</configuration>
|
||||
</entities>
|
||||
</entity_configuration>
|
||||
|
||||
32
js/admin/customer_thread.js
Normal file
32
js/admin/customer_thread.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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_CONTACT_ALLOW_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_EMAIL_MESSAGE"]').closest('.form-group').hide();
|
||||
}
|
||||
|
||||
$(document).on('change', '[name="PS_CUSTOMER_SERVICE_CONTACT_ALLOW"]', function() {
|
||||
if ($('#PS_CUSTOMER_SERVICE_CONTACT_ALLOW_on').prop('checked')) {
|
||||
$('[name="PS_CUSTOMER_SERVICE_EMAIL_MESSAGE"]').closest('.form-group').hide();
|
||||
} else {
|
||||
$('[name="PS_CUSTOMER_SERVICE_EMAIL_MESSAGE"]').closest('.form-group').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -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,29 @@
|
||||
</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="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, you can <a href="{link}" target="_blank" style="color:#337ff1">click here</a></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="space_footer" style="padding:0!important"> </td>
|
||||
</tr>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
[/{shop_url}]
|
||||
[/{shop_url}]
|
||||
|
||||
Hi {firstname} {lastname},
|
||||
{headingtext},
|
||||
|
||||
{reply}
|
||||
{reply}
|
||||
|
||||
Please do not reply directly to this email, we will not receive it.
|
||||
Please do not reply directly to this email, we will not receive it.
|
||||
|
||||
In order to reply, please use the following link: {link} [/{link}]
|
||||
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($customerThread.id_contact)}
|
||||
<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($customerThread.user_name)}{$customerThread.user_name|escape:'html':'UTF-8'}{/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="{$email|escape:'html':'UTF-8'}" />
|
||||
{/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($customerThread.id_contact)}
|
||||
<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($customerThread.phone)}{$customerThread.phone|escape:'html':'UTF-8'}{/if}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<label for="subject" class="control-label">
|
||||
{l s='Subject'}*
|
||||
</label>
|
||||
<input class="form-control contact_input" type="text" id="subject" name="subject" value="{if isset($customerThread.name)}{$customerThread.name|escape:'html':'UTF-8'}{/if}"/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{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,27 +143,20 @@
|
||||
</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>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{l s='* Required fields'}
|
||||
</div>
|
||||
{if $fileupload == 1}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -528,6 +528,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