Customer service - add predefined messages



  • Hi all,

    well I went ahead and did it myself. Here are the steps in order to add predefined messages in the customer service section. I hope that it will be useful for someone.

    ** Sorry about the french screenshots and strings, I am running a french site so it is what it is 😀 **

    1. You will have to duplicate the 2 database tables used by the orders predefined messages option. They are “xx_order_message” and “xx_order_message_lang”. Duplicate the structure only and rename them to “xx_client_message” and “xx_client_message_lang”.

    In both new tables, change the first column name to “id_client_message”.

    0_1522160311886_Capture d’écran 2018-03-27 à 10.13.40.png

    0_1522160321902_Capture d’écran 2018-03-27 à 10.16.30.png

    1. In the override section, create AdminClientMessageController.php and add the following code.
      0_1522160530797_Capture d’écran 2018-03-27 à 10.20.30.png
    <?php
    /**
     * 2007-2016 PrestaShop
     *
     * Thirty Bees is an extension to the PrestaShop e-commerce software developed by PrestaShop SA
     * Copyright (C) 2017 Thirty Bees
     *
     * NOTICE OF LICENSE
     *
     * This source file is subject to the Open Software License (OSL 3.0)
     * that is bundled with this package in the file LICENSE.txt.
     * It is also available through the world-wide-web at this URL:
     * http://opensource.org/licenses/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 license@thirtybees.com so we can send you a copy immediately.
     *
     * DISCLAIMER
     *
     * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
     * versions in the future. If you wish to customize PrestaShop for your
     * needs please refer to https://www.thirtybees.com for more information.
     *
     * @author    Thirty Bees <contact@thirtybees.com>
     * @author    PrestaShop SA <contact@prestashop.com>
     * @copyright 2017 Thirty Bees
     * @copyright 2007-2016 PrestaShop SA
     * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     *  PrestaShop is an internationally registered trademark & property of PrestaShop SA
     */
    
    /**
     * Class AdminClientMessageControllerCore
     *
     * @since 1.0.0
     */
    class AdminClientMessageControllerCore extends AdminController
    {
        /**
         * AdminClintMessageControllerCore constructor.
         *
         * @since 1.0.0
         */
        public function __construct()
        {
            $this->bootstrap = true;
            $this->table = 'client_message';
            $this->className = 'ClientMessage';
            $this->lang = true;
    
            $this->addRowAction('edit');
            $this->addRowAction('delete');
    
            $this->context = Context::getContext();
    
            if (!Tools::getValue('realedit')) {
                $this->deleted = false;
            }
    
            $this->bulk_actions = [
                'delete' => [
                    'text'    => $this->l('Delete selected'),
                    'confirm' => $this->l('Delete selected items?'),
                    'icon'    => 'icon-trash',
                ],
            ];
    
            $this->fields_list = [
                'id_client_message' => [
                    'title' => $this->l('ID'),
                    'align' => 'center',
                ],
                'name'             => [
                    'title' => $this->l('Name'),
                ],
                'message'          => [
                    'title'     => $this->l('Message'),
                    'maxlength' => 300,
                ],
            ];
    
            $this->fields_form = [
                'legend' => [
                    'title' => $this->l('Client messages'),
                    'icon'  => 'icon-mail',
                ],
                'input'  => [
                    [
                        'type'     => 'text',
                        'lang'     => true,
                        'label'    => $this->l('Name'),
                        'name'     => 'name',
                        'size'     => 53,
                        'required' => true,
                    ],
                    [
                        'type'     => 'textarea',
                        'lang'     => true,
                        'label'    => $this->l('Message'),
                        'name'     => 'message',
                        'required' => true,
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ];
    
            parent::__construct();
        }
    
        /**
         * Initialize page header toolbar
         *
         * @return void
         *
         * @since 1.0.0
         */
        public function initPageHeaderToolbar()
        {
            if (empty($this->display)) {
                $this->page_header_toolbar_btn['new_client_message'] = [
                    'href' => static::$currentIndex.'&addclient_message&token='.$this->token,
                    'desc' => $this->l('Ajouter un nouveau message client'),
                    'icon' => 'process-icon-new',
                ];
            }
    
            parent::initPageHeaderToolbar();
        }
    }
    
    1. In override, create ClientMessage.php and paste the following code inside.
      0_1522160734336_Capture d’écran 2018-03-27 à 10.24.38.png
    /**
     * 2007-2016 PrestaShop
     *
     * Thirty Bees is an extension to the PrestaShop e-commerce software developed by PrestaShop SA
     * Copyright (C) 2017 Thirty Bees
     *
     * NOTICE OF LICENSE
     *
     * This source file is subject to the Open Software License (OSL 3.0)
     * that is bundled with this package in the file LICENSE.txt.
     * It is also available through the world-wide-web at this URL:
     * http://opensource.org/licenses/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 license@thirtybees.com so we can send you a copy immediately.
     *
     * DISCLAIMER
     *
     * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
     * versions in the future. If you wish to customize PrestaShop for your
     * needs please refer to https://www.thirtybees.com for more information.
     *
     *  @author    Thirty Bees <contact@thirtybees.com>
     *  @author    PrestaShop SA <contact@prestashop.com>
     *  @copyright 2017 Thirty Bees
     *  @copyright 2007-2016 PrestaShop SA
     *  @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     *  PrestaShop is an internationally registered trademark & property of PrestaShop SA
     */
    
    /**
     * Class ClientMessageCore
     *
     * @since 1.0.0
     */
    class ClientMessageCore extends ObjectModel
    {
        // @codingStandardsIgnoreStart
        /** @var string name name */
        public $name;
    
        /** @var string message content */
        public $message;
    
        /** @var string Object creation date */
        public $date_add;
        // @codingStandardsIgnoreEnd
    
        /**
         * @see ObjectModel::$definition
         */
        public static $definition = [
            'table'     => 'client_message',
            'primary'   => 'id_client_message',
            'multilang' => true,
            'fields'    => [
                'date_add' => ['type' => self::TYPE_DATE,                   'validate' => 'isDate'                                           ],
                'name'     => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128 ],
                'message'  => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isMessage',     'required' => true, 'size' => 1200],
            ],
        ];
    
        protected $webserviceParameters = [
            'fields' => [
                'id'       => ['sqlId' => 'id_discount_type', 'xlink_resource' => 'client_message_lang'],
                'date_add' => ['sqlId' => 'date_add'],
            ],
        ];
    
        /**
         * @param $idLang
         *
         * @return array|false|mysqli_result|null|PDOStatement|resource
         *
         * @since 1.0.0
         * @version 1.0.0 Initial version
         */
        public static function getClientMessages($idLang)
        {
            return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
    		SELECT om.id_client_message, oml.name, oml.message
    		FROM '._DB_PREFIX_.'client_message om
    		LEFT JOIN '._DB_PREFIX_.'client_message_lang oml ON (oml.id_client_message = om.id_client_message)
    		WHERE oml.id_lang = '.(int) $idLang.'
    		ORDER BY name ASC');
        }
    }
    
    
    1. Next you will have to override AdminCustomerThreadsController.php in order to add the messages list to the template. Do it and add the following code into it.
      0_1522161051645_Capture d’écran 2018-03-27 à 10.30.16.png
    <?php
    /**
     * 2007-2016 PrestaShop
     *
     * Thirty Bees is an extension to the PrestaShop e-commerce software developed by PrestaShop SA
     * Copyright (C) 2017 Thirty Bees
     *
     * NOTICE OF LICENSE
     *
     * This source file is subject to the Open Software License (OSL 3.0)
     * that is bundled with this package in the file LICENSE.txt.
     * It is also available through the world-wide-web at this URL:
     * http://opensource.org/licenses/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 license@thirtybees.com so we can send you a copy immediately.
     *
     * DISCLAIMER
     *
     * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
     * versions in the future. If you wish to customize PrestaShop for your
     * needs please refer to https://www.thirtybees.com for more information.
     *
     * @author    Thirty Bees <contact@thirtybees.com>
     * @author    PrestaShop SA <contact@prestashop.com>
     * @copyright 2017 Thirty Bees
     * @copyright 2007-2016 PrestaShop SA
     * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     *  PrestaShop is an internationally registered trademark & property of PrestaShop SA
     */
    
    /**
     * Class AdminCustomerThreadsControllerCore
     *
     * @since 1.0.0
     */
    class AdminCustomerThreadsController extends AdminCustomerThreadsControllerCore
    {
        /**
         * Render view
         *
         * @return string
         *
         * @since 1.0.0
         */
        public function renderView()
        {
            if (!$idCustomerThread = (int) Tools::getValue('id_customer_thread')) {
                return '';
            }
    
            $this->context = Context::getContext();
            if (!($thread = $this->loadObject())) {
                return '';
            }
            $this->context->cookie->{'customer_threadFilter_cl!id_contact'} = $thread->id_contact;
    
            $employees = Employee::getEmployees();
    
            $messages = CustomerThread::getMessageCustomerThreads($idCustomerThread);
    
            foreach ($messages as $key => $mess) {
                if ($mess['id_employee']) {
                    $employee = new Employee($mess['id_employee']);
                    $messages[$key]['employee_image'] = $employee->getImage();
                }
                if (isset($mess['file_name']) && $mess['file_name'] != '') {
                    $messages[$key]['file_name'] = _THEME_PROD_PIC_DIR_.$mess['file_name'];
                } else {
                    unset($messages[$key]['file_name']);
                }
    
                if ($mess['id_product']) {
                    $product = new Product((int) $mess['id_product'], false, $this->context->language->id);
                    if (Validate::isLoadedObject($product)) {
                        $messages[$key]['product_name'] = $product->name;
                        $messages[$key]['product_link'] = $this->context->link->getAdminLink('AdminProducts').'&updateproduct&id_product='.(int) $product->id;
                    }
                }
            }
    
            $nextThread = CustomerThread::getNextThread((int) $thread->id);
    
            $contacts = Contact::getContacts($this->context->language->id);
    
            $actions = [];
    
            if ($nextThread) {
                $nextThread = [
                    'href' => static::$currentIndex.'&id_customer_thread='.(int) $nextThread.'&viewcustomer_thread&token='.$this->token,
                    'name' => $this->l('Reply to the next unanswered message in this thread'),
                ];
            }
    
            if ($thread->status != 'closed') {
                $actions['closed'] = [
                    'href'  => static::$currentIndex.'&viewcustomer_thread&setstatus=2&id_customer_thread='.(int) Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
                    'label' => $this->l('Mark as "handled"'),
                    'name'  => 'setstatus',
                    'value' => 2,
                ];
            } else {
                $actions['open'] = [
                    'href'  => static::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.(int) Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
                    'label' => $this->l('Re-open'),
                    'name'  => 'setstatus',
                    'value' => 1,
                ];
            }
    
            if ($thread->status != 'pending1') {
                $actions['pending1'] = [
                    'href'  => static::$currentIndex.'&viewcustomer_thread&setstatus=3&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,
                ];
            } else {
                $actions['pending1'] = [
                    'href'  => static::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.(int) Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
                    'label' => $this->l('Disable pending status'),
                    'name'  => 'setstatus',
                    'value' => 1,
                ];
            }
    
            if ($thread->status != 'pending2') {
                $actions['pending2'] = [
                    'href'  => static::$currentIndex.'&viewcustomer_thread&setstatus=4&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,
                ];
            } else {
                $actions['pending2'] = [
                    'href'  => static::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.(int) Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
                    'label' => $this->l('Disable pending status'),
                    'name'  => 'setstatus',
                    'value' => 1,
                ];
            }
    
            if ($thread->id_customer) {
                $customer = new Customer($thread->id_customer);
                $orders = Order::getCustomerOrders($customer->id);
                if ($orders && count($orders)) {
                    $totalOk = 0;
                    $ordersOk = [];
                    foreach ($orders as $key => $order) {
                        if ($order['valid']) {
                            $ordersOk[] = $order;
                            $totalOk += $order['total_paid_real'] / $order['conversion_rate'];
                        }
                        $orders[$key]['date_add'] = Tools::displayDate($order['date_add']);
                        $orders[$key]['total_paid_real'] = Tools::displayPrice($order['total_paid_real'], new Currency((int) $order['id_currency']));
                    }
                }
    
                $products = $customer->getBoughtProducts();
                if ($products && count($products)) {
                    foreach ($products as $key => $product) {
                        $products[$key]['date_add'] = Tools::displayDate($product['date_add'], null, true);
                    }
                }
            }
            $timelineItems = $this->getTimeline($messages, $thread->id_order);
            $firstMessage = $messages[0];
    
            if (!$messages[0]['id_employee']) {
                unset($messages[0]);
            }
    
            $contact = '';
            foreach ($contacts as $c) {
                if ($c['id_contact'] == $thread->id_contact) {
                    $contact = $c['name'];
                }
            }
    
            $this->tpl_view_vars = [
                'id_customer_thread'            => $idCustomerThread,
                'thread'                        => $thread,
                'actions'                       => $actions,
                'employees'                     => $employees,
                'current_employee'              => $this->context->employee,
                'messages'                      => $messages,
                'first_message'                 => $firstMessage,
                'contact'                       => $contact,
                'next_thread'                   => $nextThread,
                'orders'                        => isset($orders) ? $orders : false,
                'customer'                      => isset($customer) ? $customer : false,
                'products'                      => isset($products) ? $products : false,
                'total_ok'                      => isset($totalOk) ? Tools::displayPrice($totalOk, $this->context->currency) : false,
                'orders_ok'                     => isset($ordersOk) ? $ordersOk : false,
                'count_ok'                      => isset($ordersOk) ? count($ordersOk) : false,
                'PS_CUSTOMER_SERVICE_SIGNATURE' => str_replace('\r\n', "\n", Configuration::get('PS_CUSTOMER_SERVICE_SIGNATURE', (int) $thread->id_lang)),
                'timeline_items'                => $timelineItems,
            	'clientMessages'                => ClientMessage::getClientMessages($thread->id_lang),
            ];
    
            if ($nextThread) {
                $this->tpl_view_vars['next_thread'] = $nextThread;
            }
    
            return AdminController::renderView();
        }
    }
    
    1. And finally, you will have to override the helper view.tpl with the following code.
      0_1522161190650_Capture d’écran 2018-03-27 à 10.32.27.png
    {*
    * 2007-2016 PrestaShop
    *
    * NOTICE OF LICENSE
    *
    * This source file is subject to the Academic Free License (AFL 3.0)
    * that is bundled with this package in the file LICENSE.txt.
    * It is also available through the world-wide-web at this URL:
    * http://opensource.org/licenses/afl-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 license@prestashop.com so we can send you a copy immediately.
    *
    * DISCLAIMER
    *
    * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
    * versions in the future. If you wish to customize PrestaShop for your
    * needs please refer to http://www.prestashop.com for more information.
    *
    *  @author PrestaShop SA <contact@prestashop.com>
    *  @copyright  2007-2016 PrestaShop SA
    *  @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
    *  International Registered Trademark & Property of PrestaShop SA
    *}
    
    {extends file="helpers/view/view.tpl"}
    {block name="override_tpl"}
    {include file="controllers/customer_threads/helpers/view/modal.tpl" }
    <div class="panel">
    	<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'}&amp;viewcustomer_thread&amp;id_customer_thread={$id_customer_thread|intval}" method="post" enctype="multipart/form-data" class="form-horizontal">
    			{foreach $actions as $action}
    				<button class="btn btn-default" name="{$action.name|escape:'html':'UTF-8'}" value="{$action.value|intval}">
    					{if isset($action.icon)}<i class="{$action.icon|escape:'html':'UTF-8'}"></i>{/if}{$action.label}
    				</button>
    			{/foreach}
    			<button class="btn btn-default" type="button" data-toggle="modal" data-target="#myModal">
    				{l s="Forward this discussion to another employee"}
    			</button>
    		</form>
    	</div>
    	<div class="row">
    		<div class="message-item-initial media">
    			<a href="{if isset($customer->id)}{$link->getAdminLink('AdminCustomers')|escape:'html':'UTF-8'}&amp;id_customer={$customer->id|intval}&amp;viewcustomer&{else}#{/if}" class="avatar-lg pull-left"><i class="icon-user icon-3x"></i></a>
    			<div class="media-body">
    				<div class="row">
    					<div class="col-sm-6">
    					{if isset($customer->firstname)}
    						<h2>
    							<a href="{$link->getAdminLink('AdminCustomers')|escape:'html':'UTF-8'}&amp;id_customer={$customer->id|intval}&amp;viewcustomer&">
    							{$customer->firstname|escape:'html':'UTF-8'} {$customer->lastname|escape:'html':'UTF-8'} <small>({$customer->email|escape:'html':'UTF-8'})</small>
    							</a>
    						</h2>
    					{else}
    						<h2>{$thread->email|escape:'html':'UTF-8'}</h2>
    					{/if}
    					{if isset($contact) && trim($contact) != ''}
    						<span>{l s="To:"} </span><span class="badge">{$contact|escape:'html':'UTF-8'}</span>
    					{/if}
    					</div>
    					{if isset($customer->firstname)}
    						<div class="col-sm-6">
    							<p>
    							{if $count_ok}
    								{l s='[1]%1$d[/1] order(s) validated for a total amount of [2]%2$s[/2]' sprintf=[$count_ok, $total_ok] tags=['<span class="badge">', '<span class="badge badge-success">']}
    							{else}
    								{l s="No orders validated for the moment"}
    							{/if}
    							</p>
    							<p class="text-muted">{l s="Customer since: %s" sprintf=[{dateFormat date=$customer->date_add full=0}]}</p>
    						</div>
    					{/if}
    				</div>
    				<div class="row">
    					<div class="col-sm-12">
    						{if !$first_message.id_employee}
    							{include file="controllers/customer_threads/helpers/view/message.tpl" message=$first_message initial=true}
    						{/if}
    					</div>
    				</div>
    			</div>
    		</div>
    	</div>
    	<div class="row">
    		{foreach $messages as $message}
    			{include file="controllers/customer_threads/helpers/view/message.tpl" message=$message initial=false}
    		{/foreach}
    	</div>
    </div>
    <div class="panel">
    	<form action="{$link->getAdminLink('AdminCustomerThreads')|escape:'html':'UTF-8'}&amp;id_customer_thread={$thread->id|intval}&amp;viewcustomer_thread" method="post" enctype="multipart/form-data" class="form-horizontal">
    	<h3>{l s="Your answer to"} {if isset($customer->firstname)}{$customer->firstname|escape:'html':'UTF-8'} {$customer->lastname|escape:'html':'UTF-8'} {else} {$thread->email}{/if}</h3>
    	
    	<div class="row">
    		<div class="media">
    			<div class="pull-left">
    				<span class="avatar-md">{if isset($current_employee->firstname)}<img src="{$current_employee->getImage()}" alt="">{/if}</span>
    			</div>
    			<div class="media-body">
    				<textarea id="txt_msg" class="textarea-autosize" cols="30" rows="7" name="reply_message">{$PS_CUSTOMER_SERVICE_SIGNATURE|escape:'html':'UTF-8'}</textarea>
    			</div>
    		</div>
    	</div>
    	<div id="messages" class="row" style="margin-top: 5px;">
              <div id="message" class="form-horizontal">
                  <div class="form-group">
                    <label class="control-label pull-left">{l s='Messages prédéfinis'}</label>
                    <div class="">
                      <select width="100%" class="chosen form-control" name="client_message" id="client_message" onchange="orderOverwriteMessage(this, '{l s='Voulez-vous remplacer votre message actuel ?'}')">
                        <option value="0" selected="selected">-</option>
                        {foreach from=$clientMessages item=clientMessage}
                          <option value="{$clientMessage['message']|escape:'html':'UTF-8'}">{$clientMessage['name']}</option>
                        {/foreach}
                      </select>
                      <p class="help-block">
                        <a href="{$link->getAdminLink('AdminClientMessage')|escape:'html':'UTF-8'}">
                          {l s='Configurer les messages prédéfinis'}
                          <i class="icon-external-link"></i>
                        </a>
                      </p>
                    </div>
                  </div>
                </div>
            </div>
    	<div class="panel-footer">
    		<!--
    		<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
    			<i class="icon-magic icon-2x"></i><br>
    			{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>
    		<input type="hidden" name="id_customer_thread" value="{$thread->id|intval}" />
    		<input type="hidden" name="msg_email" value="{$thread->email}" />
    	</div>
    	</form>
    </div>
    
    {if count($timeline_items)}
    <div class="panel">
    	<h3>
    		<i class="icon-clock-o"></i>
    		{l s="Orders and messages timeline"}
    	</h3>
    	<div class="timeline">
    		{foreach $timeline_items as $dates}
    			{foreach from=$dates key=date item=timeline_item}
    				{include file="controllers/customer_threads/helpers/view/timeline_item.tpl" timeline_item=$timeline_item}
    			{/foreach}
    		{/foreach}
    	</div>
    </div>
    {/if}
    <script type="text/javascript">
    	var timer;
    		$(document).ready(function(){
    			$('select[name=id_employee_forward]').change(function(){
    				if ($(this).val() >= 0)
    					$('#message_forward').show(400);
    				else
    					$('#message_forward').hide(200);
    				if ($(this).val() == 0)
    					$('#message_forward_email').show(200);
    				else
    					$('#message_forward_email').hide(200);
    			});
    			$('textarea[name=message_forward]').click(function(){
    				if($(this).val() == '{l s='You can add a comment here.'}')
    				{
    					$(this).val('');
    				}
    			});
    			timer = setInterval("markAsRead()", 3000);
    		});
    	
    	function markAsRead()
    	{
    		$.ajax({
    			type: 'POST',
    			url: 'ajax-tab.php',
    			async: true,
    			dataType: 'json',
    			data: {
    				controller: 'AdminCustomerThreads',
    				action: 'markAsRead',
    				token : '{$token|escape:'html':'UTF-8'}',
    				id_thread: {$id_customer_thread}
    			}
    		});
    		clearInterval(timer);
    		timer = null;
    	}
    </script>
    
    {/block}
    
    
    

    @@@@@ Code is complete, don’t forget to delete class_index.php in your cache folder before running it.

    Your customer service reply page should now look like this:
    0_1522161552204_Capture d’écran 2018-03-27 à 10.36.01.png

    To add the management link to the clients menu, just go to administration-menus and add an item like this:
    0_1522161617283_Capture d’écran 2018-03-27 à 10.36.58.png

    ----> One last important thing, you may notice that the drop-down length is fine at first but does not scale if you resize your window. There is a bug in the chosen implementation (you will notice the same problem in the orders section). To fix it, you will have to edit js/admin.js and add the width parameter and set it to 100%.
    0_1522161931317_Capture d’écran 2018-03-27 à 10.43.43.png

    You should now be able to add as many predefined replies as you wish.

    Hopefully I did not forget anything but feel free to post if you have problems and I will do my best to help you out.

    Cheers !



  • WOW!! If this is not against TB code standards and is not breaking anything, how about to include in the core?! how about PR on GitHub?



  • Cool stuff! Maybe it’s something for the core. But maybe the customer Service should be redesigned in a bigger way!? At least for me the customer service right now, is a big mess 🙂



  • Yeah, our tech support staff wanted a few things added before using it.

    I’ll see what else is missing, we are also adding an option to simply send a message to multiple persons without reassigning it to anybody. Sometimes, our tech support staff are sending me and other colleagues questions that they don’t know how to answer. They have to be able to send it to multiple persons at once and also, I don’t want it to be ‘reassigned’ to me in the backend. So basically just a ‘forward’ option. We are almost done on that too.


 

Looks like your connection to thirty bees forum was lost, please wait while we try to reconnect.