* @copyright 2007-2011 PrestaShop SA * @version Release: $Revision: 8673 $ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * International Registered Trademark & Property of PrestaShop SA */ class AdminCustomerThreads extends AdminTab { public function __construct() { global $cookie; $this->table = 'customer_thread'; $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, ( 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)$cookie->id_lang.')'; $contactArray = array(); $contacts = Contact::getContacts($cookie->id_lang); foreach ($contacts AS $contact) $contactArray[$contact['id_contact']] = $contact['name']; $languageArray = array(); $languages = Language::getLanguages(FALSE); foreach ($languages AS $language) $languageArray[$language['id_lang']] = $language['name']; $statusArray = array( 'open' => $this->l('Open'), 'closed' => $this->l('Closed'), 'pending1' => $this->l('Pending 1'), 'pending2' => $this->l('Pending 2') ); $imagesArray = array( 'open' => 'status_green.gif', 'closed' => 'status_red.gif', 'pending1' => 'status_orange.gif', 'pending2' => 'status_orange.gif' ); $anticonArray = array( 'open' => 'anticon-radio-checked text-green-light', 'closed' => 'anticon-radio-checked2 text-rose', 'pending1' => 'anticon-hour-glass text-orange', 'pending2' => 'anticon-hour-glass text-orange' ); $this->fieldsDisplay = array( 'id_customer_thread' => array('title' => $this->l('ID'), 'width' => 25), 'customer' => array('title' => $this->l('Customer'), 'width' => 100, 'filter_key' => 'customer', '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', 'select' => $contactArray, 'filter_key' => 'cl!id_contact', 'filter_type' => 'int', 'align' =>'text-bold'), 'id_lang' => array('title' => $this->l('Language'), 'width' => 60, 'callback' => 'printCountry', 'type' => 'select', 'select' => $languageArray, 'filter_key' => 'l!id_lang', 'filter_type' => 'int', 'align'=>'center'), 'status' => array('title' => $this->l('Status'), 'width' => 50, 'type' => 'select', 'select' => $statusArray, 'anticon' => $anticonArray, 'align' => 'center', 'filter_key' => 'a!status', 'filter_type' => 'string'), 'employee' => array('title' => $this->l('Employee'), 'width' => 100, 'filter_key' => 'employee', 'tmpTableFilter' => true), 'id_product' => array('title' => $this->l('> 10€'), 'width' => 50, 'maxlength' => 0, 'align' =>'center'), 'id_order' => array('title' => $this->l('Nb products'), 'width' => 50, 'maxlength' => 0, 'align' =>'center text-bold','search'=>false), 'order' => array('title' => $this->l('Total cmd'), 'width' => 50, 'maxlength' => 0, 'align' =>'center text-bold'), 'date_upd' => array('title' => $this->l('Last message'), 'width' => 50, 'type'=>'datetimeLight') ); parent::__construct(); } public function postProcess() { global $currentIndex, $cookie, $link; if ($id_customer_thread = (int)Tools::getValue('id_customer_thread')) { 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); if ($id_status = (int)Tools::getValue('setstatus')) { $statusArray = 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'); Tools::redirectAdmin($currentIndex.'&token='.Tools::getValue('token')); } if (isset($_POST['id_employee_forward'])) { // Todo: need to avoid doubles $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 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)$cookie->id_lang.') 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 = ''; foreach ($messages AS $message) $output .= $this->displayMsgCustom($message, true, (int)Tools::getValue('id_employee_forward')); $cm = new CustomerMessage(); $cm->id_employee = (int)$cookie->id_employee; $cm->id_customer_thread = (int)Tools::getValue('id_customer_thread'); $cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']); $currentEmployee = new Employee($cookie->id_employee); /* ANTADIS */ $message_en_cours = new CustomerThread((int)Tools::getValue('id_customer_thread')); if($message_en_cours->id_customer == 0){ $objet_mail = Mail::l('Fwd: Customer message') . ' - ' . $message_en_cours->email; }else{ $customer_sav = new Customer($message_en_cours->id_customer); $objet_mail = Mail::l('Fwd: Customer message') . ' - ' . $customer_sav->id . ' ' . $customer_sav->lastname . ' ' .$customer_sav->firstname; } if (($id_employee = (int)Tools::getValue('id_employee_forward')) AND ($employee = new Employee($id_employee)) AND Validate::isLoadedObject($employee)) { $params = array( '{messages}' => $output, '{employee}' => $currentEmployee->firstname.' '.$currentEmployee->lastname, '{comment}' => stripslashes($_POST['message_forward'])); if (Mail::Send((int)($cookie->id_lang), 'forward_msg', $objet_mail , $params, $employee->email, $employee->firstname.' '.$employee->lastname, $currentEmployee->email, $currentEmployee->firstname.' '.$currentEmployee->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->add(); } } elseif (($email = Tools::getValue('email')) AND Validate::isEmail($email)) { $params = array( '{messages}' => $output, '{employee}' => $currentEmployee->firstname.' '.$currentEmployee->lastname, '{comment}' => stripslashes($_POST['message_forward'])); if (Mail::Send((int)($cookie->id_lang), 'forward_msg', $objet_mail , $params, $email, NULL, $currentEmployee->email, $currentEmployee->firstname.' '.$currentEmployee->lastname, NULL, NULL, _PS_MAIL_DIR_, true)) { $cm->message = $this->l('Message forwarded to').' '.$email."\n".$this->l('Comment:').' '.$_POST['message_forward']; $cm->add(); } } else echo '
'.Tools::displayError('Email invalid.').'
'; } if (Tools::isSubmit('submitReply')) { $ct = new CustomerThread($id_customer_thread); $cm = new CustomerMessage(); $cm->id_employee = (int)$cookie->id_employee; $cm->id_customer_thread = $ct->id; $cm->message = Tools::htmlentitiesutf8(nl2br2(Tools::getValue('reply_message'))); $cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']); if (isset($_FILES) AND !empty($_FILES['joinFile']['name']) AND $_FILES['joinFile']['error'] != 0) $this->_errors[] = Tools::displayError('An error occurred with the file upload.'); elseif ($cm->add()) { $fileAttachment = NULL; if (!empty($_FILES['joinFile']['name'])) { $fileAttachment['content'] = file_get_contents($_FILES['joinFile']['tmp_name']); $fileAttachment['name'] = $_FILES['joinFile']['name']; $fileAttachment['mime'] = $_FILES['joinFile']['type']; } $link_reply = Tools::getShopDomain(true).__PS_BASE_URI__.'modules/ant_support_form/support.php?id_customer_thread='.(int)($ct->id).'&token='.$ct->token.(($ct->id_contact == 9 || $ct->id_contact == 1)?'&id_contact='.$ct->id_contact : ''); //$link_reply = $link->getPageLink('contact-form.php', true).'?id_customer_thread='.(int)($ct->id).'&token='.$ct->token; $params = array( '{reply}' => nl2br2(Tools::getValue('reply_message')), '{link}' => $link_reply); if (Mail::Send($ct->id_lang, 'reply_msg', Mail::l('An answer to your message is available'), $params, Tools::getValue('msg_email'), NULL, NULL, NULL, $fileAttachment, NULL, _PS_MAIL_DIR_, true)) { $ct->status = 'closed'; $ct->update(); } Tools::redirectAdmin($currentIndex.'&id_customer_thread='.(int)$id_customer_thread.'&viewcustomer_thread&token='.Tools::getValue('token')); } else $this->_errors[] = Tools::displayError('An error occurred, your message was not sent. Please contact your system administrator.'); } } return parent::postProcess(); } public function display() { global $cookie; if (isset($_GET['filename']) AND file_exists(_PS_UPLOAD_DIR_.$_GET['filename'])) self::openUploadedFile(); elseif (isset($_GET['view'.$this->table])) $this->viewcustomer_thread(); else { $this->getList((int)$cookie->id_lang, !Tools::getValue($this->table.'Orderby') ? 'date_upd' : NULL, !Tools::getValue($this->table.'Orderway') ? 'DESC' : NULL); $this->displayList(); } } public function displayListHeader($token = NULL) { global $currentIndex, $cookie; $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 = '.$cookie->id_lang.') 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 = '.$cookie->id_lang.') WHERE ct.customer_service = 1'); $dim = count($categories); echo '
'; 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; } echo '

 '.$val['name'].'

'. ($dim > 6 ? '' : '

'.$val['description'].'

'). ($totalThread == 0 ? '

'.$this->l('No new message').'

' : ''.$totalThread.' '.($totalThread > 1 ? $this->l('new messages'): $this->l('new message')).'').'
'; } echo '
'; $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)); echo '

'.$this->l('Customer service').' : '.$this->l('Statistics').'

'; $count = 0; foreach ($params as $key => $val) echo ''; echo '
'.$key.''.$val.'

 

'.$this->l('> 10€').'

'.$this->l('> 100€').'

'; $this->displayListHeaderBis($token); } public function displayListHeaderBis($token = NULL) { global $currentIndex, $cookie; $isCms = false; if (preg_match('/cms/Ui', $this->identifier)) $isCms = true; $id_cat = Tools::getValue('id_'.($isCms ? 'cms_' : '').'category'); if (!isset($token) OR empty($token)) $token = $this->token; /* Determine total page number */ $totalPages = ceil($this->_listTotal / Tools::getValue('pagination', (isset($cookie->{$this->table.'_pagination'}) ? $cookie->{$this->table.'_pagination'} : $this->_pagination[0]))); if (!$totalPages) $totalPages = 1; echo ' '; echo '
'; foreach ($this->fieldsDisplay AS $key => $params) { echo ' '; } /* Check if object can be modified, deleted or detailed */ if ($this->edit OR $this->delete OR ($this->view AND $this->view !== 'noActionColumn')) echo ' '; echo ' '; /* Javascript hack in order to catch ENTER keypress event */ $keyPress = 'onkeypress="formSubmit(event, \'submitFilterButton_'.$this->table.'\');"'; /* Filters (input, select, date or bool) */ foreach ($this->fieldsDisplay AS $key => $params) { $width = (isset($params['width']) ? ' style="width: '.(int)($params['width']).'px;"' : ''); echo ''; if (!isset($params['type'])) $params['type'] = 'text'; $value = Tools::getValue($this->table.'Filter_'.(array_key_exists('filter_key', $params) ? $params['filter_key'] : $key)); if (isset($params['search']) AND !$params['search']) { echo '--'; continue; } switch ($params['type']) { case 'bool': echo ' '; break; case 'date': case 'datetime': if (is_string($value)) $value = unserialize($value); if (!Validate::isCleanHtml($value[0]) OR !Validate::isCleanHtml($value[1])) $value = ''; $name = $this->table.'Filter_'.(isset($params['filter_key']) ? $params['filter_key'] : $key); $nameId = str_replace('!', '__', $name); includeDatepicker(array($nameId.'_0', $nameId.'_1')); echo $this->l('From').'
'.$this->l('To').' '; break; case 'select': if (isset($params['filter_key'])) { echo ''; break; } case 'text': default: if (!Validate::isCleanHtml($value)) $value = ''; echo ''; } echo ''; } if ($this->edit OR $this->delete OR ($this->view AND $this->view !== 'noActionColumn')) echo '
'; echo ''; } public function displayListContent($token = NULL) { /* Display results in a table * * align : determine value alignment * prefix : displayed before value * suffix : displayed after value * image : object image * icon : icon determined by values * active : allow to toggle status */ global $currentIndex, $cookie; $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); $id_category = 1; // default categ $irow = 0; if ($this->_list AND isset($this->fieldsDisplay['position'])) { $positions = array_map(create_function('$elem', 'return (int)($elem[\'position\']);'), $this->_list); sort($positions); } if ($this->_list) { $isCms = false; if (preg_match('/cms/Ui', $this->identifier)) $isCms = true; $keyToGet = 'id_'.($isCms ? 'cms_' : '').'category'.(in_array($this->identifier, array('id_category', 'id_cms_category')) ? '_parent' : ''); foreach ($this->_list AS $tr) { $id = $tr[$this->identifier]; echo 'identifier,$this->identifiersDnd) ? ' id="tr_'.(($id_category = (int)(Tools::getValue('id_'.($isCms ? 'cms_' : '').'category', '1'))) ? $id_category : '').'_'.$id.'_'.$tr['position'].'"' : '').($irow++ % 2 ? ' class="alt_row"' : '').' '.((isset($tr['color']) AND $this->colorOnBackground) ? 'style="background-color: '.$tr['color'].'"' : '').'> '; foreach ($this->fieldsDisplay AS $key => $params) { $tmp = explode('!', $key); $key = isset($tmp[1]) ? $tmp[1] : $tmp[0]; echo ' '; } if ($this->edit OR $this->delete OR ($this->view AND $this->view !== 'noActionColumn')) { echo ''; } echo ''; } } } protected function _displayDeleteLink($token, $id) { global $currentIndex; $_cacheLang['Delete'] = $this->l('Delete'); $_cacheLang['DeleteItem'] = $this->l('Delete item #', __CLASS__, TRUE, FALSE); echo ' '; } protected function _displayViewLink($token = NULL, $id) { global $currentIndex; $_cacheLang['View'] = $this->l('View'); echo ' '; } private function openUploadedFile() { $filename = $_GET['filename']; $extensions = array('.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 = ''; foreach ($extensions AS $key => $val) if (substr($filename, -4) == $key OR substr($filename, -5) == $key) { $extension = $val; break; } ob_end_clean(); header('Content-Type: '.$extension); header('Content-Disposition:attachment;filename="'.$filename.'"'); readfile(_PS_UPLOAD_DIR_.$filename); die; } private function displayMsgCustom($message, $email = false, $id_employee = null) { global $cookie, $currentIndex; $customersToken = Tools::getAdminToken('AdminCustomers'.(int)(Tab::getIdFromClassName('AdminCustomers')).(int)($cookie->id_employee)); $contacts = Contact::getContacts($cookie->id_lang); $output = '
'; 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 .= '
'.Tools::displayDate($message['date_add'], (int)($cookie->id_lang), true).'
'.( (!empty($message['file_name']) AND file_exists(_PS_UPLOAD_DIR_.$message['file_name'])) ? '' : '' ) .(empty($message['employee_name']) ?'' :'').'
'; if(empty($message['employee_name'])){ $output .='

'.$this->l('Informations').'

    '; // if(empty($message['employee_name'])) { // $output .= '
  • '.strip_tags($message['user_agent']).'
  • '; // } // $output .= '
  • '.$this->l('Thread ID:').' '.(int)$message['id_customer_thread'].'
  • //
  • '.$this->l('Message ID:').' '.(int)$message['id_customer_message'].'
  • '; if(!empty($message['id_order']) AND empty($message['employee_name'])) { $output .= '
  • '.$this->l('Order #').' '.(int)($message['id_order']).'
  • '; } if(!empty($message['id_product']) && empty($message['employee_name'])){ $products = Db::getInstance()->ExecuteS(' SELECT spc.*, pl.`name` FROM `'._DB_PREFIX_.'support_product_customerthread` spc LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = spc.`id_product`) WHERE spc.`id_customer_thread` = '.(int)$message['id_customer_thread'].' AND pl.`id_lang` = 2' ); $output .= '
  • '.$this->l('Chosen Products:').'

    '; foreach ($products as $key => $product) { $img_path = ''; $img = Db::getInstance()->getRow(' SELECT id_image FROM `'._DB_PREFIX_.'image` i WHERE i.`id_product` = '.(int)$product['id_product'].' AND i.`cover` = 1' ); if (isset($img['id_image']) && !empty($img['id_image'])) { $image_obj = new Image((int)$img['id_image']); $img_path = (isset($image_obj)?$image_obj->getExistingImgPath():''); } $output .= ' '; } $output .= '

     

  • '; } $output .= '
'; } $output .= '
'; } else { $output .= ' '.($id_employee ? ''.$this->l('View this thread').'
' : '').' '.$this->l('Sent by:').' '.(!empty($message['customer_name']) ? $message['customer_name'].' ('.$message['email'].')' : $message['email']) .((!empty($message['id_customer']) AND empty($message['employee_name'])) ? '
'.$this->l('Customer ID:').' '.(int)($message['id_customer']).'
' : '') .((!empty($message['id_order']) AND empty($message['employee_name'])) ? '
'.$this->l('Order #').': '.(int)($message['id_order']).'
' : '') .((!empty($message['id_product']) AND empty($message['employee_name'])) ? '
'.$this->l('Product #').': '.(int)($message['id_product']).'
' : '') .''.$this->l('Subject:').' '.$message['subject']; } $employees = Db::getInstance()->ExecuteS(' SELECT e.id_employee, e.firstname, e.lastname FROM '._DB_PREFIX_.'employee e WHERE e.active = 1 ORDER BY e.lastname ASC'); $output .= '
'; // Adding Antadis - linking with ant_support_form module if (Module::isInstalled('ant_support_form')) { $result = Db::getInstance()->getRow(' SELECT sr.*, srl.title FROM `'._DB_PREFIX_.'support_reason` sr LEFT JOIN `'._DB_PREFIX_.'support_reason_lang` srl ON (srl.id_reason = sr.id_reason) LEFT JOIN `'._DB_PREFIX_.'support_reason_customerthread` src ON (src.id_reason = sr.id_reason) WHERE `id_customer_thread` = '.(int) $message['id_customer_thread'].' AND srl.id_lang = '.$cookie->id_lang ); if ($result) { $output .='
'.$this->l('Reason:').' '.$result['title'].'
'; } } // end adding $message['message'] = preg_replace('/(https?:\/\/[a-z0-9#%&_=\(\)\.\? \+\-@\/]{6,1000})([\s\n<])/Uui', '\1\2', html_entity_decode($message['message'], ENT_NOQUOTES, 'UTF-8')); $output .= '
'.$this->l('Message:').'
'.$message['message'].'
'; if (!$email) { if (empty($message['employee_name'])) { $orderMessages = OrderMessage::getOrderMessages((int)($message['id_lang'])); $output .= '

 

'; } } $output .= '
'; return $output; } private function displayMsg($message, $email = false, $id_employee = null) { global $cookie, $currentIndex; $customersToken = Tools::getAdminToken('AdminCustomers'.(int)(Tab::getIdFromClassName('AdminCustomers')).(int)($cookie->id_employee)); $contacts = Contact::getContacts($cookie->id_lang); 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 = '
'.( !empty($message['employee_name']) ? ''.Configuration::get('PS_SHOP_NAME').' '.Configuration::get('PS_SHOP_NAME').' - '.$message['employee_name'] : ''.Configuration::get('PS_SHOP_NAME').' '.( !empty($message['id_customer']) ? ''.$message['customer_name'].'' : $message['email'] ) ).'
'.( (!empty($message['id_customer']) AND empty($message['employee_name'])) ? ''.$this->l('Customer ID:').' '.(int)($message['id_customer']).' '.$this->l('view').'
' : '' ).' '.$this->l('Sent on:').' '.Tools::displayDate($message['date_add'], (int)($cookie->id_lang), true).'
'.( empty($message['employee_name']) ? ''.$this->l('Browser:').' '.strip_tags($message['user_agent']).'
' : '' ).( (!empty($message['file_name']) AND file_exists(_PS_UPLOAD_DIR_.$message['file_name'])) ? ''.$this->l('File attachment').' '.$this->l('view').'
' : '' ).( (!empty($message['id_order']) AND empty($message['employee_name'])) ? ''.$this->l('Order #').' '.(int)($message['id_order']).' '.$this->l('view').'
' : '' ).( (!empty($message['id_product']) AND empty($message['employee_name'])) ? ''.$this->l('Product #').' '.(int)($message['id_product']).' '.$this->l('view').'
' : '' ).'
'.$this->l('Subject:').' '; } else { $output = '
'.($id_employee ? ''.$this->l('View this thread').'
' : '').' '.$this->l('Sent by:').' '.(!empty($message['customer_name']) ? $message['customer_name'].' ('.$message['email'].')' : $message['email']) .((!empty($message['id_customer']) AND empty($message['employee_name'])) ? '
'.$this->l('Customer ID:').' '.(int)($message['id_customer']).'
' : '') .((!empty($message['id_order']) AND empty($message['employee_name'])) ? '
'.$this->l('Order #').': '.(int)($message['id_order']).'
' : '') .((!empty($message['id_product']) AND empty($message['employee_name'])) ? '
'.$this->l('Product #').': '.(int)($message['id_product']).'
' : '') .'
'.$this->l('Subject:').' '.$message['subject']; } // Adding Antadis - linking with ant_support_form module if (Module::isInstalled('ant_support_form')) { $result = Db::getInstance()->getRow(' SELECT sr.*, srl.title FROM `'._DB_PREFIX_.'support_reason` sr LEFT JOIN `'._DB_PREFIX_.'support_reason_lang` srl ON (srl.id_reason = sr.id_reason) LEFT JOIN `'._DB_PREFIX_.'support_reason_customerthread` src ON (src.id_reason = sr.id_reason) WHERE `id_customer_thread` = '.(int) $message['id_customer_thread'].' AND srl.id_lang = '.$cookie->id_lang ); if ($result) { $output .='

'.$this->l('Reason:').' '.$result['title'].'
'; } } // end adding $message['message'] = preg_replace('/(https?:\/\/[a-z0-9#%&_=\(\)\.\? \+\-@\/]{6,1000})([\s\n<])/Uui', '\1\2', html_entity_decode($message['message'], ENT_NOQUOTES, 'UTF-8')); $output .= '

'.$this->l('Thread ID:').' '.(int)$message['id_customer_thread'].'
'.$this->l('Message ID:').' '.(int)$message['id_customer_message'].'
'.$this->l('Message:').'
'.$message['message'].'
'; if (!$email) { if (empty($message['employee_name'])) $output .= '

'; } return $output; } public function viewcustomer_thread() { global $cookie, $currentIndex; if (!($thread = $this->loadObject())) return; $cookie->{'customer_threadFilter_cl!id_contact'} = $thread->id_contact; echo '

'.$this->l('Messages').'

'; // if ($nextThread) // echo $this->displayButton(' // // '.$this->l('Answer to the next unanswered message in this category').' > // '); // else // echo $this->displayButton(' // '.$this->l('The other messages in this category have been answered').''); if ($thread->status != "closed") echo $this->displayButton(' '.$this->l('Set this message as handled').' '); if ($thread->status != "pending1") echo $this->displayButton(' '.$this->l('pending 1').' '); else echo $this->displayButton(' '.$this->l('In Pending 1').' '); if ($thread->status != "pending2") echo $this->displayButton(' '.$this->l('pending 2').' '); else echo $this->displayButton(' '.$this->l('In Pending 2').' '); echo '
 
'; $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 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)$cookie->id_lang.') 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'); echo '
'; $nextThread = 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)$thread->id.' ORDER BY date_add DESC LIMIT 1 ) '.($cookie->{'customer_threadFilter_cl!id_contact'} ? 'AND ct.id_contact = '.(int)$cookie->{'customer_threadFilter_cl!id_contact'} : '').' '.($cookie->{'customer_threadFilter_l!id_lang'} ? 'AND ct.id_lang = '.(int)$cookie->{'customer_threadFilter_l!id_lang'} : ''). ' ORDER BY ct.date_upd ASC'); $order_thread = null; foreach ($messages AS $message){ if ($message['id_order']){ $order_thread = new Order((int)($message['id_order'])); break; } } if ($thread->id_customer) { $customer = new Customer($thread->id_customer); $products = $customer->getBoughtProducts(); $nb_orders = Db::getInstance()->getValue(' SELECT COUNT(id_order) FROM '._DB_PREFIX_.'orders WHERE id_customer = '.(int)$customer->id.' AND valid=1 '); $customer_info = array( 'nb_orders' => $nb_orders, ); } echo '
'; Module::hookExec('rightColumnSav', array( 'customer' => $customer, 'customer_info' => $customer_info, 'order' => $order_thread) ); echo '
'; echo '
'; echo '
'; foreach ($messages AS $message) { echo $this->displayMsgCustom($message); } echo '
'; echo '
 
'; if ($thread->id_customer) { $customer = new Customer($thread->id_customer); //$products = $customer->getBoughtProducts(); $orders = Order::getCustomerOrders($customer->id); echo '
'; if ($orders AND sizeof($orders)) { $totalOK = 0; $ordersOK = array(); $tokenOrders = Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)($cookie->id_employee)); foreach ($orders as $order) if ($order['valid']) { $ordersOK[] = $order; $totalOK += $order['total_paid_real']; } if ($countOK = sizeof($ordersOK)) { echo '

'.$this->l('Orders').'

'.$this->l('Validated Orders:').' '.$countOK.' '.$this->l('for').' '.Tools::displayPrice($totalOK, new Currency(Configuration::get('PS_CURRENCY_DEFAULT'))).'

'; /* Determine current page number */ $page = (int)(Tools::getValue('submitFilter'.$this->table)); if (!$page) $page = 1; if ($page > 1) echo '   '; echo $this->l('Page').' '.$page.' / '.$totalPages; if ($page < $totalPages) echo '  '; echo ' | '.$this->l('Display').' / '.(int)($this->_listTotal).' '.$this->l('result(s)').'
'; /* Display column names and arrows for ordering (ASC, DESC) */ if (array_key_exists($this->identifier,$this->identifiersDnd) AND $this->_orderBy == 'position') { echo ' '; } echo 'identifier,$this->identifiersDnd) ? ' id="'.(((int)(Tools::getValue($this->identifiersDnd[$this->identifier], 1))) ? substr($this->identifier,3,strlen($this->identifier)) : '').'"' : '' ).' class="table'.((array_key_exists($this->identifier,$this->identifiersDnd) AND ($this->_orderBy != 'position 'AND $this->_orderWay != 'DESC')) ? ' tableDnD' : '' ).'" cellpadding="0" cellspacing="0">
'; if ($this->delete) echo ' '; echo ' '.$params['title']; if (!isset($params['orderby']) OR $params['orderby']) { // Cleaning links if (Tools::getValue($this->table.'Orderby') && Tools::getValue($this->table.'Orderway')) $currentIndex = preg_replace('/&'.$this->table.'Orderby=([a-z _]*)&'.$this->table.'Orderway=([a-z]*)/i', '', $currentIndex); echo '
'; } echo '
'.$this->l('Actions').'
'; if ($this->delete) echo ' --'; echo ' --
'; if ($this->delete AND (!isset($this->_listSkipDelete) OR !in_array($id, $this->_listSkipDelete))) echo ''; echo 'noLink) OR !$this->noLink)) echo ' onclick="document.location = \''.$currentIndex.'&'.$this->identifier.'='.$id.($this->view? '&view' : '&update').$this->table.'&token='.($token!=NULL ? $token : $this->token).'\'">'.(isset($params['prefix']) ? $params['prefix'] : ''); else echo '>'; if ($key == 'id_product' AND isset($tr[$key]) AND $tr[$key] !=0 AND isset($tr['id_order']) ) { $order = new Order((int)$tr['id_order']); $cart = new Cart((int)$order->id_cart); $products = Db::getInstance()->executeS(' SELECT * FROM `'._DB_PREFIX_.'support_product_customerthread` WHERE `id_customer_thread` = '.(int)$tr['id_customer_thread'] ); $supTo10 = 0; $supTo100 = 0; if(!empty($products)) { foreach ($products as $product) { $tax_rate = Tax::getProductTaxRate((int)$product['id_product'], (int)($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')})); $price = Product::getPriceStatic((int)$product['id_product'], false, (int)$product['id_product_attribute'], 6, NULL, false, true, 1, false, ((int)($tr['id_customer']) ? (int)($tr['id_customer']) : NULL), (int)($order->id_cart), ((int)($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) ? (int)($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) : NULL), $specificPriceOutput); $price = Tools::ps_round($price * (1 + (float)($tax_rate) / 100), 2); if($price>10){ $supTo10++; } if($price>100){ $supTo100++; } } } echo ($supTo10>0?'

'.($supTo100>0?'':'').'

':'

'); } elseif ($key == 'id_order' AND isset($tr[$key])) { $order = new Order((int)$tr[$key]); $cart = new Cart((int)$order->id_cart); $nb_products = $cart->nbProducts(); echo '

'.($nb_products>0?$nb_products:'--').'

'; } elseif ($key == 'order' AND isset($tr['id_order']) AND (int)$tr['id_order']!=0) { $currency = new Currency((int)(Configuration::get('PS_CURRENCY_DEFAULT'))); $order = new Order((int)$tr['id_order']); $cart = new Cart((int)$order->id_cart); echo '

'.($order?Tools::displayPrice($cart->getOrderTotal(TRUE),$currency):'--').'

'; } elseif (isset($params['active']) AND isset($tr[$key])) { $this->_displayEnableLink($token, $id, $tr[$key], $params['active'], Tools::getValue('id_category'), Tools::getValue('id_product')); } elseif (isset($params['activeVisu']) AND isset($tr[$key])) { echo ''.($tr[$key] ? $this->l('Enabled') : $this->l('Disabled')).''; } elseif (isset($params['position'])) { if ($this->_orderBy == 'position' AND $this->_orderWay != 'DESC') { echo ' '.$this->l('Down').''; echo ' '.$this->l('Up').''; } else echo (int)($tr[$key] + 1); } elseif (isset($params['image'])) { // item_id is the product id in a product image context, else it is the image id. $item_id = isset($params['image_id']) ? $tr[$params['image_id']] : $id; // If it's a product image if (isset($tr['id_image'])) { $image = new Image((int)$tr['id_image']); $path_to_image = _PS_IMG_DIR_.$params['image'].'/'.$image->getExistingImgPath().'.'.$this->imageType; }else $path_to_image = _PS_IMG_DIR_.$params['image'].'/'.$item_id.(isset($tr['id_image']) ? '-'.(int)($tr['id_image']) : '').'.'.$this->imageType; echo cacheImage($path_to_image, $this->table.'_mini_'.$item_id.'.'.$this->imageType, 45, $this->imageType); } elseif (isset($params['icon']) AND (isset($params['icon'][$tr[$key]]) OR isset($params['icon']['default']))) echo ''.$tr[$key]).''; elseif (isset($params['anticon']) AND (isset($params['anticon'][$tr[$key]]) OR isset($params['anticon']['default']))) echo ' '; elseif (isset($params['price'])) echo Tools::displayPrice($tr[$key], (isset($params['currency']) ? Currency::getCurrencyInstance((int)($tr['id_currency'])) : $currency), false); elseif (isset($params['float'])) echo rtrim(rtrim($tr[$key], '0'), '.'); elseif (isset($params['type']) AND $params['type'] == 'date') echo Tools::displayDate($tr[$key], (int)$cookie->id_lang); elseif (isset($params['type']) AND $params['type'] == 'datetime') echo Tools::displayDate($tr[$key], (int)$cookie->id_lang, true); elseif (isset($params['type']) AND $params['type'] == 'datetimeLight') echo date('d/m/Y H:i',strtotime($tr[$key])); elseif (isset($tr[$key])) { $echo = ($key == 'price' ? round($tr[$key], 2) : isset($params['maxlength']) ? Tools::substr($tr[$key], 0, $params['maxlength']).'...' : $tr[$key]); echo isset($params['callback']) ? call_user_func_array(array($this->className, $params['callback']), array($echo, $tr)) : $echo; } else echo '--'; echo (isset($params['suffix']) ? $params['suffix'] : ''). '
'; if ($this->view) $this->_displayViewLink($token, $id); if ($this->edit) $this->_displayEditLink($token, $id); if ($this->delete AND (!isset($this->_listSkipDelete) OR !in_array($id, $this->_listSkipDelete))) $this->_displayDeleteLink($token, $id); if ($this->duplicate) $this->_displayDuplicate($token, $id); echo '
'; $irow = 0; foreach ($ordersOK AS $order) echo ''; echo '
'.$this->l('ID').' '.$this->l('Date').' '.$this->l('Products').' '.$this->l('Total paid').' '.$this->l('Payment').' '.$this->l('State').' '.$this->l('Actions').'
'.$order['id_order'].' '.Tools::displayDate($order['date_add'], (int)($cookie->id_lang)).' '.$order['nb_products'].' '.Tools::displayPrice($order['total_paid_real'], new Currency((int)($order['id_currency']))).' '.$order['payment'].' '.$order['order_state'].'
'; } } // if ($products AND sizeof($products)) // { // echo '
//

'.$this->l('Products').'

// // // // // // // // '; // $irow = 0; // $tokenOrders = Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)($cookie->id_employee)); // foreach ($products AS $product) // echo ' // // // // // // // '; // echo '
'.$this->l('Date').''.$this->l('ID').''.$this->l('Name').''.$this->l('Quantity').''.$this->l('Actions').'
'.Tools::displayDate($product['date_add'], (int)($cookie->id_lang), true).''.$product['product_id'].''.$product['product_name'].''.$product['product_quantity'].'
//
'; // } echo ''; } echo '
 
'; } private function displayButton($content) { return '

'.$content.'

'; } }