// fix refactoring templates in AdminCustomerThreadsController
This commit is contained in:
@@ -0,0 +1,102 @@
|
|||||||
|
{*
|
||||||
|
* 2007-2011 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-2011 PrestaShop SA
|
||||||
|
* @version Release: $Revision: 9639 $
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* International Registered Trademark & Property of PrestaShop SA
|
||||||
|
*}
|
||||||
|
|
||||||
|
{extends file="helper/list/list_header.tpl"}
|
||||||
|
|
||||||
|
{block name="override_header"}
|
||||||
|
|
||||||
|
<div id="CustomerThreadContacts">
|
||||||
|
|
||||||
|
{assign var=nb_categories value=count($categories)}
|
||||||
|
|
||||||
|
{foreach $categories as $key => $val}
|
||||||
|
|
||||||
|
{assign var=total_thread value=0}
|
||||||
|
{assign var=id_customer_thread value=0}
|
||||||
|
|
||||||
|
{foreach $contacts as $tmp => $tmp2}
|
||||||
|
{if $val.id_contact == $tmp2.id_contact}
|
||||||
|
|
||||||
|
{assign var=total_thread value=$tmp2.total}
|
||||||
|
{assign var=id_customer_thread value=$tmp2.id_customer_thread}
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
{/foreach}
|
||||||
|
|
||||||
|
<div style="width:{if $nb_categories > 6}200{else}300{/if}px;">
|
||||||
|
|
||||||
|
<h3> {$val.name}</h3>
|
||||||
|
|
||||||
|
{if $nb_categories < 6}
|
||||||
|
<p>{$val.description}</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $total_thread == 0}
|
||||||
|
<h4>{l s='No new message'}</h4>
|
||||||
|
{else}
|
||||||
|
<a href="{$currentIndex}&token={$token}&id_customer_thread={$id_customer_thread}&viewcustomer_thread" class="button">
|
||||||
|
{$total_thread}
|
||||||
|
{if $total_thread > 1}{l s='new messages'}{else}{l s='new message'}{/if}
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/foreach}
|
||||||
|
|
||||||
|
<div id="MeaningStatus">
|
||||||
|
<h3> {l s='Meaning of status'}</h3>
|
||||||
|
<ul>
|
||||||
|
<li><img src="../img/admin/status_green.png" alt="{l s='Open'}">{l s='Open'}</li>
|
||||||
|
<li><img src="../img/admin/status_red.png" alt="{l s='Closed'}">{l s='Closed'}</li>
|
||||||
|
<li><img src="../img/admin/status_orange.png" alt="{l s='Pending 1'}">{l s='Pending 1'}</li>
|
||||||
|
<li><img src="../img/admin/status_orange.png" alt="{l s='Pending 2'}">{l s='Pending 2'}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="CustomerService">
|
||||||
|
<table cellspacing="1" class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">{l s='Customer service'} : {l s='Statistics'}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{assign var=count value=0}
|
||||||
|
{foreach $params as $key => $val}
|
||||||
|
{assign var=count value=$count+1}
|
||||||
|
<tr {if $count % 2 == 0}class="alt_row"{/if}>
|
||||||
|
<td>{$key}</td>
|
||||||
|
<td>{$val}</td>
|
||||||
|
</tr>
|
||||||
|
{/foreach}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="clear"> </p>
|
||||||
|
|
||||||
|
{/block}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
{*
|
||||||
|
* 2007-2011 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-2011 PrestaShop SA
|
||||||
|
* @version Release: $Revision: 8897 $
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* International Registered Trademark & Property of PrestaShop SA
|
||||||
|
*}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{if !$email}
|
||||||
|
|
||||||
|
<fieldset style="margin-top:10px;{if !empty($message.employee_name)}background: rgb(255,236,242){/if}">
|
||||||
|
<legend {if !empty($message.employee_name)}style="background:rgb(255,210,225)"{/if}>
|
||||||
|
{if !empty($message.employee_name)}
|
||||||
|
<img src="../img/t/AdminCustomers.gif" alt="{$PS_SHOP_NAME}" />
|
||||||
|
{$PS_SHOP_NAME} - {$message.employee_name}
|
||||||
|
{else}
|
||||||
|
<img src="../img/admin/tab-customers.gif" alt="{$PS_SHOP_NAME}" />
|
||||||
|
{if !empty($message.id_customer)}
|
||||||
|
<a href="index.php?tab=AdminCustomers&id_customer={$message.id_customer}&viewcustomer&token={getAdminToken tab='AdminCustomers'}" title="{l s='View customer'}">
|
||||||
|
{$message.customer_name}
|
||||||
|
</a>
|
||||||
|
{else}
|
||||||
|
{$message.email}
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</legend>
|
||||||
|
|
||||||
|
<div style="font-size:11px">
|
||||||
|
{if !empty($message.id_customer) && empty($message.employee_name)}
|
||||||
|
<b>{l s='Customer ID:'}</b>
|
||||||
|
<a href="index.php?tab=AdminCustomers&id_customer={$message.id_customer}&viewcustomer&token={getAdminToken tab='AdminCustomers'}" title="{l s='View customer'}">
|
||||||
|
{$message.id_customer} <img src="../img/admin/search.gif" alt="{l s='view'}" />
|
||||||
|
</a><br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<b>{l s='Sent on:'}</b> {$message.date_add}<br />
|
||||||
|
{if empty($message.employee_name)}
|
||||||
|
<b>{l s='Browser:'}</b> {$message.user_agent}<br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if !empty($message.file_name) && $file_name}
|
||||||
|
<b>{l s='File attachment'}</b>
|
||||||
|
<a href="index.php?tab=AdminCustomerThreads&id_customer_thread={$message.id_customer_thread}&viewcustomer_thread&token={getAdminToken tab='AdminCustomerThreads'}&filename={$message.file_name}"
|
||||||
|
title="{l s='View file'}">
|
||||||
|
<img src="../img/admin/search.gif" alt="{l s='view'}" />
|
||||||
|
</a><br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if !empty($message.id_order) && empty($message.employee_name)}
|
||||||
|
<b>{l s='Order #'}</b>
|
||||||
|
<a href="index.php?tab=AdminOrders&id_order={$message.id_order}&vieworder&token={getAdminToken tab='AdminOrders'}" title="{l s='View order'}">
|
||||||
|
{$message.id_order} <img src="../img/admin/search.gif" alt="{l s='view'}" />
|
||||||
|
</a><br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if !empty($message.id_product) && empty($message.employee_name)}
|
||||||
|
<b>{l s='Product #'}</b>
|
||||||
|
<a href="index.php?tab=AdminOrders&id_order={$id_order_product}&vieworder&token={getAdminToken tab='AdminOrders'}" title="{l s='View order'}">
|
||||||
|
{$message.id_product} <img src="../img/admin/search.gif" alt="{l s='view'}" />
|
||||||
|
</a><br />
|
||||||
|
{/if}
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<form action="{$current}&token={$token}&id_customer_thread={$message.id_customer_thread}&viewcustomer_thread" method="post">
|
||||||
|
<b>{l s='Subject:'}</b>
|
||||||
|
<input type="hidden" name="id_customer_message" value="{$message.id_customer_message}" />
|
||||||
|
<select name="id_contact" onchange="this.form.submit();">
|
||||||
|
{foreach $contacts as $contact}
|
||||||
|
<option value="{$contact.id_contact}" {if $contact.id_contact == $message.id_contact}selected="selected"{/if}>
|
||||||
|
{$contact.name}
|
||||||
|
</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{else}
|
||||||
|
|
||||||
|
<div style="font-size:11px">
|
||||||
|
{if $id_employee}
|
||||||
|
<a href="{$current}&token={getAdminToken tab='AdminCustomerThreads'}&id_customer_thread={$message.id_customer_thread}&viewcustomer_thread">'.
|
||||||
|
{l s='View this thread'}
|
||||||
|
</a><br />
|
||||||
|
{/if}
|
||||||
|
<b>{l s='Sent by:'}</b>
|
||||||
|
|
||||||
|
{if !empty($message.customer_name)}
|
||||||
|
{$message.customer_name} ({$message.email})
|
||||||
|
{else}
|
||||||
|
{$message.email}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if !empty($message.id_customer) && empty($message.employee_name)}
|
||||||
|
<br /><b>{l s='Customer ID:'}</b> {$message.id_customer}<br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if !empty($message.id_order) && empty($message.employee_name)}
|
||||||
|
<br /><b>{l s='Order #'}:</b> {$message.id_order}<br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if !empty($message.id_product) && empty($message.employee_name)}
|
||||||
|
<br /><b>{l s='Product #'}:</b> {$message.id_product}<br />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<br /><b>{l s='Subject:'}</b> {$message.subject}
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
<br /><br />
|
||||||
|
<b>{l s='Thread ID:'}</b> {$message.id_customer_thread}<br />
|
||||||
|
<b>{l s='Message ID:'}</b> {$message.id_customer_message}<br />
|
||||||
|
<b>{l s='Message:'}</b><br />
|
||||||
|
{$message.message}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{if !$email}
|
||||||
|
|
||||||
|
{if empty($message.employee_name)}
|
||||||
|
|
||||||
|
<p style="text-align:right">
|
||||||
|
<button style="font-family: Verdana; font-size: 11px; font-weight:bold; height: 65px; width: 120px;"
|
||||||
|
onclick="$('#reply_to_{$message.id_customer_message}').show(500); $(this).hide();">
|
||||||
|
<img src="../img/admin/contact.gif" alt="" style="margin-bottom: 5px;" /><br />{l s='Reply to this message'}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div id="reply_to_{$message.id_customer_message}" style="display: none; margin-top: 20px;"">
|
||||||
|
<form action="{$current}&token={getAdminToken tab='AdminCustomerThreads'}&id_customer_thread={$message.id_customer_thread}&viewcustomer_thread" method="post" enctype="multipart/form-data">
|
||||||
|
<p>{l s='Please type your reply below:'}</p>
|
||||||
|
<textarea style="width: 450px; height: 175px;" name="reply_message">'.
|
||||||
|
{$PS_CUSTOMER_SERVICE_SIGNATURE}
|
||||||
|
</textarea>
|
||||||
|
<div style="width: 450px; text-align: right; font-style: italic; font-size: 9px; margin-top: 2px;">
|
||||||
|
{l s='Your reply will be sent to:'} {$message.email}
|
||||||
|
</div>
|
||||||
|
<div style="width: 450px; margin-top: 0px;">
|
||||||
|
<input type="file" name="joinFile"/>
|
||||||
|
<div>
|
||||||
|
<div style="width: 450px; text-align: center;">
|
||||||
|
<input type="submit" class="button" name="submitReply" value="{l s='Send my reply'}" style="margin-top:20px;" />
|
||||||
|
<input type="hidden" name="id_customer_thread" value="{$message.id_customer_thread}" />
|
||||||
|
<input type="hidden" name="msg_email" value="{$message.email}" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
{*
|
||||||
|
* 2007-2011 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-2011 PrestaShop SA
|
||||||
|
* @version Release: $Revision: 8897 $
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
* International Registered Trademark & Property of PrestaShop SA
|
||||||
|
*}
|
||||||
|
|
||||||
|
{extends file="helper/view/view.tpl"}
|
||||||
|
|
||||||
|
{block name="override_tpl"}
|
||||||
|
<form action="{$current}&token={$token}&viewcustomer_thread&id_customer_thread={$id_customer_thread}" method="post" enctype="multipart/form-data">
|
||||||
|
<fieldset>
|
||||||
|
|
||||||
|
<div id="ChangeStatus">
|
||||||
|
<select onchange="quickSelect(this);">
|
||||||
|
<option value="0">{l s='Change status of message:'}</option>
|
||||||
|
{foreach $actions as $action}
|
||||||
|
<option value="{$action.href}">> {$action.name}</option>
|
||||||
|
{/foreach}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<img src="../img/admin/msg-forward.png" alt="" style="vertical-align: middle;" />
|
||||||
|
{l s='Forward this discussion to an employee:'}
|
||||||
|
<select name="id_employee_forward" style="vertical-align: middle;">
|
||||||
|
<option value="-1">{l s='-- Choose --'}</option>
|
||||||
|
{foreach $employees as $employee}
|
||||||
|
<option value="{$employee.id_employee}"> {$employee.firstname|substr:0:1}. {$employee.lastname}</option>
|
||||||
|
{/foreach}
|
||||||
|
<option value="0">{l s='Someone else'}</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="message_forward_email" style="display:none">
|
||||||
|
<b>{l s='E-mail'}</b> <input type="text" name="email" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="message_forward" style="display:none;margin-bottom:10px">
|
||||||
|
<textarea name="message_forward" style="width:500px;height:80px;margin-top:15px;">{l s='You can add a comment here.'}</textarea><br />
|
||||||
|
<input type="Submit" name="submitForward" class="button" value="{l s='Forward this discussion'}" style="margin-top: 10px;" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<div class="clear"> </div>
|
||||||
|
|
||||||
|
{if $thread->id_customer}
|
||||||
|
|
||||||
|
<div style="float:right;margin-left:20px;">
|
||||||
|
{if $orders && count($orders)}
|
||||||
|
{if $count_ok}
|
||||||
|
<div>
|
||||||
|
<h2>{l s='Orders'}</h2>
|
||||||
|
<table cellspacing="0" cellpadding="0" class="table float">
|
||||||
|
<tr>
|
||||||
|
<th class="center">{l s='ID'}</th>
|
||||||
|
<th class="center">{l s='Date'}</th>
|
||||||
|
<th class="center">{l s='Products'}</th>
|
||||||
|
<th class="center">{l s='Total paid'}</th>
|
||||||
|
<th class="center">{l s='Payment'}</th>
|
||||||
|
<th class="center">{l s='State'}</th>
|
||||||
|
<th class="center">{l s='Actions'}</th>
|
||||||
|
</tr>
|
||||||
|
{assign var=irow value=0}
|
||||||
|
{foreach $orders_ok as $order}
|
||||||
|
<tr {if $irow++ % 2}class="alt_row"{/if} style="cursor: pointer"
|
||||||
|
onclick="document.location='?tab=AdminOrders&id_order={$order.id_order}&vieworder&token={getAdminToken tab='AdminOrders'}">
|
||||||
|
<td class="center">{$order.id_order}</td>
|
||||||
|
<td>{$order.date_add}</td>
|
||||||
|
<td align="right">{$order.nb_products}</td>
|
||||||
|
<td align="right">{$order.total_paid_real}</td>
|
||||||
|
<td>{$order.payment}</td>
|
||||||
|
<td>{$order.order_state}</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="?tab=AdminOrders&id_order={$order.id_order}&vieworder&token={getAdminToken tab='AdminOrders'}">
|
||||||
|
<img src="../img/admin/details.gif" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/foreach}
|
||||||
|
</table>
|
||||||
|
<h3 style="color:green;font-weight:700;margin-top:10px">
|
||||||
|
{l s='Validated Orders:'} {$count_ok} {l s='for'} {$total_ok}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{if $products && count($products)}
|
||||||
|
<div>
|
||||||
|
<h2>{l s='Products'}</h2>
|
||||||
|
<table cellspacing="0" cellpadding="0" class="table">
|
||||||
|
<tr>
|
||||||
|
<th class="center">{l s='Date'}</th>
|
||||||
|
<th class="center">{l s='ID'}</th>
|
||||||
|
<th class="center">{l s='Name'}</th>
|
||||||
|
<th class="center">{l s='Quantity'}</th>
|
||||||
|
<th class="center">{l s='Actions'}</th>
|
||||||
|
</tr>
|
||||||
|
{assign var=irow value=0}
|
||||||
|
{foreach $products as $product}
|
||||||
|
<tr {if $irow++ % 2}class="alt_row"{/if} style="cursor: pointer"
|
||||||
|
onclick="document.location = '?tab=AdminOrders&id_order={$product.id_order}&vieworder&token={getAdminToken tab='AdminOrders'}'">
|
||||||
|
<td>{$product.date_add}</td>
|
||||||
|
<td>{$product.product_id}</td>
|
||||||
|
<td>{$product.product_name}</td>
|
||||||
|
<td align="right">{$product.product_quantity}</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="?tab=AdminOrders&id_order={$product.id_order}&vieworder&token={getAdminToken tab='AdminOrders'}">
|
||||||
|
<img src="../img/admin/details.gif" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/foreach}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div style="margin-top:10px">
|
||||||
|
{foreach $messages as $message}
|
||||||
|
{$message}
|
||||||
|
{/foreach}
|
||||||
|
</div>
|
||||||
|
<div class="clear"> </div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(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);
|
||||||
|
});
|
||||||
|
$('teaxtrea[name=message_forward]').click(function(){
|
||||||
|
if($(this).val() == '{l s='You can add a comment here.'}')
|
||||||
|
{
|
||||||
|
$(this).val('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
*}
|
*}
|
||||||
|
|
||||||
{if !$simple_header}
|
{if !$simple_header}
|
||||||
<link href="../css/admin.css" rel="stylesheet" type="text/css" />
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|||||||
+30
-15
@@ -27,34 +27,34 @@
|
|||||||
|
|
||||||
class ContactCore extends ObjectModel
|
class ContactCore extends ObjectModel
|
||||||
{
|
{
|
||||||
public $id;
|
public $id;
|
||||||
|
|
||||||
/** @var string Name */
|
/** @var string Name */
|
||||||
public $name;
|
public $name;
|
||||||
|
|
||||||
/** @var string e-mail */
|
/** @var string e-mail */
|
||||||
public $email;
|
public $email;
|
||||||
|
|
||||||
/** @var string Detailed description */
|
/** @var string Detailed description */
|
||||||
public $description;
|
public $description;
|
||||||
|
|
||||||
public $customer_service;
|
public $customer_service;
|
||||||
|
|
||||||
protected $fieldsRequired = array();
|
protected $fieldsRequired = array();
|
||||||
protected $fieldsSize = array('email' => 128);
|
protected $fieldsSize = array('email' => 128);
|
||||||
protected $fieldsValidate = array('email' => 'isEmail', 'customer_service' => 'isBool');
|
protected $fieldsValidate = array('email' => 'isEmail', 'customer_service' => 'isBool');
|
||||||
protected $fieldsRequiredLang = array('name');
|
protected $fieldsRequiredLang = array('name');
|
||||||
protected $fieldsSizeLang = array('name' => 32);
|
protected $fieldsSizeLang = array('name' => 32);
|
||||||
protected $fieldsValidateLang = array('name' => 'isGenericName', 'description' => 'isCleanHtml');
|
protected $fieldsValidateLang = array('name' => 'isGenericName', 'description' => 'isCleanHtml');
|
||||||
|
|
||||||
protected $table = 'contact';
|
protected $table = 'contact';
|
||||||
protected $identifier = 'id_contact';
|
protected $identifier = 'id_contact';
|
||||||
|
|
||||||
public function getFields()
|
public function getFields()
|
||||||
{
|
{
|
||||||
$this->validateFields();
|
$this->validateFields();
|
||||||
$fields['email'] = pSQL($this->email);
|
$fields['email'] = pSQL($this->email);
|
||||||
$fields['customer_service'] = (int)($this->customer_service);
|
$fields['customer_service'] = (int)$this->customer_service;
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class ContactCore extends ObjectModel
|
|||||||
* @param Context
|
* @param Context
|
||||||
* @return array Contacts
|
* @return array Contacts
|
||||||
*/
|
*/
|
||||||
static public function getContacts($id_lang, Shop $shop = null)
|
public static function getContacts($id_lang, Shop $shop = null)
|
||||||
{
|
{
|
||||||
if (!$shop)
|
if (!$shop)
|
||||||
$shop = Context::getContext()->shop;
|
$shop = Context::getContext()->shop;
|
||||||
@@ -89,5 +89,20 @@ class ContactCore extends ObjectModel
|
|||||||
ORDER BY `name` ASC';
|
ORDER BY `name` ASC';
|
||||||
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
|
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return available categories contacts
|
||||||
|
* @return array Contacts
|
||||||
|
*/
|
||||||
|
public static function getCategoriesContacts()
|
||||||
|
{
|
||||||
|
return Db::getInstance()->executeS('
|
||||||
|
SELECT cl.*
|
||||||
|
FROM '._DB_PREFIX_.'contact ct
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'contact_lang cl
|
||||||
|
ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)Context::getContext()->language->id.')
|
||||||
|
WHERE ct.customer_service = 1
|
||||||
|
');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-11
@@ -47,11 +47,11 @@ class CustomerMessageCore extends ObjectModel
|
|||||||
public function getFields()
|
public function getFields()
|
||||||
{
|
{
|
||||||
$this->validateFields();
|
$this->validateFields();
|
||||||
$fields['id_customer_thread'] = (int)($this->id_customer_thread);
|
$fields['id_customer_thread'] = (int)$this->id_customer_thread;
|
||||||
$fields['id_employee'] = (int)($this->id_employee);
|
$fields['id_employee'] = (int)$this->id_employee;
|
||||||
$fields['message'] = pSQL($this->message);
|
$fields['message'] = pSQL($this->message);
|
||||||
$fields['file_name'] = pSQL($this->file_name);
|
$fields['file_name'] = pSQL($this->file_name);
|
||||||
$fields['ip_address'] = (int)($this->ip_address);
|
$fields['ip_address'] = (int)$this->ip_address;
|
||||||
$fields['user_agent'] = pSQL($this->user_agent);
|
$fields['user_agent'] = pSQL($this->user_agent);
|
||||||
$fields['private'] = pSQL($this->private);
|
$fields['private'] = pSQL($this->private);
|
||||||
$fields['date_add'] = pSQL($this->date_add);
|
$fields['date_add'] = pSQL($this->date_add);
|
||||||
@@ -61,14 +61,39 @@ class CustomerMessageCore extends ObjectModel
|
|||||||
public static function getMessagesByOrderId($id_order, $private = true)
|
public static function getMessagesByOrderId($id_order, $private = true)
|
||||||
{
|
{
|
||||||
return Db::getInstance()->executeS('
|
return Db::getInstance()->executeS('
|
||||||
SELECT cm.*, c.`firstname` AS cfirstname, c.`lastname` AS clastname, e.`firstname` AS efirstname, e.`lastname` AS elastname, (COUNT(cm.id_customer_message) = 0 AND ct.id_customer != 0) AS is_new_for_me
|
SELECT cm.*,
|
||||||
FROM `'._DB_PREFIX_.'customer_message` cm
|
c.`firstname` AS cfirstname,
|
||||||
LEFT JOIN `'._DB_PREFIX_.'customer_thread` ct ON ct.`id_customer_thread` = cm.`id_customer_thread`
|
c.`lastname` AS clastname,
|
||||||
LEFT JOIN `'._DB_PREFIX_.'customer` c ON ct.`id_customer` = c.`id_customer`
|
e.`firstname` AS efirstname,
|
||||||
LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e ON e.`id_employee` = cm.`id_employee`
|
e.`lastname` AS elastname,
|
||||||
WHERE ct.id_order = '.(int)$id_order.' AND '.(!$private ? 'cm.`private` = 0' : '').'
|
(COUNT(cm.id_customer_message) = 0 AND ct.id_customer != 0) AS is_new_for_me
|
||||||
GROUP BY cm.id_customer_message
|
FROM `'._DB_PREFIX_.'customer_message` cm
|
||||||
ORDER BY cm.date_add DESC');
|
LEFT JOIN `'._DB_PREFIX_.'customer_thread` ct
|
||||||
|
ON ct.`id_customer_thread` = cm.`id_customer_thread`
|
||||||
|
LEFT JOIN `'._DB_PREFIX_.'customer` c
|
||||||
|
ON ct.`id_customer` = c.`id_customer`
|
||||||
|
LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e
|
||||||
|
ON e.`id_employee` = cm.`id_employee`
|
||||||
|
WHERE ct.id_order = '.(int)$id_order.'
|
||||||
|
AND '.(!$private ? 'cm.`private` = 0' : '').'
|
||||||
|
GROUP BY cm.id_customer_message
|
||||||
|
ORDER BY cm.date_add DESC
|
||||||
|
');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getTotalCustomerMessages($where = null)
|
||||||
|
{
|
||||||
|
if (is_null($where))
|
||||||
|
return (int)Db::getInstance()->getValue('
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM '._DB_PREFIX_.'customer_message
|
||||||
|
');
|
||||||
|
else
|
||||||
|
return (int)Db::getInstance()->getValue(sprintf('
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM '._DB_PREFIX_.'customer_message
|
||||||
|
WHERE %s
|
||||||
|
', $where));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-13
@@ -45,18 +45,27 @@ class CustomerThreadCore extends ObjectModel
|
|||||||
|
|
||||||
protected $fieldsRequired = array('id_lang', 'id_contact', 'token');
|
protected $fieldsRequired = array('id_lang', 'id_contact', 'token');
|
||||||
protected $fieldsSize = array('email' => 254);
|
protected $fieldsSize = array('email' => 254);
|
||||||
protected $fieldsValidate = array('id_lang' => 'isUnsignedId', 'id_contact' => 'isUnsignedId', 'id_shop' => 'isUnsignedId', 'id_customer' => 'isUnsignedId',
|
|
||||||
'id_order' => 'isUnsignedId', 'id_product' => 'isUnsignedId', 'email' => 'isEmail', 'token' => 'isGenericName');
|
protected $fieldsValidate = array(
|
||||||
|
'id_lang' => 'isUnsignedId',
|
||||||
|
'id_contact' => 'isUnsignedId',
|
||||||
|
'id_shop' => 'isUnsignedId',
|
||||||
|
'id_customer' => 'isUnsignedId',
|
||||||
|
'id_order' => 'isUnsignedId',
|
||||||
|
'id_product' => 'isUnsignedId',
|
||||||
|
'email' => 'isEmail',
|
||||||
|
'token' => 'isGenericName'
|
||||||
|
);
|
||||||
|
|
||||||
public function getFields()
|
public function getFields()
|
||||||
{
|
{
|
||||||
$this->validateFields();
|
$this->validateFields();
|
||||||
$fields['id_lang'] = (int)($this->id_lang);
|
$fields['id_lang'] = (int)$this->id_lang;
|
||||||
$fields['id_shop'] = (int)$this->id_shop;
|
$fields['id_shop'] = (int)$this->id_shop;
|
||||||
$fields['id_contact'] = (int)($this->id_contact);
|
$fields['id_contact'] = (int)$this->id_contact;
|
||||||
$fields['id_customer'] = (int)($this->id_customer);
|
$fields['id_customer'] = (int)$this->id_customer;
|
||||||
$fields['id_order'] = (int)($this->id_order);
|
$fields['id_order'] = (int)$this->id_order;
|
||||||
$fields['id_product'] = (int)($this->id_product);
|
$fields['id_product'] = (int)$this->id_product;
|
||||||
$fields['status'] = pSQL($this->status);
|
$fields['status'] = pSQL($this->status);
|
||||||
$fields['email'] = pSQL($this->email);
|
$fields['email'] = pSQL($this->email);
|
||||||
$fields['token'] = pSQL($this->token);
|
$fields['token'] = pSQL($this->token);
|
||||||
@@ -69,23 +78,108 @@ class CustomerThreadCore extends ObjectModel
|
|||||||
{
|
{
|
||||||
if (!Validate::isUnsignedId($this->id))
|
if (!Validate::isUnsignedId($this->id))
|
||||||
return false;
|
return false;
|
||||||
Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'customer_message` WHERE `id_customer_thread` = '.(int)($this->id));
|
Db::getInstance()->execute('
|
||||||
|
DELETE FROM `'._DB_PREFIX_.'customer_message`
|
||||||
|
WHERE `id_customer_thread` = '.(int)$this->id
|
||||||
|
);
|
||||||
return (parent::delete());
|
return (parent::delete());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getCustomerMessages($id_customer)
|
public static function getCustomerMessages($id_customer)
|
||||||
{
|
{
|
||||||
return Db::getInstance()->executeS('
|
return Db::getInstance()->executeS('
|
||||||
SELECT * FROM '._DB_PREFIX_.'customer_thread ct
|
SELECT *
|
||||||
LEFT JOIN '._DB_PREFIX_.'customer_message cm ON ct.id_customer_thread = cm.id_customer_thread
|
FROM '._DB_PREFIX_.'customer_thread ct
|
||||||
WHERE id_customer = '.(int)($id_customer));
|
LEFT JOIN '._DB_PREFIX_.'customer_message cm
|
||||||
|
ON ct.id_customer_thread = cm.id_customer_thread
|
||||||
|
WHERE id_customer = '.(int)$id_customer
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getIdCustomerThreadByEmailAndIdOrder($email, $id_order)
|
public static function getIdCustomerThreadByEmailAndIdOrder($email, $id_order)
|
||||||
{
|
{
|
||||||
return Db::getInstance()->getValue('
|
return Db::getInstance()->getValue('
|
||||||
SELECT cm.id_customer_thread FROM '._DB_PREFIX_.'customer_thread cm
|
SELECT cm.id_customer_thread
|
||||||
WHERE cm.email = \''.pSQL($email).'\' AND cm.id_shop = '.(int)Context::getContext()->shop->getId(true).' AND cm.id_order = '.(int)$id_order.'');
|
FROM '._DB_PREFIX_.'customer_thread cm
|
||||||
|
WHERE cm.email = \''.pSQL($email).'\'
|
||||||
|
AND cm.id_shop = '.(int)Context::getContext()->shop->getId(true).'
|
||||||
|
AND cm.id_order = '.(int)$id_order
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getContacts()
|
||||||
|
{
|
||||||
|
return Db::getInstance()->executeS('
|
||||||
|
SELECT cl.*, COUNT(*) as total, (
|
||||||
|
SELECT id_customer_thread
|
||||||
|
FROM '._DB_PREFIX_.'customer_thread ct2
|
||||||
|
WHERE status = "open" AND ct.id_contact = ct2.id_contact
|
||||||
|
ORDER BY date_upd ASC
|
||||||
|
LIMIT 1
|
||||||
|
) as id_customer_thread
|
||||||
|
FROM '._DB_PREFIX_.'customer_thread ct
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'contact_lang cl
|
||||||
|
ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)Context::getContext()->language->id.')
|
||||||
|
WHERE ct.status = "open"
|
||||||
|
AND ct.id_contact IS NOT NULL
|
||||||
|
AND cl.id_contact IS NOT NULL
|
||||||
|
GROUP BY ct.id_contact HAVING COUNT(*) > 0
|
||||||
|
');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getTotalCustomerThreads($where = null)
|
||||||
|
{
|
||||||
|
if (is_null($where))
|
||||||
|
return (int)Db::getInstance()->getValue('
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM '._DB_PREFIX_.'customer_thread
|
||||||
|
');
|
||||||
|
else
|
||||||
|
return (int)Db::getInstance()->getValue(sprintf('
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM '._DB_PREFIX_.'customer_thread
|
||||||
|
WHERE %s
|
||||||
|
', $where));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMessageCustomerThreads($id_customer_thread)
|
||||||
|
{
|
||||||
|
return Db::getInstance()->executeS('
|
||||||
|
SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name,
|
||||||
|
CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname
|
||||||
|
FROM '._DB_PREFIX_.'customer_thread ct
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'customer_message cm
|
||||||
|
ON (ct.id_customer_thread = cm.id_customer_thread)
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'contact_lang cl
|
||||||
|
ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)Context::getContext()->language->id.')
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'employee e
|
||||||
|
ON e.id_employee = cm.id_employee
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'customer c
|
||||||
|
ON (IFNULL(ct.id_customer, ct.email) = IFNULL(c.id_customer, c.email))
|
||||||
|
WHERE ct.id_customer_thread = '.(int)$id_customer_thread.'
|
||||||
|
ORDER BY cm.date_add DESC
|
||||||
|
');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getNextThread($id_customer_thread)
|
||||||
|
{
|
||||||
|
$context = Context::getContext();
|
||||||
|
return Db::getInstance()->getValue('
|
||||||
|
SELECT id_customer_thread
|
||||||
|
FROM '._DB_PREFIX_.'customer_thread ct
|
||||||
|
WHERE ct.status = "open"
|
||||||
|
AND ct.date_upd = (
|
||||||
|
SELECT date_add FROM '._DB_PREFIX_.'customer_message
|
||||||
|
WHERE (id_employee IS NULL OR id_employee = 0)
|
||||||
|
AND id_customer_thread = '.(int)$id_customer_thread.'
|
||||||
|
ORDER BY date_add DESC LIMIT 1
|
||||||
|
)
|
||||||
|
'.($context->cookie->{'customer_threadFilter_cl!id_contact'} ?
|
||||||
|
'AND ct.id_contact = '.(int)$context->cookie->{'customer_threadFilter_cl!id_contact'} : '').'
|
||||||
|
'.($context->cookie->{'customer_threadFilter_l!id_lang'} ?
|
||||||
|
'AND ct.id_lang = '.(int)$context->cookie->{'customer_threadFilter_l!id_lang'} : '').
|
||||||
|
' ORDER BY ct.date_upd ASC
|
||||||
|
');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,19 @@ class EmployeeCore extends ObjectModel
|
|||||||
return parent::add($autodate, $null_values);
|
return parent::add($autodate, $null_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return list of employees
|
||||||
|
*/
|
||||||
|
public static function getEmployees()
|
||||||
|
{
|
||||||
|
return Db::getInstance()->executeS('
|
||||||
|
SELECT `id_employee`, `firstname`, `lastname`
|
||||||
|
FROM `'._DB_PREFIX_.'employee`
|
||||||
|
WHERE `active` = 1
|
||||||
|
ORDER BY `lastname` ASC
|
||||||
|
');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return employee instance from its e-mail (optionnaly check password)
|
* Return employee instance from its e-mail (optionnaly check password)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -604,6 +604,19 @@ class OrderCore extends ObjectModel
|
|||||||
return $resultArray;
|
return $resultArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getIdOrderProduct($id_customer, $id_product)
|
||||||
|
{
|
||||||
|
return (int)Db::getInstance()->getValue('
|
||||||
|
SELECT o.id_order
|
||||||
|
FROM '._DB_PREFIX_.'orders o
|
||||||
|
LEFT JOIN '._DB_PREFIX_.'order_detail od
|
||||||
|
ON o.id_order = od.id_order
|
||||||
|
WHERE o.id_customer = '.(int)$id_customer.'
|
||||||
|
AND od.product_id = '.(int)$id_product.'
|
||||||
|
ORDER BY o.date_add DESC
|
||||||
|
');
|
||||||
|
}
|
||||||
|
|
||||||
protected function setProductCustomizedDatas(&$product, $customized_datas)
|
protected function setProductCustomizedDatas(&$product, $customized_datas)
|
||||||
{
|
{
|
||||||
$product['customizedDatas'] = null;
|
$product['customizedDatas'] = null;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class AdminCartsController extends AdminController
|
|||||||
'callback' => 'getOrderTotalUsingTaxCalculationMethod',
|
'callback' => 'getOrderTotalUsingTaxCalculationMethod',
|
||||||
'orderby' => false,
|
'orderby' => false,
|
||||||
'search' => false,
|
'search' => false,
|
||||||
'width' => 50,
|
'width' => 80,
|
||||||
'align' => 'right',
|
'align' => 'right',
|
||||||
'prefix' => '<b>',
|
'prefix' => '<b>',
|
||||||
'suffix' => '</b>',
|
'suffix' => '</b>',
|
||||||
@@ -72,14 +72,14 @@ class AdminCartsController extends AdminController
|
|||||||
),
|
),
|
||||||
'carrier' => array(
|
'carrier' => array(
|
||||||
'title' => $this->l('Carrier'),
|
'title' => $this->l('Carrier'),
|
||||||
'width' => 25,
|
'width' => 50,
|
||||||
'align' => 'center',
|
'align' => 'center',
|
||||||
'callback' => 'replaceZeroByShopName',
|
'callback' => 'replaceZeroByShopName',
|
||||||
'filter_key' => 'ca!name'
|
'filter_key' => 'ca!name'
|
||||||
),
|
),
|
||||||
'date_add' => array(
|
'date_add' => array(
|
||||||
'title' => $this->l('Date'),
|
'title' => $this->l('Date'),
|
||||||
'width' => 90,
|
'width' => 120,
|
||||||
'align' => 'right',
|
'align' => 'right',
|
||||||
'type' => 'datetime',
|
'type' => 'datetime',
|
||||||
'filter_key' => 'a!date_add'
|
'filter_key' => 'a!date_add'
|
||||||
|
|||||||
@@ -31,74 +31,147 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
{
|
{
|
||||||
$this->context = Context::getContext();
|
$this->context = Context::getContext();
|
||||||
$this->table = 'customer_thread';
|
$this->table = 'customer_thread';
|
||||||
|
$this->className = 'CustomerThread';
|
||||||
$this->lang = false;
|
$this->lang = false;
|
||||||
$this->className = 'CustomerThread';
|
|
||||||
$this->edit = false;
|
|
||||||
$this->view = true;
|
|
||||||
$this->delete = true;
|
|
||||||
|
|
||||||
$this->_select = 'CONCAT(c.firstname," ",c.lastname) as customer, cl.name as contact, l.name as language, group_concat(message) as messages, (
|
$contact_array = array();
|
||||||
SELECT IFNULL(CONCAT(LEFT(e.firstname, 1),". ",e.lastname), "--")
|
|
||||||
FROM '._DB_PREFIX_.'customer_message cm2 INNER JOIN '._DB_PREFIX_.'employee e ON e.id_employee = cm2.id_employee
|
|
||||||
WHERE cm2.id_employee > 0 AND cm2.`id_customer_thread` = a.`id_customer_thread`
|
|
||||||
ORDER BY cm2.date_add DESC LIMIT 1) as employee';
|
|
||||||
$this->_group = 'GROUP BY cm.id_customer_thread';
|
|
||||||
$this->_join = '
|
|
||||||
LEFT JOIN `'._DB_PREFIX_.'customer` c ON c.`id_customer` = a.`id_customer`
|
|
||||||
LEFT JOIN `'._DB_PREFIX_.'customer_message` cm ON cm.`id_customer_thread` = a.`id_customer_thread`
|
|
||||||
LEFT JOIN `'._DB_PREFIX_.'lang` l ON l.`id_lang` = a.`id_lang`
|
|
||||||
LEFT JOIN `'._DB_PREFIX_.'contact_lang` cl ON (cl.`id_contact` = a.`id_contact` AND cl.`id_lang` = '.(int)$this->context->language->id.')';
|
|
||||||
|
|
||||||
$contactArray = array();
|
|
||||||
$contacts = Contact::getContacts($this->context->language->id);
|
$contacts = Contact::getContacts($this->context->language->id);
|
||||||
foreach ($contacts AS $contact)
|
foreach ($contacts as $contact)
|
||||||
$contactArray[$contact['id_contact']] = $contact['name'];
|
$contact_array[$contact['id_contact']] = $contact['name'];
|
||||||
|
|
||||||
$languageArray = array();
|
$language_array = array();
|
||||||
$languages = Language::getLanguages();
|
$languages = Language::getLanguages();
|
||||||
foreach ($languages AS $language)
|
foreach ($languages as $language)
|
||||||
$languageArray[$language['id_lang']] = $language['name'];
|
$language_array[$language['id_lang']] = $language['name'];
|
||||||
|
|
||||||
$statusArray = array(
|
$status_array = array(
|
||||||
'open' => $this->l('Open'),
|
'open' => $this->l('Open'),
|
||||||
'closed' => $this->l('Closed'),
|
'closed' => $this->l('Closed'),
|
||||||
'pending1' => $this->l('Pending 1'),
|
'pending1' => $this->l('Pending 1'),
|
||||||
'pending2' => $this->l('Pending 2')
|
'pending2' => $this->l('Pending 2')
|
||||||
);
|
);
|
||||||
|
|
||||||
$imagesArray = array(
|
$images_array = array(
|
||||||
'open' => 'status_green.gif',
|
'open' => 'status_green.png',
|
||||||
'closed' => 'status_red.gif',
|
'closed' => 'status_red.png',
|
||||||
'pending1' => 'status_orange.gif',
|
'pending1' => 'status_orange.png',
|
||||||
'pending2' => 'status_orange.gif'
|
'pending2' => 'status_orange.png'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->fieldsDisplay = array(
|
$this->fieldsDisplay = array(
|
||||||
'id_customer_thread' => array('title' => $this->l('ID'), 'width' => 25),
|
'id_customer_thread' => array(
|
||||||
'customer' => array('title' => $this->l('Customer'), 'width' => 100, 'filter_key' => 'customer', 'tmpTableFilter' => true),
|
'title' => $this->l('ID'),
|
||||||
'email' => array('title' => $this->l('E-mail'), 'width' => 100, 'filter_key' => 'a!email'),
|
'width' => 25
|
||||||
'contact' => array('title' => $this->l('Type'), 'width' => 75, 'type' => 'select', 'list' => $contactArray, 'filter_key' => 'cl!id_contact', 'filter_type' => 'int'),
|
),
|
||||||
'language' => array('title' => $this->l('Language'), 'width' => 60, 'type' => 'select', 'list' => $languageArray, 'filter_key' => 'l!id_lang', 'filter_type' => 'int'),
|
'customer' => array(
|
||||||
'status' => array('title' => $this->l('Status'), 'width' => 50, 'type' => 'select', 'list' => $statusArray, 'icon' => $imagesArray, 'align' => 'center', 'filter_key' => 'a!status', 'filter_type' => 'string'),
|
'title' => $this->l('Customer'),
|
||||||
'employee' => array('title' => $this->l('Employee'), 'width' => 100, 'filter_key' => 'employee', 'tmpTableFilter' => true),
|
'width' => 100,
|
||||||
'messages' => array('title' => $this->l('Messages'), 'width' => 50, 'filter_key' => 'messages', 'tmpTableFilter' => true, 'maxlength' => 0),
|
'filter_key' => 'customer',
|
||||||
'date_upd' => array('title' => $this->l('Last message'), 'width' => 90)
|
'tmpTableFilter' => true
|
||||||
|
),
|
||||||
|
'email' => array(
|
||||||
|
'title' => $this->l('E-mail'),
|
||||||
|
'width' => 100,
|
||||||
|
'filter_key' => 'a!email'
|
||||||
|
),
|
||||||
|
'contact' => array(
|
||||||
|
'title' => $this->l('Type'),
|
||||||
|
'width' => 75,
|
||||||
|
'type' => 'select',
|
||||||
|
'list' => $contact_array,
|
||||||
|
'filter_key' => 'cl!id_contact',
|
||||||
|
'filter_type' => 'int'
|
||||||
|
),
|
||||||
|
'language' => array(
|
||||||
|
'title' => $this->l('Language'),
|
||||||
|
'width' => 60,
|
||||||
|
'type' => 'select',
|
||||||
|
'list' => $language_array,
|
||||||
|
'filter_key' => 'l!id_lang',
|
||||||
|
'filter_type' => 'int'
|
||||||
|
),
|
||||||
|
'status' => array(
|
||||||
|
'title' => $this->l('Status'),
|
||||||
|
'width' => 50,
|
||||||
|
'type' => 'select',
|
||||||
|
'list' => $status_array,
|
||||||
|
'icon' => $images_array,
|
||||||
|
'align' => 'center',
|
||||||
|
'filter_key' => 'a!status',
|
||||||
|
'filter_type' => 'string'
|
||||||
|
),
|
||||||
|
'employee' => array(
|
||||||
|
'title' => $this->l('Employee'),
|
||||||
|
'width' => 100,
|
||||||
|
'filter_key' => 'employee',
|
||||||
|
'tmpTableFilter' => true
|
||||||
|
),
|
||||||
|
'messages' => array(
|
||||||
|
'title' => $this->l('Messages'),
|
||||||
|
'width' => 50,
|
||||||
|
'filter_key' => 'messages',
|
||||||
|
'tmpTableFilter' => true,
|
||||||
|
'maxlength' => 0
|
||||||
|
),
|
||||||
|
'date_upd' => array(
|
||||||
|
'title' => $this->l('Last message'),
|
||||||
|
'width' => 90
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
|
||||||
|
|
||||||
$this->shopLinkType = 'shop';
|
$this->shopLinkType = 'shop';
|
||||||
|
|
||||||
$this->options = array(
|
$this->options = array(
|
||||||
'general' => array(
|
'general' => array(
|
||||||
'title' => $this->l('Customer service options'),
|
'title' => $this->l('Customer service options'),
|
||||||
'fields' => array(
|
'fields' => array(
|
||||||
'PS_SAV_IMAP_URL' => array('title' => $this->l('Imap url'), 'desc' => $this->l('Url for imap server (mail.server.com)'), 'type' => 'text', 'size' => 40, 'visibility' => Shop::CONTEXT_ALL),
|
'PS_SAV_IMAP_URL' => array(
|
||||||
'PS_SAV_IMAP_PORT' => array('title' => $this->l('Imap port'), 'desc' => $this->l('Port to use to connect imap server'), 'type' => 'text', 'defaultValue' => 143, 'visibility' => Shop::CONTEXT_ALL),
|
'title' => $this->l('Imap url'),
|
||||||
'PS_SAV_IMAP_USER' => array('title' => $this->l('Imap user'), 'desc' => $this->l('User to use to connect imap server'), 'type' => 'text', 'size' => 40, 'visibility' => Shop::CONTEXT_ALL),
|
'desc' => $this->l('Url for imap server (mail.server.com)'),
|
||||||
'PS_SAV_IMAP_PWD' => array('title' => $this->l('Imap password'), 'desc' => $this->l('Password to use to connect imap server'), 'type' => 'text', 'size' => 40, 'visibility' => Shop::CONTEXT_ALL),
|
'type' => 'text',
|
||||||
'PS_SAV_IMAP_SSL' => array('title' => $this->l('Imap use ssl'), 'type' => 'bool', 'visibility' => Shop::CONTEXT_ALL),
|
'size' => 40,
|
||||||
'PS_SAV_IMAP_DELETE_MSG' => array('title' => $this->l('Deletes messages'), 'desc' => $this->l('Deletes message after sync. If you do not active this option, the sync will be longer'), 'cast' => 'intval', 'type' => 'select', 'identifier' => 'value', 'list' => array(
|
'visibility' => Shop::CONTEXT_ALL
|
||||||
'0' => array('value' => 0, 'name' => $this->l('No')),
|
),
|
||||||
'1' => array('value' => 1, 'name' => $this->l('Yes'))
|
'PS_SAV_IMAP_PORT' => array(
|
||||||
), 'visibility' => Shop::CONTEXT_ALL)
|
'title' => $this->l('Imap port'),
|
||||||
|
'desc' => $this->l('Port to use to connect imap server'),
|
||||||
|
'type' => 'text',
|
||||||
|
'defaultValue' => 143,
|
||||||
|
'visibility' => Shop::CONTEXT_ALL
|
||||||
|
),
|
||||||
|
'PS_SAV_IMAP_USER' => array(
|
||||||
|
'title' => $this->l('Imap user'),
|
||||||
|
'desc' => $this->l('User to use to connect imap server'),
|
||||||
|
'type' => 'text',
|
||||||
|
'size' => 40,
|
||||||
|
'visibility' => Shop::CONTEXT_ALL
|
||||||
|
),
|
||||||
|
'PS_SAV_IMAP_PWD' => array(
|
||||||
|
'title' => $this->l('Imap password'),
|
||||||
|
'desc' => $this->l('Password to use to connect imap server'),
|
||||||
|
'type' => 'text',
|
||||||
|
'size' => 40,
|
||||||
|
'visibility' => Shop::CONTEXT_ALL
|
||||||
|
),
|
||||||
|
'PS_SAV_IMAP_SSL' => array(
|
||||||
|
'title' => $this->l('Imap use ssl'),
|
||||||
|
'type' => 'bool',
|
||||||
|
'visibility' => Shop::CONTEXT_ALL
|
||||||
|
),
|
||||||
|
'PS_SAV_IMAP_DELETE_MSG' => array(
|
||||||
|
'title' => $this->l('Deletes messages'),
|
||||||
|
'desc' => $this->l('Deletes message after sync. If you do not active this option, the sync will be longer'),
|
||||||
|
'cast' => 'intval',
|
||||||
|
'type' => 'select',
|
||||||
|
'identifier' => 'value',
|
||||||
|
'list' => array(
|
||||||
|
'0' => array('value' => 0, 'name' => $this->l('No')),
|
||||||
|
'1' => array('value' => 1, 'name' => $this->l('Yes'))
|
||||||
|
),
|
||||||
|
'visibility' => Shop::CONTEXT_ALL
|
||||||
|
)
|
||||||
),
|
),
|
||||||
'submit' => array('title' => $this->l(' Save '), 'class' => 'button')
|
'submit' => array('title' => $this->l(' Save '), 'class' => 'button')
|
||||||
),
|
),
|
||||||
@@ -107,69 +180,151 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderList()
|
||||||
|
{
|
||||||
|
$this->addRowAction('view');
|
||||||
|
$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,
|
||||||
|
(
|
||||||
|
SELECT IFNULL(CONCAT(LEFT(e.`firstname`, 1),". ",e.`lastname`), "--")
|
||||||
|
FROM `'._DB_PREFIX_.'customer_message` cm2
|
||||||
|
INNER JOIN '._DB_PREFIX_.'employee e
|
||||||
|
ON e.`id_employee` = cm2.`id_employee`
|
||||||
|
WHERE cm2.id_employee > 0
|
||||||
|
AND cm2.`id_customer_thread` = a.`id_customer_thread`
|
||||||
|
ORDER BY cm2.`date_add` DESC LIMIT 1
|
||||||
|
) as employee';
|
||||||
|
|
||||||
|
$this->_join = '
|
||||||
|
LEFT JOIN `'._DB_PREFIX_.'customer` c
|
||||||
|
ON c.`id_customer` = a.`id_customer`
|
||||||
|
LEFT JOIN `'._DB_PREFIX_.'customer_message` cm
|
||||||
|
ON cm.`id_customer_thread` = a.`id_customer_thread`
|
||||||
|
LEFT JOIN `'._DB_PREFIX_.'lang` l
|
||||||
|
ON l.`id_lang` = a.`id_lang`
|
||||||
|
LEFT JOIN `'._DB_PREFIX_.'contact_lang` cl
|
||||||
|
ON (cl.`id_contact` = a.`id_contact` AND cl.`id_lang` = '.(int)$this->context->language->id.')';
|
||||||
|
|
||||||
|
$this->_group = 'GROUP BY cm.id_customer_thread';
|
||||||
|
|
||||||
|
$contacts = CustomerThread::getContacts();
|
||||||
|
|
||||||
|
$categories = Contact::getCategoriesContacts();
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
$this->l('Total threads') => $all = CustomerThread::getTotalCustomerThreads(),
|
||||||
|
$this->l('Threads pending') => $pending = CustomerThread::getTotalCustomerThreads('status LIKE "%pending%"'),
|
||||||
|
$this->l('Total customer messages') => CustomerMessage::getTotalCustomerMessages('id_employee = 0'),
|
||||||
|
$this->l('Total employee messages') => CustomerMessage::getTotalCustomerMessages('id_employee != 0'),
|
||||||
|
$this->l('Threads unread') => $unread = CustomerThread::getTotalCustomerThreads('status = "open"'),
|
||||||
|
$this->l('Threads closed') => $all - ($unread + $pending)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->tpl_list_vars = array(
|
||||||
|
'contacts' => $contacts,
|
||||||
|
'categories' => $categories,
|
||||||
|
'params' => $params
|
||||||
|
);
|
||||||
|
|
||||||
|
return parent::renderList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initToolbar()
|
||||||
|
{
|
||||||
|
parent::initToolbar();
|
||||||
|
unset($this->toolbar_btn['new']);
|
||||||
|
}
|
||||||
|
|
||||||
public function postProcess()
|
public function postProcess()
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($id_customer_thread = (int)Tools::getValue('id_customer_thread'))
|
if ($id_customer_thread = (int)Tools::getValue('id_customer_thread'))
|
||||||
{
|
{
|
||||||
if (($id_contact = (int)Tools::getValue('id_contact')))
|
if (($id_contact = (int)Tools::getValue('id_contact')))
|
||||||
Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'customer_thread SET id_contact = '.(int)$id_contact.' WHERE id_customer_thread = '.(int)$id_customer_thread);
|
Db::getInstance()->execute('
|
||||||
|
UPDATE '._DB_PREFIX_.'customer_thread
|
||||||
|
SET id_contact = '.(int)$id_contact.'
|
||||||
|
WHERE id_customer_thread = '.(int)$id_customer_thread
|
||||||
|
);
|
||||||
if ($id_status = (int)Tools::getValue('setstatus'))
|
if ($id_status = (int)Tools::getValue('setstatus'))
|
||||||
{
|
{
|
||||||
$statusArray = array(1 => 'open', 2 => 'closed', 3 => 'pending1', 4 => 'pending2');
|
$status_array = array(1 => 'open', 2 => 'closed', 3 => 'pending1', 4 => 'pending2');
|
||||||
Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'customer_thread SET status = "'.$statusArray[$id_status].'" WHERE id_customer_thread = '.(int)$id_customer_thread.' LIMIT 1');
|
Db::getInstance()->execute('
|
||||||
|
UPDATE '._DB_PREFIX_.'customer_thread
|
||||||
|
SET status = "'.$status_array[$id_status].'"
|
||||||
|
WHERE id_customer_thread = '.(int)$id_customer_thread.' LIMIT 1
|
||||||
|
');
|
||||||
}
|
}
|
||||||
if (isset($_POST['id_employee_forward']))
|
if (isset($_POST['id_employee_forward']))
|
||||||
{
|
{
|
||||||
$messages = Db::getInstance()->executeS('
|
$messages = Db::getInstance()->executeS('
|
||||||
SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name, CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname
|
SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name,
|
||||||
FROM '._DB_PREFIX_.'customer_thread ct
|
CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname
|
||||||
LEFT JOIN '._DB_PREFIX_.'customer_message cm ON (ct.id_customer_thread = cm.id_customer_thread)
|
FROM '._DB_PREFIX_.'customer_thread ct
|
||||||
LEFT JOIN '._DB_PREFIX_.'contact_lang cl ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)$this->context->language->id.')
|
LEFT JOIN '._DB_PREFIX_.'customer_message cm
|
||||||
LEFT OUTER JOIN '._DB_PREFIX_.'employee e ON e.id_employee = cm.id_employee
|
ON (ct.id_customer_thread = cm.id_customer_thread)
|
||||||
LEFT OUTER JOIN '._DB_PREFIX_.'customer c ON (c.email = ct.email)
|
LEFT JOIN '._DB_PREFIX_.'contact_lang cl
|
||||||
WHERE ct.id_customer_thread = '.(int)Tools::getValue('id_customer_thread').'
|
ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)$this->context->language->id.')
|
||||||
ORDER BY cm.date_add DESC');
|
LEFT OUTER JOIN '._DB_PREFIX_.'employee e
|
||||||
|
ON e.id_employee = cm.id_employee
|
||||||
|
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
|
||||||
|
');
|
||||||
$output = '';
|
$output = '';
|
||||||
foreach ($messages AS $message)
|
foreach ($messages as $message)
|
||||||
$output .= $this->displayMsg($message, true, (int)Tools::getValue('id_employee_forward'));
|
$output .= $this->displayMessage($message, true, (int)Tools::getValue('id_employee_forward'));
|
||||||
|
|
||||||
$cm = new CustomerMessage();
|
$cm = new CustomerMessage();
|
||||||
$cm->id_employee = (int)$this->context->employee->id;
|
$cm->id_employee = (int)$this->context->employee->id;
|
||||||
$cm->id_customer_thread = (int)Tools::getValue('id_customer_thread');
|
$cm->id_customer_thread = (int)Tools::getValue('id_customer_thread');
|
||||||
$cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']);
|
$cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']);
|
||||||
$currentEmployee = $this->context->employee;
|
$current_employee = $this->context->employee;
|
||||||
if (($id_employee = (int)Tools::getValue('id_employee_forward')) AND ($employee = new Employee($id_employee)) AND Validate::isLoadedObject($employee))
|
$id_employee = (int)Tools::getValue('id_employee_forward');
|
||||||
|
$employee = new Employee($id_employee);
|
||||||
|
$email = Tools::getValue('email');
|
||||||
|
if ($id_employee && $employee && Validate::isLoadedObject($employee))
|
||||||
{
|
{
|
||||||
$params = array(
|
$params = array(
|
||||||
'{messages}' => $output,
|
'{messages}' => $output,
|
||||||
'{employee}' => $currentEmployee->firstname.' '.$currentEmployee->lastname,
|
'{employee}' => $current_employee->firstname.' '.$current_employee->lastname,
|
||||||
'{comment}' => stripslashes($_POST['message_forward']));
|
'{comment}' => stripslashes($_POST['message_forward']));
|
||||||
|
|
||||||
if (Mail::Send($this->context->language->id, 'forward_msg', Mail::l('Fwd: Customer message'), $params,
|
if (Mail::Send(
|
||||||
$employee->email, $employee->firstname.' '.$employee->lastname,
|
$this->context->language->id,
|
||||||
$currentEmployee->email, $currentEmployee->firstname.' '.$currentEmployee->lastname,
|
'forward_msg',
|
||||||
NULL, NULL, _PS_MAIL_DIR_, true))
|
Mail::l('Fwd: Customer message'),
|
||||||
|
$params,
|
||||||
|
$employee->email,
|
||||||
|
$employee->firstname.' '.$employee->lastname,
|
||||||
|
$current_employee->email,
|
||||||
|
$current_employee->firstname.' '.$current_employee->lastname,
|
||||||
|
null, null, _PS_MAIL_DIR_, true))
|
||||||
{
|
{
|
||||||
$cm->message = $this->l('Message forwarded to').' '.$employee->firstname.' '.$employee->lastname."\n".$this->l('Comment:').' '.$_POST['message_forward'];
|
$cm->message = $this->l('Message forwarded to').' '.$employee->firstname.' '.$employee->lastname."\n".$this->l('Comment:').' '.$_POST['message_forward'];
|
||||||
$cm->add();
|
$cm->add();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if ($email && Validate::isEmail($email))
|
||||||
elseif (($email = Tools::getValue('email')) AND Validate::isEmail($email))
|
|
||||||
{
|
{
|
||||||
$params = array(
|
$params = array(
|
||||||
'{messages}' => $output,
|
'{messages}' => $output,
|
||||||
'{employee}' => $currentEmployee->firstname.' '.$currentEmployee->lastname,
|
'{employee}' => $current_employee->firstname.' '.$current_employee->lastname,
|
||||||
'{comment}' => stripslashes($_POST['message_forward']));
|
'{comment}' => stripslashes($_POST['message_forward']));
|
||||||
|
|
||||||
if (Mail::Send((int)($cookie->id_lang), 'forward_msg', Mail::l('Fwd: Customer message'), $params,
|
if (Mail::Send(
|
||||||
$email, NULL,
|
(int)$cookie->id_lang,
|
||||||
$currentEmployee->email, $currentEmployee->firstname.' '.$currentEmployee->lastname,
|
'forward_msg',
|
||||||
NULL, NULL, _PS_MAIL_DIR_, true))
|
Mail::l('Fwd: Customer message'),
|
||||||
|
$params, $email, null,
|
||||||
|
$current_employee->email, $current_employee->firstname.' '.$current_employee->lastname,
|
||||||
|
null, null, _PS_MAIL_DIR_, true))
|
||||||
{
|
{
|
||||||
$cm->message = $this->l('Message forwarded to').' '.$email."\n".$this->l('Comment:').' '.$_POST['message_forward'];
|
$cm->message = $this->l('Message forwarded to').' '.$email."\n".$this->l('Comment:').' '.$_POST['message_forward'];
|
||||||
$cm->add();
|
$cm->add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
$this->_errors[] = '<div class="alert error">'.Tools::displayError('Email invalid.').'</div>';
|
$this->_errors[] = '<div class="alert error">'.Tools::displayError('Email invalid.').'</div>';
|
||||||
@@ -182,30 +337,38 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
$cm->id_customer_thread = $ct->id;
|
$cm->id_customer_thread = $ct->id;
|
||||||
$cm->message = Tools::htmlentitiesutf8(Tools::nl2br(Tools::getValue('reply_message')));
|
$cm->message = Tools::htmlentitiesutf8(Tools::nl2br(Tools::getValue('reply_message')));
|
||||||
$cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']);
|
$cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']);
|
||||||
if (isset($_FILES) AND !empty($_FILES['joinFile']['name']) AND $_FILES['joinFile']['error'] != 0)
|
if (isset($_FILES) && !empty($_FILES['joinFile']['name']) && $_FILES['joinFile']['error'] != 0)
|
||||||
$this->_errors[] = Tools::displayError('An error occurred with the file upload.');
|
$this->_errors[] = Tools::displayError('An error occurred with the file upload.');
|
||||||
else if ($cm->add())
|
else if ($cm->add())
|
||||||
{
|
{
|
||||||
$fileAttachment = NULL;
|
$file_attachment = null;
|
||||||
if (!empty($_FILES['joinFile']['name']))
|
if (!empty($_FILES['joinFile']['name']))
|
||||||
{
|
{
|
||||||
$fileAttachment['content'] = file_get_contents($_FILES['joinFile']['tmp_name']);
|
$file_attachment['content'] = file_get_contents($_FILES['joinFile']['tmp_name']);
|
||||||
$fileAttachment['name'] = $_FILES['joinFile']['name'];
|
$file_attachment['name'] = $_FILES['joinFile']['name'];
|
||||||
$fileAttachment['mime'] = $_FILES['joinFile']['type'];
|
$file_attachment['mime'] = $_FILES['joinFile']['type'];
|
||||||
}
|
}
|
||||||
$params = array(
|
$params = array(
|
||||||
'{reply}' => Tools::nl2br(Tools::getValue('reply_message')),
|
'{reply}' => Tools::nl2br(Tools::getValue('reply_message')),
|
||||||
'{link}' => Tools::url($this->context->link->getPageLink('contact', true), 'id_customer_thread='.(int)($ct->id).'&token='.$ct->token),
|
'{link}' => Tools::url(
|
||||||
|
$this->context->link->getPageLink('contact', true),
|
||||||
|
'id_customer_thread='.(int)$ct->id.'&token='.$ct->token
|
||||||
|
),
|
||||||
);
|
);
|
||||||
//#ct == id_customer_thread #tc == token of thread <== used in the synchronization imap
|
//#ct == id_customer_thread #tc == token of thread <== used in the synchronization imap
|
||||||
if (Mail::Send($ct->id_lang, 'reply_msg', Mail::l('An answer to your message is available').' #ct'.$ct->id.'#tc'.$ct->token,
|
if (Mail::Send(
|
||||||
$params, Tools::getValue('msg_email'), NULL, NULL, NULL, $fileAttachment, NULL,
|
$ct->id_lang,
|
||||||
|
'reply_msg',
|
||||||
|
Mail::l('An answer to your message is available').' #ct'.$ct->id.'#tc'.$ct->token,
|
||||||
|
$params, Tools::getValue('msg_email'), null, null, null, $file_attachment, null,
|
||||||
_PS_MAIL_DIR_, true))
|
_PS_MAIL_DIR_, true))
|
||||||
{
|
{
|
||||||
$ct->status = 'closed';
|
$ct->status = 'closed';
|
||||||
$ct->update();
|
$ct->update();
|
||||||
}
|
}
|
||||||
Tools::redirectAdmin(self::$currentIndex.'&id_customer_thread='.(int)$id_customer_thread.'&viewcustomer_thread&token='.Tools::getValue('token'));
|
Tools::redirectAdmin(
|
||||||
|
self::$currentIndex.'&id_customer_thread='.(int)$id_customer_thread.'&viewcustomer_thread&token='.Tools::getValue('token')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
$this->_errors[] = Tools::displayError('An error occurred, your message was not sent. Please contact your system administrator.');
|
$this->_errors[] = Tools::displayError('An error occurred, your message was not sent. Please contact your system administrator.');
|
||||||
@@ -217,86 +380,32 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
|
|
||||||
public function initContent()
|
public function initContent()
|
||||||
{
|
{
|
||||||
|
if (isset($_GET['filename']) && file_exists(_PS_UPLOAD_DIR_.$_GET['filename']))
|
||||||
if (isset($_GET['filename']) AND file_exists(_PS_UPLOAD_DIR_.$_GET['filename']))
|
|
||||||
self::openUploadedFile();
|
self::openUploadedFile();
|
||||||
|
|
||||||
return parent::initContent();
|
return parent::initContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function displayListHeader($token = NULL)
|
|
||||||
{
|
|
||||||
$content = '';
|
|
||||||
$contacts = Db::getInstance()->executeS('
|
|
||||||
SELECT cl.*, COUNT(*) as total, (
|
|
||||||
SELECT id_customer_thread
|
|
||||||
FROM '._DB_PREFIX_.'customer_thread ct2
|
|
||||||
WHERE status = "open" AND ct.id_contact = ct2.id_contact
|
|
||||||
ORDER BY date_upd ASC
|
|
||||||
LIMIT 1
|
|
||||||
) as id_customer_thread
|
|
||||||
FROM '._DB_PREFIX_.'customer_thread ct
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'contact_lang cl ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)$this->context->language->id.')
|
|
||||||
WHERE ct.status = "open"
|
|
||||||
GROUP BY ct.id_contact HAVING COUNT(*) > 0');
|
|
||||||
$categories = Db::getInstance()->executeS('
|
|
||||||
SELECT cl.*
|
|
||||||
FROM '._DB_PREFIX_.'contact ct
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'contact_lang cl ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)$this->context->language->id.')
|
|
||||||
WHERE ct.customer_service = 1');
|
|
||||||
$dim = count($categories);
|
|
||||||
|
|
||||||
$content .= '<div style="float:left;border:0;width:640px;">';
|
|
||||||
foreach ($categories as $key => $val)
|
|
||||||
{
|
|
||||||
$totalThread = 0;
|
|
||||||
$id_customer_thread = 0;
|
|
||||||
foreach ($contacts as $tmp => $tmp2)
|
|
||||||
if ($val['id_contact'] == $tmp2['id_contact'])
|
|
||||||
{
|
|
||||||
$totalThread = $tmp2['total'];
|
|
||||||
$id_customer_thread = $tmp2['id_customer_thread'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$content .= '<div style="background-color:#EFEFEF;float:left;margin:0 10px 10px 0;width:'.($dim > 6 ? '200' : '300').'px;border:1px solid #CFCFCF" >
|
|
||||||
<h3 style="overflow:hidden;line-height:25px;color:#812143;height:25px;margin:0;"> '.$val['name'].'</h3>'.
|
|
||||||
($dim > 6 ? '' : '<p style="overflow:hidden;line-height:15px;height:45px;margin:0;padding:0 5px;">'.$val['description'].'</p>').
|
|
||||||
($totalThread == 0 ? '<h3 style="padding:0 5px;margin:0;height:23px;line-height:23px;background-color:#DEDEDE">'.$this->l('No new message').'</h3>'
|
|
||||||
: '<a href="'.self::$currentIndex.'&token='.Tools::getValue('token').'&id_customer_thread='.$id_customer_thread.'&viewcustomer_thread" style="padding:0 5px;display:block;height:23px;line-height:23px;border:0;" class="button">'.$totalThread.' '.($totalThread > 1 ? $this->l('new messages'): $this->l('new message')).'</a>').'
|
|
||||||
</div>';
|
|
||||||
}
|
|
||||||
$content .= '</div>';
|
|
||||||
|
|
||||||
$params = array(
|
|
||||||
$this->l('Total threads') => $all = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'customer_thread'),
|
|
||||||
$this->l('Threads pending') => $pending = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'customer_thread WHERE status LIKE "%pending%"'),
|
|
||||||
$this->l('Total customer messages') => Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'customer_message WHERE id_employee = 0'),
|
|
||||||
$this->l('Total employee messages') => Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'customer_message WHERE id_employee != 0'),
|
|
||||||
$this->l('Threads unread') => $unread = Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'customer_thread WHERE status = "open"'),
|
|
||||||
$this->l('Threads closed') => $all - ($unread + $pending));
|
|
||||||
|
|
||||||
$content .= '<div style="float:right;padding 0px;border:1px solid #CFCFCF;width:280px;">
|
|
||||||
<h3 class="button" style="margin:0;line-height:23px;height:23px;border:0;padding:0 5px;">'.$this->l('Customer service').' : '.$this->l('Statistics').'</h3>
|
|
||||||
<table cellspacing="1" class="table" style="border-collapse:separate;width:280px;border:0">';
|
|
||||||
$count = 0;
|
|
||||||
foreach ($params as $key => $val)
|
|
||||||
$content .= '<tr '.(++$count % 2 == 0 ? 'class="alt_row"' : '').'><td>'.$key.'</td><td>'.$val.'</td></tr>';
|
|
||||||
$content .= ' </table>
|
|
||||||
</div><p class="clear"> </p>';
|
|
||||||
$this->content .= $content;
|
|
||||||
return parent::displayListHeader($token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function openUploadedFile()
|
private function openUploadedFile()
|
||||||
{
|
{
|
||||||
$filename = $_GET['filename'];
|
$filename = $_GET['filename'];
|
||||||
|
|
||||||
$extensions = array('.txt' => 'text/plain', '.rtf' => 'application/rtf', '.doc' => 'application/msword', '.docx'=> 'application/msword',
|
$extensions = array(
|
||||||
'.pdf' => 'application/pdf', '.zip' => 'multipart/x-zip', '.png' => 'image/png', '.jpeg' => 'image/jpeg', '.gif' => 'image/gif', '.jpg' => 'image/jpeg');
|
'.txt' => 'text/plain',
|
||||||
|
'.rtf' => 'application/rtf',
|
||||||
|
'.doc' => 'application/msword',
|
||||||
|
'.docx'=> 'application/msword',
|
||||||
|
'.pdf' => 'application/pdf',
|
||||||
|
'.zip' => 'multipart/x-zip',
|
||||||
|
'.png' => 'image/png',
|
||||||
|
'.jpeg' => 'image/jpeg',
|
||||||
|
'.gif' => 'image/gif',
|
||||||
|
'.jpg' => 'image/jpeg'
|
||||||
|
);
|
||||||
|
|
||||||
$extension = '';
|
$extension = '';
|
||||||
foreach ($extensions AS $key => $val)
|
foreach ($extensions as $key => $val)
|
||||||
if (substr($filename, -4) == $key OR substr($filename, -5) == $key)
|
if (substr($filename, -4) == $key || substr($filename, -5) == $key)
|
||||||
{
|
{
|
||||||
$extension = $val;
|
$extension = $val;
|
||||||
break;
|
break;
|
||||||
@@ -308,314 +417,148 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
readfile(_PS_UPLOAD_DIR_.$filename);
|
readfile(_PS_UPLOAD_DIR_.$filename);
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
private function displayMsg($message, $email = false, $id_employee = null)
|
|
||||||
{
|
|
||||||
$customersToken = Tools::getAdminToken('AdminCustomers'.(int)(Tab::getIdFromClassName('AdminCustomers')).(int)$this->context->employee->id);
|
|
||||||
$contacts = Contact::getContacts($this->context->language->id);
|
|
||||||
|
|
||||||
if (!$email)
|
|
||||||
{
|
|
||||||
if (!empty($message['id_product']) AND empty($message['employee_name']))
|
|
||||||
$id_order_product = Db::getInstance()->getValue('
|
|
||||||
SELECT o.id_order
|
|
||||||
FROM '._DB_PREFIX_.'orders o
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'order_detail od ON o.id_order = od.id_order
|
|
||||||
WHERE o.id_customer = '.(int)$message['id_customer'].'
|
|
||||||
AND od.product_id = '.(int)$message['id_product'].'
|
|
||||||
ORDER BY o.date_add DESC');
|
|
||||||
|
|
||||||
$output = '
|
|
||||||
<fieldset style="'.(!empty($message['employee_name']) ? 'background: rgb(255,236,242);' : '').'width:600px;margin-top:10px">
|
|
||||||
<legend '.(empty($message['employee_name']) ? '' : 'style="background:rgb(255,210,225)"').'>'.(
|
|
||||||
!empty($message['employee_name'])
|
|
||||||
? '<img src="../img/t/AdminCustomers.gif" alt="'.Configuration::get('PS_SHOP_NAME').'" /> '.Configuration::get('PS_SHOP_NAME').' - '.$message['employee_name']
|
|
||||||
: '<img src="'.__PS_BASE_URI__.'img/admin/tab-customers.gif" alt="'.Configuration::get('PS_SHOP_NAME').'" /> '.(
|
|
||||||
!empty($message['id_customer'])
|
|
||||||
? '<a href="index.php?tab=AdminCustomers&id_customer='.(int)($message['id_customer']).'&viewcustomer&token='.$customersToken.'" title="'.$this->l('View customer').'">'.$message['customer_name'].'</a>'
|
|
||||||
: $message['email']
|
|
||||||
)
|
|
||||||
).'</legend>
|
|
||||||
<div style="font-size:11px">'.(
|
|
||||||
(!empty($message['id_customer']) AND empty($message['employee_name']))
|
|
||||||
? '<b>'.$this->l('Customer ID:').'</b> <a href="index.php?tab=AdminCustomers&id_customer='.(int)($message['id_customer']).'&viewcustomer&token='.$customersToken.'" title="'.$this->l('View customer').'">'.(int)($message['id_customer']).' <img src="../img/admin/search.gif" alt="'.$this->l('view').'" /></a><br />'
|
|
||||||
: ''
|
|
||||||
).'
|
|
||||||
<b>'.$this->l('Sent on:').'</b> '.Tools::displayDate($message['date_add'], $this->context->language->id, true).'<br />'.(
|
|
||||||
empty($message['employee_name'])
|
|
||||||
? '<b>'.$this->l('Browser:').'</b> '.strip_tags($message['user_agent']).'<br />'
|
|
||||||
: ''
|
|
||||||
).(
|
|
||||||
(!empty($message['file_name']) AND file_exists(_PS_UPLOAD_DIR_.$message['file_name']))
|
|
||||||
? '<b>'.$this->l('File attachment').'</b> <a href="index.php?tab=AdminCustomerThreads&id_customer_thread='.$message['id_customer_thread'].'&viewcustomer_thread&token='.Tools::getAdminToken('AdminCustomerThreads'.(int)(Tab::getIdFromClassName('AdminCustomerThreads')).(int)$this->context->employee->id).'&filename='.$message['file_name'].'" title="'.$this->l('View file').'"><img src="../img/admin/search.gif" alt="'.$this->l('view').'" /></a><br />'
|
|
||||||
: ''
|
|
||||||
).(
|
|
||||||
(!empty($message['id_order']) AND empty($message['employee_name']))
|
|
||||||
? '<b>'.$this->l('Order #').'</b> <a href="index.php?tab=AdminOrders&id_order='.(int)($message['id_order']).'&vieworder&token='.Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)$this->context->employee->id).'" title="'.$this->l('View order').'">'.(int)($message['id_order']).' <img src="../img/admin/search.gif" alt="'.$this->l('view').'" /></a><br />'
|
|
||||||
: ''
|
|
||||||
).(
|
|
||||||
(!empty($message['id_product']) AND empty($message['employee_name']))
|
|
||||||
? '<b>'.$this->l('Product #').'</b> <a href="index.php?tab=AdminOrders&id_order='.(int)($id_order_product).'&vieworder&token='.Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)$this->context->employee->id).'" title="'.$this->l('View order').'">'.(int)($message['id_product']).' <img src="../img/admin/search.gif" alt="'.$this->l('view').'" /></a><br />'
|
|
||||||
: ''
|
|
||||||
).'<br />
|
|
||||||
<form action="'.Tools::htmlentitiesutf8($_SERVER['REQUEST_URI']).'" method="post">
|
|
||||||
<b>'.$this->l('Subject:').'</b>
|
|
||||||
<input type="hidden" name="id_customer_message" value="'.$message['id_customer_message'].'" />
|
|
||||||
<select name="id_contact" onchange="this.form.submit();">';
|
|
||||||
foreach ($contacts as $contact)
|
|
||||||
$output .= '<option value="'.(int)$contact['id_contact'].'" '.($contact['id_contact'] == $message['id_contact'] ? 'selected="selected"' : '').'>'.Tools::htmlentitiesutf8($contact['name']).'</option>';
|
|
||||||
$output .= '</select>
|
|
||||||
</form>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$output = '<div style="font-size:11px">
|
|
||||||
'.($id_employee ? '<a href="'.Tools::getHttpHost(true).self::$currentIndex.'&token='.Tools::getAdminToken('AdminCustomerThreads'.(int)(Tab::getIdFromClassName('AdminCustomerThreads')).(int)($id_employee)).'&id_customer_thread='.(int)$message['id_customer_thread'].'&viewcustomer_thread">'.$this->l('View this thread').'</a><br />' : '').'
|
|
||||||
<b>'.$this->l('Sent by:').'</b> '.(!empty($message['customer_name']) ? $message['customer_name'].' ('.$message['email'].')' : $message['email'])
|
|
||||||
.((!empty($message['id_customer']) AND empty($message['employee_name'])) ? '<br /><b>'.$this->l('Customer ID:').'</b> '.(int)($message['id_customer']).'<br />' : '')
|
|
||||||
.((!empty($message['id_order']) AND empty($message['employee_name'])) ? '<br /><b>'.$this->l('Order #').':</b> '.(int)($message['id_order']).'<br />' : '')
|
|
||||||
.((!empty($message['id_product']) AND empty($message['employee_name'])) ? '<br /><b>'.$this->l('Product #').':</b> '.(int)($message['id_product']).'<br />' : '')
|
|
||||||
.'<br /><b>'.$this->l('Subject:').'</b> '.$message['subject'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$message['message'] = preg_replace('/(https?:\/\/[a-z0-9#%&_=\(\)\.\? \+\-@\/]{6,1000})([\s\n<])/Uui', '<a href="\1">\1</a>\2', html_entity_decode($message['message'], ENT_NOQUOTES, 'UTF-8'));
|
|
||||||
$output .= '<br /><br />
|
|
||||||
<b>'.$this->l('Thread ID:').'</b> '.(int)$message['id_customer_thread'].'<br />
|
|
||||||
<b>'.$this->l('Message ID:').'</b> '.(int)$message['id_customer_message'].'<br />
|
|
||||||
<b>'.$this->l('Message:').'</b><br />
|
|
||||||
'.$message['message'].'
|
|
||||||
</div>';
|
|
||||||
|
|
||||||
if (!$email)
|
|
||||||
{
|
|
||||||
if (empty($message['employee_name']))
|
|
||||||
$output .= '
|
|
||||||
<p style="text-align:right">
|
|
||||||
<button style="font-family: Verdana; font-size: 11px; font-weight:bold; height: 65px; width: 120px;" onclick="$(\'#reply_to_'.(int)($message['id_customer_message']).'\').show(500); $(this).hide();">
|
|
||||||
<img src="'.__PS_BASE_URI__.'img/admin/contact.gif" alt="" style="margin-bottom: 5px;" /><br />'.$this->l('Reply to this message').'
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
<div id="reply_to_'.(int)($message['id_customer_message']).'" style="display: none; margin-top: 20px;"">
|
|
||||||
<form action="'.Tools::htmlentitiesutf8($_SERVER['REQUEST_URI']).'" method="post" enctype="multipart/form-data">
|
|
||||||
<p>'.$this->l('Please type your reply below:').'</p>
|
|
||||||
<textarea style="width: 450px; height: 175px;" name="reply_message">'.str_replace('\r\n', "\n", Configuration::get('PS_CUSTOMER_SERVICE_SIGNATURE', $message['id_lang'])).'</textarea>
|
|
||||||
<div style="width: 450px; text-align: right; font-style: italic; font-size: 9px; margin-top: 2px;">
|
|
||||||
'.$this->l('Your reply will be sent to:').' '.$message['email'].'
|
|
||||||
</div>
|
|
||||||
<div style="width: 450px; margin-top: 0px;">
|
|
||||||
<input type="file" name="joinFile"/>
|
|
||||||
<div>
|
|
||||||
<div style="width: 450px; text-align: center;">
|
|
||||||
<input type="submit" class="button" name="submitReply" value="'.$this->l('Send my reply').'" style="margin-top:20px;" />
|
|
||||||
<input type="hidden" name="id_customer_thread" value="'.(int)($message['id_customer_thread']).'" />
|
|
||||||
<input type="hidden" name="msg_email" value="'.$message['email'].'" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>';
|
|
||||||
$output .= '
|
|
||||||
</fieldset>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function renderView()
|
public function renderView()
|
||||||
{
|
{
|
||||||
$content = '';
|
if (!$id_customer_thread = (int)Tools::getValue('id_customer_thread'))
|
||||||
$this->toolbar_title = $this->l('Customer Threads');
|
return;
|
||||||
|
|
||||||
$this->context = Context::getContext();
|
$this->context = Context::getContext();
|
||||||
if (!($thread = $this->loadObject()))
|
if (!($thread = $this->loadObject()))
|
||||||
return;
|
return;
|
||||||
$this->context->cookie->{'customer_threadFilter_cl!id_contact'} = $thread->id_contact;
|
$this->context->cookie->{'customer_threadFilter_cl!id_contact'} = $thread->id_contact;
|
||||||
|
|
||||||
$employees = Db::getInstance()->executeS('
|
$employees = Employee::getEmployees();
|
||||||
SELECT e.id_employee, e.firstname, e.lastname FROM '._DB_PREFIX_.'employee e
|
|
||||||
WHERE e.active = 1 ORDER BY e.lastname ASC');
|
|
||||||
|
|
||||||
$content .= '
|
$messages = CustomerThread::getMessageCustomerThreads($id_customer_thread);
|
||||||
<h2>'.$this->l('Messages').'</h2>
|
|
||||||
<form action="'.Tools::htmlentitiesUTF8($_SERVER['REQUEST_URI']).'" method="post" enctype="multipart/form-data">
|
|
||||||
<p>
|
|
||||||
<img src="../img/admin/msg-forward.png" alt="" style="vertical-align: middle;" /> '.$this->l('Forward this discussion to an employee:').'
|
|
||||||
<select name="id_employee_forward" style="vertical-align: middle;" onchange="
|
|
||||||
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);
|
|
||||||
">
|
|
||||||
<option value="-1">'.$this->l('-- Choose --').'</option>
|
|
||||||
<option value="0">'.$this->l('Someone else').'</option>';
|
|
||||||
foreach ($employees AS $employee)
|
|
||||||
$content .= ' <option value="'.(int)($employee['id_employee']).'">'.substr($employee['firstname'], 0, 1).'. '.$employee['lastname'].'</option>';
|
|
||||||
$content .= ' </select>
|
|
||||||
<div id="message_forward_email" style="display:none">
|
|
||||||
<b>'.$this->l('E-mail').'</b> <input type="text" name="email" />
|
|
||||||
</div>
|
|
||||||
<div id="message_forward" style="display:none;margin-bottom:10px">
|
|
||||||
<textarea name="message_forward" style="width: 500px; height: 80px; margin-top: 15px;" onclick="if ($(this).val() == \''.addslashes($this->l('You can add a comment here.')).'\') { $(this).val(\'\'); }">'.$this->l('You can add a comment here.').'</textarea><br />
|
|
||||||
<input type="Submit" name="submitForward" class="button" value="'.$this->l('Forward this discussion').'" style="margin-top: 10px;" />
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
<div class="clear"> </div>';
|
|
||||||
|
|
||||||
$messages = Db::getInstance()->executeS('
|
$next_thread = CustomerThread::getNextThread((int)$thread->id);
|
||||||
SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name, CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname
|
|
||||||
FROM '._DB_PREFIX_.'customer_thread ct
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'customer_message cm ON (ct.id_customer_thread = cm.id_customer_thread)
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'contact_lang cl ON (cl.id_contact = ct.id_contact AND cl.id_lang = '.(int)$this->context->language->id.')
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'employee e ON e.id_employee = cm.id_employee
|
|
||||||
LEFT JOIN '._DB_PREFIX_.'customer c ON (IFNULL(ct.id_customer, ct.email) = IFNULL(c.id_customer, c.email))
|
|
||||||
WHERE ct.id_customer_thread = '.(int)Tools::getValue('id_customer_thread').'
|
|
||||||
ORDER BY cm.date_add DESC');
|
|
||||||
|
|
||||||
$content .= '<div style="float:right">';
|
$actions = array();
|
||||||
|
|
||||||
$nextThread = Db::getInstance()->getValue('
|
if ($next_thread)
|
||||||
SELECT id_customer_thread FROM '._DB_PREFIX_.'customer_thread ct
|
$actions['next_thread'] = array(
|
||||||
WHERE ct.status = "open" AND ct.date_upd = (
|
'href' => self::$currentIndex.'&id_customer_thread='.(int)$next_thread.'&viewcustomer_thread&token='.$this->token,
|
||||||
SELECT date_add FROM '._DB_PREFIX_.'customer_message
|
'name' => $this->l('Answer to the next unanswered message in this category')
|
||||||
WHERE (id_employee IS NULL OR id_employee = 0) AND id_customer_thread = '.(int)$thread->id.'
|
);
|
||||||
ORDER BY date_add DESC LIMIT 1
|
|
||||||
)
|
|
||||||
'.($this->context->cookie->{'customer_threadFilter_cl!id_contact'} ? 'AND ct.id_contact = '.(int)$this->context->cookie->{'customer_threadFilter_cl!id_contact'} : '').'
|
|
||||||
'.($this->context->cookie->{'customer_threadFilter_l!id_lang'} ? 'AND ct.id_lang = '.(int)$this->context->cookie->{'customer_threadFilter_l!id_lang'} : '').
|
|
||||||
' ORDER BY ct.date_upd ASC');
|
|
||||||
|
|
||||||
if ($nextThread)
|
|
||||||
$content .= $this->displayButton('
|
|
||||||
<a href="'.self::$currentIndex.'&id_customer_thread='.(int)$nextThread.'&viewcustomer_thread&token='.$this->token.'">
|
|
||||||
<img src="../img/admin/next-msg.png" title="'.$this->l('Go to the oldest next unanswered message').'" style="margin-bottom: 10px;" />
|
|
||||||
<br />'.$this->l('Answer to the next unanswered message in this category').' >
|
|
||||||
</a>');
|
|
||||||
else
|
else
|
||||||
$content .= $this->displayButton('
|
$actions['next_thread'] = array(
|
||||||
<img src="../img/admin/msg-ok.png" title="'.$this->l('Go to the oldest next unanswered message').'" style="margin-bottom: 10px;" />
|
'href' => false,
|
||||||
<br />'.$this->l('The other messages in this category have been answered'));
|
'name' => $this->l('The other messages in this category have been answered')
|
||||||
|
);
|
||||||
|
|
||||||
if ($thread->status != "closed")
|
if ($thread->status != 'closed')
|
||||||
$content .= $this->displayButton('
|
$actions['closed'] = array(
|
||||||
<a href="'.self::$currentIndex.'&viewcustomer_thread&setstatus=2&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token.'">
|
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=2&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||||
<img src="../img/admin/msg-ok.png" style="margin-bottom:10px" />
|
'name' => $this->l('Set this message as handled')
|
||||||
<br />'.$this->l('Set this message as handled').'
|
);
|
||||||
</a>');
|
|
||||||
|
|
||||||
if ($thread->status != "pending1")
|
if ($thread->status != 'pending1')
|
||||||
$content .= $this->displayButton('
|
$actions['pending1'] = array(
|
||||||
<a href="'.self::$currentIndex.'&viewcustomer_thread&setstatus=3&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token.'">
|
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=3&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||||
<img src="../img/admin/msg-pending.png" style="margin-bottom:10px" />
|
'name' => $this->l('Declare this message as "pending 1" (will be answered later)')
|
||||||
<br />'.$this->l('Declare this message').'<br />'.$this->l('as "pending 1"').'<br />'.$this->l('(will be answered later)').'
|
);
|
||||||
</a>');
|
|
||||||
else
|
else
|
||||||
$content .= $this->displayButton('
|
$actions['pending1'] = array(
|
||||||
<a href="'.self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token.'">
|
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||||
<img src="../img/admin/msg-is-pending.png" style="margin-bottom:10px" />
|
'name' => $this->l('Disable pending status')
|
||||||
<br />'.$this->l('Click here to disable pending status').'
|
);
|
||||||
</a>');
|
|
||||||
|
|
||||||
if ($thread->status != "pending2")
|
if ($thread->status != 'pending2')
|
||||||
$content .= $this->displayButton('
|
$actions['pending2'] = array(
|
||||||
<a href="'.self::$currentIndex.'&viewcustomer_thread&setstatus=4&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token.'">
|
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=4&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||||
<img src="../img/admin/msg-pending.png" style="margin-bottom:10px" />
|
'name' => $this->l('Declare this message as "pending 2" (will be answered later)')
|
||||||
<br />'.$this->l('Declare this message').'<br />'.$this->l('as "pending 2"').'<br />'.$this->l('(will be answered later)').'
|
);
|
||||||
</a>');
|
|
||||||
else
|
else
|
||||||
$content .= $this->displayButton('
|
$actions['pending2'] = array(
|
||||||
<a href="'.self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token.'">
|
'href' => self::$currentIndex.'&viewcustomer_thread&setstatus=1&id_customer_thread='.Tools::getValue('id_customer_thread').'&viewmsg&token='.$this->token,
|
||||||
<img src="../img/admin/msg-is-pending.png" style="margin-bottom:10px" />
|
'name' => $this->l('Disable pending status')
|
||||||
<br />'.$this->l('Click here to disable pending status').'
|
);
|
||||||
</a>');
|
|
||||||
|
|
||||||
$content .= '</div>';
|
|
||||||
|
|
||||||
if ($thread->id_customer)
|
if ($thread->id_customer)
|
||||||
{
|
{
|
||||||
$customer = new Customer($thread->id_customer);
|
$customer = new Customer($thread->id_customer);
|
||||||
$products = $customer->getBoughtProducts();
|
|
||||||
$orders = Order::getCustomerOrders($customer->id);
|
$orders = Order::getCustomerOrders($customer->id);
|
||||||
|
if ($orders && count($orders))
|
||||||
$content .= '<div style="float:left;width:600px">';
|
|
||||||
if ($orders AND sizeof($orders))
|
|
||||||
{
|
{
|
||||||
$totalOK = 0;
|
$total_ok = 0;
|
||||||
$ordersOK = array();
|
$orders_ok = array();
|
||||||
$tokenOrders = Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)$this->context->employee->id);
|
foreach ($orders as $key => $order)
|
||||||
foreach ($orders as $order)
|
{
|
||||||
if ($order['valid'])
|
if ($order['valid'])
|
||||||
{
|
{
|
||||||
$ordersOK[] = $order;
|
$orders_ok[] = $order;
|
||||||
$totalOK += $order['total_paid_real'];
|
$total_ok += $order['total_paid_real'];
|
||||||
}
|
}
|
||||||
if ($countOK = sizeof($ordersOK))
|
$orders[$key]['date_add'] = Tools::displayDate($order['date_add'], $this->context->language->id);
|
||||||
{
|
$orders[$key]['total_paid_real'] = Tools::displayPrice($order['total_paid_real'], new Currency((int)$order['id_currency']));
|
||||||
$content .= '<div style="float:left;margin-right:20px;">
|
|
||||||
<h2>'.$this->l('Orders').'</h2>
|
|
||||||
<table cellspacing="0" cellpadding="0" class="table float">
|
|
||||||
<tr>
|
|
||||||
<th class="center">'.$this->l('ID').'</th>
|
|
||||||
<th class="center">'.$this->l('Date').'</th>
|
|
||||||
<th class="center">'.$this->l('Products').'</th>
|
|
||||||
<th class="center">'.$this->l('Total paid').'</th>
|
|
||||||
<th class="center">'.$this->l('Payment').'</th>
|
|
||||||
<th class="center">'.$this->l('State').'</th>
|
|
||||||
<th class="center">'.$this->l('Actions').'</th>
|
|
||||||
</tr>';
|
|
||||||
$irow = 0;
|
|
||||||
foreach ($ordersOK AS $order)
|
|
||||||
$content .= '<tr '.($irow++ % 2 ? 'class="alt_row"' : '').' style="cursor: pointer" onclick="document.location = \'?tab=AdminOrders&id_order='.$order['id_order'].'&vieworder&token='.$tokenOrders.'\'">
|
|
||||||
<td class="center">'.$order['id_order'].'</td>
|
|
||||||
<td>'.Tools::displayDate($order['date_add'], $this->context->language->id).'</td>
|
|
||||||
<td align="right">'.$order['nb_products'].'</td>
|
|
||||||
<td align="right">'.Tools::displayPrice($order['total_paid_real'], new Currency((int)($order['id_currency']))).'</td>
|
|
||||||
<td>'.$order['payment'].'</td>
|
|
||||||
<td>'.$order['order_state'].'</td>
|
|
||||||
<td align="center"><a href="?tab=AdminOrders&id_order='.$order['id_order'].'&vieworder&token='.$tokenOrders.'"><img src="../img/admin/details.gif" /></a></td>
|
|
||||||
</tr>';
|
|
||||||
$content .= '</table>
|
|
||||||
<h3 style="color:green;font-weight:700;margin-top:10px">'.$this->l('Validated Orders:').' '.$countOK.' '.$this->l('for').' '.Tools::displayPrice($totalOK, $this->context->currency).'</h3>
|
|
||||||
</div>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($products AND sizeof($products))
|
|
||||||
{
|
$products = $customer->getBoughtProducts();
|
||||||
$content .= '<div style="float:left;margin-right:20px">
|
if ($products && count($products))
|
||||||
<h2>'.$this->l('Products').'</h2>
|
foreach ($products as $key => $product)
|
||||||
<table cellspacing="0" cellpadding="0" class="table">
|
$products[$key]['date_add'] = Tools::displayDate($product['date_add'], $this->context->language->id, true);
|
||||||
<tr>
|
|
||||||
<th class="center">'.$this->l('Date').'</th>
|
|
||||||
<th class="center">'.$this->l('ID').'</th>
|
|
||||||
<th class="center">'.$this->l('Name').'</th>
|
|
||||||
<th class="center">'.$this->l('Quantity').'</th>
|
|
||||||
<th class="center">'.$this->l('Actions').'</th>
|
|
||||||
</tr>';
|
|
||||||
$irow = 0;
|
|
||||||
$tokenOrders = Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)$this->context->employee->id);
|
|
||||||
foreach ($products AS $product)
|
|
||||||
$content .= '
|
|
||||||
<tr '.($irow++ % 2 ? 'class="alt_row"' : '').' style="cursor: pointer" onclick="document.location = \'?tab=AdminOrders&id_order='.$product['id_order'].'&vieworder&token='.$tokenOrders.'\'">
|
|
||||||
<td>'.Tools::displayDate($product['date_add'], $this->context->language->id, true).'</td>
|
|
||||||
<td>'.$product['product_id'].'</td>
|
|
||||||
<td>'.$product['product_name'].'</td>
|
|
||||||
<td align="right">'.$product['product_quantity'].'</td>
|
|
||||||
<td align="center"><a href="?tab=AdminOrders&id_order='.$product['id_order'].'&vieworder&token='.$tokenOrders.'"><img src="../img/admin/details.gif" /></a></td>
|
|
||||||
</tr>';
|
|
||||||
$content .= '</table></div>';
|
|
||||||
}
|
|
||||||
$content .= '</div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$content .= '<div style="float:left;margin-top:10px">';
|
foreach ($messages as $key => $message)
|
||||||
foreach ($messages AS $message)
|
$messages[$key] = $this->displayMessage($message);
|
||||||
$content .= $this->displayMsg($message);
|
|
||||||
$content .= '</div><div class="clear"> </div>';
|
$this->tpl_view_vars = array(
|
||||||
|
'id_customer_thread' => $id_customer_thread,
|
||||||
|
'thread' => $thread,
|
||||||
|
'actions' => $actions,
|
||||||
|
'employees' => $employees,
|
||||||
|
'messages' => $messages,
|
||||||
|
'next_thread' => $next_thread,
|
||||||
|
'orders' => isset($orders) ? $orders : false,
|
||||||
|
'customer' => isset($customer) ? $customer : false,
|
||||||
|
'products' => isset($products) ? $products : false,
|
||||||
|
'total_ok' => isset($total_ok) ? Tools::displayPrice($total_ok, $this->context->currency) : false,
|
||||||
|
'orders_ok' => isset($orders_ok) ? $orders_ok : false,
|
||||||
|
'count_ok' => isset($orders_ok) ? count($orders_ok) : false
|
||||||
|
);
|
||||||
|
|
||||||
$this->content = $content;
|
|
||||||
return parent::renderView();
|
return parent::renderView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function displayMessage($message, $email = false, $id_employee = null)
|
||||||
|
{
|
||||||
|
$tpl = $this->context->smarty->createTemplate($this->tpl_folder.'message.tpl');
|
||||||
|
|
||||||
|
$contacts = Contact::getContacts($this->context->language->id);
|
||||||
|
|
||||||
|
if (!$email)
|
||||||
|
{
|
||||||
|
if (!empty($message['id_product']) && empty($message['employee_name']))
|
||||||
|
$id_order_product = Order::getIdOrderProduct((int)$message['id_customer'], (int)$message['id_product']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$message['date_add'] = Tools::displayDate($message['date_add'], $this->context->language->id, true);
|
||||||
|
$message['user_agent'] = strip_tags($message['user_agent']);
|
||||||
|
$message['message'] = preg_replace(
|
||||||
|
'/(https?:\/\/[a-z0-9#%&_=\(\)\.\? \+\-@\/]{6,1000})([\s\n<])/Uui',
|
||||||
|
'<a href="\1">\1</a>\2',
|
||||||
|
html_entity_decode($message['message'],
|
||||||
|
ENT_NOQUOTES, 'UTF-8')
|
||||||
|
);
|
||||||
|
|
||||||
|
$tpl->assign(array(
|
||||||
|
'current' => self::$currentIndex,
|
||||||
|
'token' => $this->token,
|
||||||
|
'message' => $message,
|
||||||
|
'id_order_product' => isset($id_order_product) ? $id_order_product : null,
|
||||||
|
'email' => $email,
|
||||||
|
'id_employee' => $id_employee,
|
||||||
|
'PS_SHOP_NAME' => Configuration::get('PS_SHOP_NAME'),
|
||||||
|
'file_name' => file_exists(_PS_UPLOAD_DIR_.$message['file_name']),
|
||||||
|
'contacts' => $contacts,
|
||||||
|
'PS_CUSTOMER_SERVICE_SIGNATURE' => str_replace('\r\n', "\n", Configuration::get('PS_CUSTOMER_SERVICE_SIGNATURE', $message['id_lang']))
|
||||||
|
));
|
||||||
|
|
||||||
|
return $tpl->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
private function displayButton($content)
|
private function displayButton($content)
|
||||||
{
|
{
|
||||||
return '
|
return '
|
||||||
@@ -626,7 +569,6 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
</div>';
|
</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function renderOptions()
|
public function renderOptions()
|
||||||
{
|
{
|
||||||
if (Configuration::get('PS_SAV_IMAP_URL')
|
if (Configuration::get('PS_SAV_IMAP_URL')
|
||||||
@@ -640,6 +582,5 @@ class AdminCustomerThreadsControllerCore extends AdminController
|
|||||||
return parent::renderOptions();
|
return parent::renderOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+80
-13
@@ -1858,25 +1858,92 @@ ul.connectedSortable
|
|||||||
ul.connectedSortable li.module_list {
|
ul.connectedSortable li.module_list {
|
||||||
margin: 0 5px 5px 5px;
|
margin: 0 5px 5px 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-size: 1.2em;
|
font-size:1.2em;
|
||||||
border: 1px solid #CCC;
|
border:1px solid #CCC;
|
||||||
background: #F6F6F6;
|
background:#F6F6F6;
|
||||||
font-weight: bold;
|
font-weight:bold;
|
||||||
color: #1C94C4;
|
color:#1C94C4;
|
||||||
outline: none;
|
outline:none;
|
||||||
}
|
|
||||||
/* Accounting css */
|
|
||||||
.formAccountingExport {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Accounting css */
|
||||||
|
.formAccountingExport {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
.input-error
|
.input-error
|
||||||
{
|
{
|
||||||
color:#D8000C;
|
color:#D8000C;
|
||||||
font-size:12px;
|
font-size:12px;
|
||||||
font-weight:normal;
|
font-weight:normal;
|
||||||
margin: 0 0 10px 0;
|
margin:0 0 10px 0;
|
||||||
line-height: 20px;
|
line-height:20px;
|
||||||
padding: 10px 15px;
|
padding:10px 15px;
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Customer Thread */
|
||||||
|
#CustomerThreadContacts{
|
||||||
|
float:left;
|
||||||
|
border:0;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts div {
|
||||||
|
background-color:#EFEFEF;
|
||||||
|
float:left;
|
||||||
|
margin:0 10px 10px 0;
|
||||||
|
border:1px solid #CFCFCF;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts p {
|
||||||
|
overflow:hidden;
|
||||||
|
line-height:15px;
|
||||||
|
height:45px;
|
||||||
|
margin:0;
|
||||||
|
padding:0 5px;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts h3 {
|
||||||
|
overflow:hidden;
|
||||||
|
line-height:25px;
|
||||||
|
color:#812143;
|
||||||
|
height:25px;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts a {
|
||||||
|
padding:0 5px;
|
||||||
|
display:block;
|
||||||
|
height:23px;
|
||||||
|
line-height:23px;
|
||||||
|
border:0;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts h4 {
|
||||||
|
margin:0;
|
||||||
|
line-height:23px;
|
||||||
|
height:23px;
|
||||||
|
border:0;
|
||||||
|
padding:0 5px;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts div#CustomerService {
|
||||||
|
width:300px;
|
||||||
|
background:none;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts div#CustomerService table.table {
|
||||||
|
width:300px;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts div#CustomerService table.table thead{
|
||||||
|
margin:0;
|
||||||
|
line-height:23px;
|
||||||
|
height:23px;
|
||||||
|
border:0;
|
||||||
|
padding:0 5px;
|
||||||
|
font-weight:bold;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
#CustomerThreadContacts div#MeaningStatus{
|
||||||
|
width:300px
|
||||||
|
}
|
||||||
|
#ChangeStatus{
|
||||||
|
position:absolute;
|
||||||
|
margin:20px 20px 0 0;
|
||||||
|
right:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 740 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 754 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 779 B |
Reference in New Issue
Block a user