762 lines
46 KiB
PHP
Executable File
762 lines
46 KiB
PHP
Executable File
<?php
|
|
|
|
class AdminStatseasy extends AdminTab{
|
|
|
|
private $_html;
|
|
private $_error;
|
|
public $name = 'statseasy';
|
|
public $multishop_context;
|
|
public $multishop_context_group;
|
|
|
|
/*
|
|
* Affiche le contenu de l'onglet
|
|
* @param -
|
|
* @return -
|
|
*/
|
|
public function display(){
|
|
|
|
require_once(dirname(__FILE__).'/statseasy.php');
|
|
$Statseasy = new Statseasy();
|
|
|
|
$currentIndex = 'index.php?controller='.$this->context->controller->controller_name;
|
|
$cookie = $this->context->cookie;
|
|
|
|
// var
|
|
$id_currency=Configuration::get('PS_CURRENCY_DEFAULT');
|
|
$Currency = new Currency($id_currency);
|
|
$topX = Configuration::get('STATSEASY_NBTOP');
|
|
if(empty($topX)){$topX=5;}else{$topX=Configuration::get('STATSEASY_NBTOP');}
|
|
|
|
$iso = Db::getInstance()->getValue('SELECT iso_code FROM '._DB_PREFIX_.'lang WHERE `id_lang` = '.pSQL(Context::getContext()->language->id));
|
|
|
|
|
|
if($Statseasy->ps_version=='1.6'){
|
|
$this->_html .= '<link rel="stylesheet" type="text/css" href="'.Tools::getHttpHost(true).__PS_BASE_URI__.'modules/statseasy/css/styles_1.6.css">';
|
|
}
|
|
$this->_html.= '<div class="panel" id="stats_easy_bo">';
|
|
|
|
// CSS
|
|
$this->_html.= '
|
|
<link href="'.__PS_BASE_URI__.'/modules/statseasy/css/bo.css" rel="stylesheet" type="text/css" />
|
|
<link href="'.__PS_BASE_URI__.'/modules/statseasy/css/screen.css" rel="stylesheet" type="text/css" />
|
|
<link type="text/css" rel="stylesheet" href="'.__PS_BASE_URI__.'modules/statseasy/libraries/jquery_ui/css/ui-lightness/jquery-ui-1.8.10.custom.css" />
|
|
<link type="text/css" rel="stylesheet" href="'.__PS_BASE_URI__.'js/jquery/ui/themes/ui-lightness/jquery.ui.theme.css" />
|
|
<link type="text/css" rel="stylesheet" href="'.__PS_BASE_URI__.'js/jquery/ui/themes/ui-lightness/jquery.ui.datepicker.css" />';
|
|
|
|
// JS
|
|
if($Statseasy->ps_version<1.6){
|
|
$this->_html.= '
|
|
<script type="text/javascript" src="../modules/statseasy/libraries/jquery_ui/js/jquery-ui-1.8.10.custom.min.js"></script>
|
|
<script src="'.__PS_BASE_URI__.'/js/jquery/ui/jquery.ui.datepicker.min.js" type="text/javascript"></script>
|
|
<script type="text/javascript" src="'.__PS_BASE_URI__.'js/jquery/ui/i18n/jquery.ui.datepicker-'.Tools::htmlentitiesUTF8($iso).'.js"></script> ';
|
|
}
|
|
|
|
$this->_html.= '
|
|
<script type="text/javascript">
|
|
$(document).ready(function(){
|
|
$.datepicker.setDefaults({ dateFormat: "yy-mm-dd" });
|
|
$("#date_start").datepicker();
|
|
$.datepicker.setDefaults($.datepicker.regional["fr"]);
|
|
$.datepicker.setDefaults({ dateFormat: "yy-mm-dd" });
|
|
$("#date_end").datepicker();
|
|
});
|
|
</script>';
|
|
|
|
if(Tools::isSubmit('submitFilterDate')){
|
|
$cookie->statseasy_date_start = Tools::getValue('date_start');
|
|
$cookie->statseasy_date_end = Tools::getValue('date_end');
|
|
}
|
|
|
|
$date_start = $cookie->statseasy_date_start;
|
|
$date_end = $cookie->statseasy_date_end;
|
|
if(empty($date_start) && empty($date_end)){
|
|
$date_start = date('Y').'-'.date('m').'-01';
|
|
$date_end = date('Y-m-d');
|
|
}
|
|
|
|
// Forme filtre
|
|
$this->_html.= '
|
|
<form action="'.$_SERVER['REQUEST_URI'].'" method="post">
|
|
<div>
|
|
<div style="float:left;" id="div_date_start"><label style="width:80px;" for="date_start">'.$this->l('Date début').'</label>
|
|
<input type="text" style="" name="date_start" value="'.$date_start.'" id="date_start">
|
|
<div class="clear pspace"></div>
|
|
</div>
|
|
<div style="float:left;" id="div_date_end">
|
|
<label style="width:80px;" for="date_end">'.$this->l('Date fin').'</label>
|
|
<input type="text" style="" name="date_end" value="'.$date_end.'" id="date_end">
|
|
<div class="clear pspace"></div>
|
|
</div>
|
|
<div style="" id="div_submitFilterDate">
|
|
<input type="submit" class="button" style="" value="'.$this->l('Filtrer').'" name="submitFilterDate">
|
|
</div>
|
|
</form>
|
|
<hr/>';
|
|
|
|
$this->_html .= '
|
|
<a href="'.$_SERVER['REQUEST_URI'].'&export=pdf" target="_blank"><img src="'._MODULE_DIR_.'statseasy/img/pdf.png" style="vertical-align:top" target="_blank" />'.$this->l('Imprimer les statistiques en PDF').'</a><br/>
|
|
<hr/>';
|
|
|
|
$states_paid = Db::getInstance()->getRow('SELECT `id_statseasy` FROM `'._DB_PREFIX_ .'statseasy` WHERE `type`="orderStatesPaid" AND `id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$states_wait = Db::getInstance()->getRow('SELECT `id_statseasy` FROM `'._DB_PREFIX_ .'statseasy` WHERE `type`="orderStatesWait" AND `id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$states_del = Db::getInstance()->getRow('SELECT `id_statseasy` FROM `'._DB_PREFIX_ .'statseasy` WHERE `type`="orderStatesDel" AND `id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
|
|
if(empty($states_paid) || empty($states_wait) || empty($states_del)){
|
|
$this->_html.= $Statseasy->msgError($this->l('Veuillez configurer le module sous l\'onglet "Modules"'));
|
|
}else{
|
|
|
|
/*
|
|
* Statistiques commandes
|
|
*/
|
|
|
|
// sélectionne toutes les commandes
|
|
$orders = Db::getInstance()->ExecuteS('SELECT o.`id_order`,o.`total_shipping`,o.`total_discounts` FROM `'._DB_PREFIX_.'orders` o WHERE `date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59" AND `id_shop`="'.pSQL($this->context->shop->id).'" ORDER BY `date_add`');
|
|
|
|
// statuts commandes payées
|
|
$orderStatesPaid = Db::getInstance()->ExecuteS('SELECT value FROM '._DB_PREFIX_ .'statseasy WHERE type="orderStatesPaid" AND `id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$orderStatesPaidLst = array();
|
|
foreach($orderStatesPaid as $orderStatePaid){$orderStatesPaidLst[] = $orderStatePaid['value'];}
|
|
// statuts commandes attentes
|
|
$orderStatesWait = Db::getInstance()->ExecuteS('SELECT value FROM '._DB_PREFIX_ .'statseasy WHERE type="orderStatesWait" AND `id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$orderStatesWaitLst = array();
|
|
foreach($orderStatesWait as $orderStateWait){$orderStatesWaitLst[] = $orderStateWait['value'];}
|
|
// statuts commandes annulées
|
|
$orderStatesDel = Db::getInstance()->ExecuteS('SELECT value FROM '._DB_PREFIX_ .'statseasy WHERE type="orderStatesDel" AND `id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$orderStatesDelLst = array();
|
|
foreach($orderStatesDel as $orderStateDel){$orderStatesDelLst[] = $orderStateDel['value'];}
|
|
|
|
// commandes payées
|
|
$totalAllOrdersReducPaid = 0;
|
|
$totalAllOrdersPaid = 0;
|
|
$totalAllOrderShippingPaid = 0;
|
|
$totalAllOrderTvaPaid = 0;
|
|
$totalOrderShippingPaid = 0;
|
|
$nbOrdersPaid = 0;
|
|
// commandes attentes
|
|
$totalAllOrdersReducWait = 0;
|
|
$totalAllOrdersWait = 0;
|
|
$totalAllOrderShippingWait = 0;
|
|
$totalAllOrderTvaWait = 0;
|
|
$totalOrderShippingWait = 0;
|
|
$nbOrdersWait = 0;
|
|
// commandes supprimées
|
|
$totalAllOrdersReducDel = 0;
|
|
$totalAllOrdersDel = 0;
|
|
$totalAllOrderShippingDel = 0;
|
|
$totalAllOrderTvaDel = 0;
|
|
$totalOrderShippingDel = 0;
|
|
$nbOrdersDel = 0;
|
|
|
|
foreach($orders as $order){
|
|
|
|
$Order = new Order($order['id_order']);
|
|
|
|
// commandes payées
|
|
if(in_array($Order->getCurrentState(),$orderStatesPaidLst)){
|
|
$totalAllOrdersReducPaid=$totalAllOrdersReducPaid+$order['total_discounts'];
|
|
$TotalOrderProductsWithTaxes = $Order->getTotalProductsWithTaxes();
|
|
$totalOrderShippingPaid = Tools::ps_round($order['total_shipping'],2);
|
|
$totalOrderPaid = $TotalOrderProductsWithTaxes+$totalOrderShippingPaid;
|
|
$totalAllOrdersPaid=$totalAllOrdersPaid+$totalOrderPaid;
|
|
$totalAllOrderShippingPaid=$totalAllOrderShippingPaid+$totalOrderShippingPaid;
|
|
$totalAllOrderTvaPaid=$totalAllOrderTvaPaid+($Order->getTotalProductsWithTaxes()-$Order->getTotalProductsWithoutTaxes());
|
|
$nbOrdersPaid++;
|
|
}
|
|
// commandes attentes
|
|
if(in_array($Order->getCurrentState(),$orderStatesWaitLst)){
|
|
$totalAllOrdersReducWait=$totalAllOrdersReducWait+$order['total_discounts'];
|
|
$TotalOrderProductsWithTaxes = $Order->getTotalProductsWithTaxes();
|
|
$totalOrderShippingWait = Tools::ps_round($order['total_shipping'],2);
|
|
$totalOrderWait = $TotalOrderProductsWithTaxes+$totalOrderShippingWait;
|
|
$totalAllOrdersWait=$totalAllOrdersWait+$totalOrderWait;
|
|
$totalAllOrderShippingWait=$totalAllOrderShippingWait+$totalOrderShippingWait;
|
|
$totalAllOrderTvaWait=$totalAllOrderTvaWait+($Order->getTotalProductsWithTaxes()-$Order->getTotalProductsWithoutTaxes());
|
|
$nbOrdersWait++;
|
|
}
|
|
// commandes supprimées
|
|
if(in_array($Order->getCurrentState(),$orderStatesDelLst)){
|
|
$totalAllOrdersReducDel=$totalAllOrdersReducDel+$order['total_discounts'];
|
|
$TotalOrderProductsWithTaxes = $Order->getTotalProductsWithTaxes();
|
|
$totalOrderShippingDel = Tools::ps_round($order['total_shipping'],2);
|
|
$totalOrderDel = $TotalOrderProductsWithTaxes+$totalOrderShippingDel;
|
|
$totalAllOrdersDel=$totalAllOrdersDel+$totalOrderDel;
|
|
$totalAllOrderShippingDel=$totalAllOrderShippingDel+$totalOrderShippingDel;
|
|
$totalAllOrderTvaDel=$totalAllOrderTvaDel+($Order->getTotalProductsWithTaxes()-$Order->getTotalProductsWithoutTaxes());
|
|
$nbOrdersDel++;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Statistiques articles les plus vendus
|
|
*/
|
|
$ordersDetailBestSales = Db::getInstance()->ExecuteS(' SELECT SUM(od.`product_quantity`) as quantitySale, SUM(od.`product_price`) as priceSale, od.`product_id`,od.`product_name`,od.`tax_rate`,o.`id_order` FROM '._DB_PREFIX_ .'orders o
|
|
LEFT JOIN '._DB_PREFIX_ .'order_detail od ON o.`id_order`=od.`id_order`
|
|
WHERE o.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND o.`id_shop`="'.pSQL($this->context->shop->id).'"
|
|
GROUP BY od.`product_name`
|
|
ORDER BY quantitySale DESC
|
|
LIMIT 0,'.pSQL($topX));
|
|
$productsBestSales='<table class="table">
|
|
<tr>
|
|
<th>'.$this->l('Produit').'</th>
|
|
<th align="right">'.$this->l('Qte').'</th>
|
|
<th>'.$this->l('CA').'</th>
|
|
</tr>';
|
|
$rank = 1;
|
|
foreach($ordersDetailBestSales as $oDbS){
|
|
|
|
if(Tools::strlen($oDbS['product_name'])>Configuration::get('STATSEASY_NBCHARS_CUT') && Tools::getValue('export')=='pdf'){$productName=Tools::substr($oDbS['product_name'],0,Configuration::get('STATSEASY_NBCHARS_CUT')).'...';}else{$productName=$oDbS['product_name'];}
|
|
$productsBestSales .= '<tr>
|
|
<td class="medium">'.$rank++.'. '.$productName.'</td>
|
|
<td class="very_small" align="right">'.$oDbS['quantitySale'].'</td>
|
|
<td class="very_medium" align="right">'.Tools::displayPrice(($oDbS['priceSale']*$oDbS['tax_rate']/100)+$oDbS['priceSale'],$Currency).'</td>
|
|
</tr>';
|
|
}
|
|
// s'il manque des positions
|
|
$rankEmpty = $topX-count($ordersDetailBestSales);
|
|
if($rankEmpty>0){
|
|
for($i=1;$i<=$rankEmpty;$i++){
|
|
$productsBestSales .= '<tr><td class="medium">'.$rank++.'. -</td><td align="right" class="very_small">-</td><td align="right" class="very_medium">-</td></tr>';
|
|
}
|
|
}
|
|
$productsBestSales.='</table>';
|
|
|
|
/*
|
|
* Statistiques articles qui ont plus rapportés
|
|
*/
|
|
$ordersDetailMaxCash = Db::getInstance()->ExecuteS('SELECT
|
|
SUM(od.`product_quantity`) AS quantityMaxCash,
|
|
SUM(od.`product_price`) AS priceMaxCash,
|
|
od.`product_id`,od.`product_name`,o.`id_order`
|
|
FROM '._DB_PREFIX_ .'orders o
|
|
LEFT JOIN '._DB_PREFIX_ .'order_detail od ON o.`id_order`=od.`id_order`
|
|
WHERE o.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND o.`id_shop`="'.pSQL($this->context->shop->id).'"
|
|
GROUP BY od.`product_name`
|
|
ORDER BY priceMaxCash DESC
|
|
LIMIT 0,'.pSQL($topX));
|
|
|
|
$productsMaxCash='<table class="table">
|
|
<tr>
|
|
<th>'.$this->l('Produit').'</th>
|
|
<th align="right">'.$this->l('Qte').'</th>
|
|
<th>'.$this->l('CA').'</th>
|
|
</tr>';
|
|
$rank = 1;
|
|
foreach($ordersDetailMaxCash as $oDbC){
|
|
if(Tools::strlen($oDbC['product_name'])>Configuration::get('STATSEASY_NBCHARS_CUT') && Tools::getValue('export')=='pdf'){$productName=Tools::substr($oDbC['product_name'],0,Configuration::get('STATSEASY_NBCHARS_CUT')).'...';}else{$productName=$oDbC['product_name'];}
|
|
$productsMaxCash .= '<tr>
|
|
<td class="medium">'.$rank++.'. '.$productName.'</td>
|
|
<td class="very_small" align="right">'.$oDbC['quantityMaxCash'].'</td>
|
|
<td class="very_medium" align="right">'.Tools::displayPrice(($oDbC['priceMaxCash']*$oDbS['tax_rate']/100)+$oDbC['priceMaxCash'],$Currency).'</td>
|
|
</tr>';
|
|
}
|
|
// s'il manque des positions
|
|
$rankEmpty = $topX-count($ordersDetailMaxCash);
|
|
if($rankEmpty>0){
|
|
for($i=1;$i<=$rankEmpty;$i++){
|
|
$productsMaxCash .= '<tr><td class="medium">'.$rank++.'. -</td><td align="right" class="very_small">-</td><td align="right" class="very_medium">-</td></tr>';
|
|
}
|
|
}
|
|
$productsMaxCash.='</table>';
|
|
|
|
/*
|
|
* Statistiques des meilleurs clients
|
|
*/
|
|
$not_in_list = '';
|
|
foreach($orderStatesDelLst as $id_order_state){$not_in_list .= $id_order_state.',';}
|
|
foreach($orderStatesWaitLst as $id_order_state){$not_in_list .= $id_order_state.',';}
|
|
$ordersBestCustomers = Db::getInstance()->ExecuteS('SELECT SUM(o.`total_paid`) as totalPaid, COUNT(o.`id_customer`) AS ordersCustomer, o.`id_customer`
|
|
FROM `'._DB_PREFIX_ .'orders` o
|
|
LEFT JOIN `'._DB_PREFIX_ .'order_state` os ON (o.`current_state`=os.`id_order_state`)
|
|
WHERE o.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND o.`current_state` NOT IN('.pSQL(Tools::substr($not_in_list,0,-1)).')
|
|
AND o.`id_shop`="'.pSQL($this->context->shop->id).'"
|
|
GROUP BY o.`id_customer`
|
|
ORDER BY totalPaid DESC
|
|
LIMIT 0,'.pSQL($topX));
|
|
|
|
$bestCustomers ='<table class="table">
|
|
<tr>
|
|
<th>'.$this->l('Client').'</th>
|
|
<th align="right">'.$this->l('Cmdes').'</th>
|
|
<th>'.$this->l('CA').'</th>
|
|
</tr>';
|
|
$rank = 1;
|
|
foreach($ordersBestCustomers as $oBc){;
|
|
$Customer = new Customer($oBc['id_customer']);
|
|
$customer = $Customer->getFields();
|
|
$bestCustomers .= '<tr>
|
|
<td class="medium">'.$rank++.'. '.$customer['firstname'].' '.$customer['lastname'].'</td>
|
|
<td class="very_small" align="right">'.$oBc['ordersCustomer'].'</td>
|
|
<td class="very_medium" align="right">'.Tools::displayPrice($oBc['totalPaid'],$Currency).'</td>
|
|
</tr>';
|
|
}
|
|
// s'il manque des positions
|
|
$rankEmpty = $topX-count($ordersBestCustomers);
|
|
if($rankEmpty>0){
|
|
for($i=1;$i<=$rankEmpty;$i++){
|
|
$bestCustomers .= '<tr><td class="medium">'.$rank++.'. -</td><td align="right" class="very_small">-</td><td align="right" class="very_medium">-</td></tr>';
|
|
}
|
|
}
|
|
$bestCustomers.='</table>';
|
|
|
|
/* Statistiques visiteurs */
|
|
$totalGuests = Db::getInstance()->getValue('SELECT COUNT(DISTINCT c.`id_guest`) as nbGuests
|
|
FROM '._DB_PREFIX_ .'connections c
|
|
WHERE c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"'
|
|
);
|
|
$totalVisits = Db::getInstance()->getValue('SELECT COUNT(c.`id_guest`) as nbGuests
|
|
FROM '._DB_PREFIX_ .'connections c
|
|
WHERE c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"'
|
|
);
|
|
|
|
/* Statistiques provenance url des clients */
|
|
$referers = Db::getInstance()->ExecuteS('SELECT c.`http_referer`
|
|
FROM '._DB_PREFIX_ .'connections c
|
|
WHERE c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"'
|
|
);
|
|
$aReferers = array();
|
|
foreach($referers as $r){
|
|
$website = preg_replace('/^www./', '', parse_url($r['http_referer']), PHP_URL_HOST);
|
|
if(!empty($website['host'])){
|
|
@$aReferers[$website['host']]++;
|
|
}else{
|
|
@$aReferers[$this->l('Lien direct')]++;
|
|
}
|
|
}
|
|
arsort($aReferers);
|
|
// garde uniquement les X premiers resultats
|
|
$topXrefers = array();
|
|
$i=0;
|
|
foreach($aReferers as $site=>$visits){
|
|
$topXrefers[$site] = $visits;
|
|
$i++;
|
|
if($i>=$topX){break;}
|
|
}
|
|
$aReferers = $topXrefers;
|
|
|
|
$bestReferers = '<table class="table">
|
|
<tr>
|
|
<th>'.$this->l('Site').'</th>
|
|
<th>'.$this->l('Nb. visit.').'</th>
|
|
</tr>';
|
|
$rank = 1;
|
|
foreach($aReferers as $site=>$visits){
|
|
if(empty($r['http_referer'])){$r['http_referer']=$this->l('Lien direct');}
|
|
$bestReferers .= '<tr><td class="large">'.$rank++.'. '.$site.'</td><td align="right" class="small">'.$visits.'</td></tr>';
|
|
}
|
|
$rankEmpty = $topX-count($aReferers);
|
|
if($rankEmpty>0){
|
|
for($i=1;$i<=$rankEmpty;$i++){
|
|
$bestReferers .= '<tr><td class="large">'.$rank++.'. -</td><td align="right" class="small">-</td></tr>';
|
|
}
|
|
}
|
|
$bestReferers.='</table>';
|
|
|
|
/* Nombre de nouveaux clients inscrits */
|
|
$nbNewCustomers = Db::getInstance()->getValue('SELECT COUNT(c.`id_customer`) as nbCustomers
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
|
|
|
|
/* Sexe clients */
|
|
$nbCustomersH = Db::getInstance()->getValue('SELECT COUNT(c.`id_customer`) as nbCustomers
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`id_gender`=1
|
|
AND c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$nbCustomersF = Db::getInstance()->getValue('SELECT COUNT(c.`id_customer`) as nbCustomers
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`id_gender`=2
|
|
AND c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$nbCustomersI = Db::getInstance()->getValue('SELECT COUNT(c.`id_customer`) as nbCustomers
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`id_gender`=9
|
|
AND c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
$nbCustomers = $nbCustomersI+$nbCustomersH+$nbCustomersF;
|
|
// masque la division par 0
|
|
$nbCustomersHpercent = @Tools::ps_round($nbCustomersH/$nbCustomers*100,2);
|
|
$nbCustomersFpercent = @Tools::ps_round($nbCustomersF/$nbCustomers*100,2);
|
|
$nbCustomersIpercent = @Tools::ps_round($nbCustomersI/$nbCustomers*100,2);
|
|
|
|
/* Moyenne d'age clients */
|
|
$averageCustomerAgeG = Db::getInstance()->getValue('SELECT AVG(DATEDIFF(CURDATE(),c.`birthday`)/365) as averageCustomerAge
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`birthday` IS NOT NULL
|
|
AND c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
if(empty($averageCustomerAgeG)){$averageCustomerAgeG = '-';}
|
|
|
|
$averageCustomerAgeH = Db::getInstance()->getValue('SELECT AVG(DATEDIFF(CURDATE(),c.`birthday`)/365) as averageCustomerAge
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`birthday` IS NOT NULL
|
|
AND c.`id_gender`=1
|
|
AND c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
if(empty($averageCustomerAgeH)){$averageCustomerAgeH = '-';}
|
|
|
|
$averageCustomerAgeF = Db::getInstance()->getValue('SELECT AVG(DATEDIFF(CURDATE(),c.`birthday`)/365) as averageCustomerAge
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
WHERE c.`birthday` IS NOT NULL
|
|
AND c.`id_gender`=2
|
|
AND c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
if(empty($averageCustomerAgeF)){$averageCustomerAgeF = '-';}
|
|
|
|
/* Provenance clients */
|
|
$customersCountry = Db::getInstance()->ExecuteS('SELECT COUNT(a.`id_country`) AS nbIdCountry, a.`id_country`
|
|
FROM '._DB_PREFIX_ .'customer c
|
|
LEFT JOIN '._DB_PREFIX_ .'address a ON c.`id_customer`= a.`id_customer`
|
|
WHERE c.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND c.`id_shop`="'.pSQL($this->context->shop->id).'"
|
|
GROUP BY a.`id_country`
|
|
ORDER BY nbIdCountry DESC
|
|
LIMIT 0,'.pSQL($topX)
|
|
);
|
|
$bestCustomersCountry = '<table class="table">
|
|
<tr>
|
|
<th>'.$this->l('Pays').'</th>
|
|
<th>'.$this->l('Nb. clients').'</th>
|
|
</tr>';
|
|
$rank = 1;
|
|
foreach($customersCountry as $cc){
|
|
$Country = new Country($cc['id_country']);
|
|
$bestCustomersCountry .= '<tr><td class="large">'.$rank++.'. '.$Country->name[$cookie->id_lang].'</td><td align="right" class="small">'.$cc['nbIdCountry'].'</td></tr>';
|
|
}
|
|
$rankEmpty = $topX-count($customersCountry);
|
|
if($rankEmpty>0){
|
|
for($i=1;$i<=$rankEmpty;$i++){
|
|
$bestCustomersCountry .= '<tr><td class="large">'.$rank++.'. -</td><td align="right" class="small">-</td></tr>';
|
|
}
|
|
}
|
|
$bestCustomersCountry .= '</table>';
|
|
|
|
/* Top recherches */
|
|
$topSearch = Db::getInstance()->ExecuteS('SELECT COUNT(s.`keywords`) as topKeywords, s.`keywords`
|
|
FROM '._DB_PREFIX_ .'statssearch s
|
|
WHERE s.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND s.`id_shop`="'.pSQL($this->context->shop->id).'"
|
|
GROUP BY s.`keywords`
|
|
ORDER BY topKeywords DESC
|
|
LIMIT 0,'.pSQL($topX)
|
|
);
|
|
$bestSearch = '<table class="table">
|
|
<tr>
|
|
<th>'.$this->l('Mot clé').'</th>
|
|
<th>'.$this->l('Nb. rech.').'</th>
|
|
</tr>';
|
|
$rank = 1;
|
|
foreach($topSearch as $s){
|
|
$bestSearch .= '<tr><td class="large">'.$rank++.'. '.$s['keywords'].'</td><td align="right" class="small">'.$s['topKeywords'].'</td></tr>';
|
|
}
|
|
$rankEmpty = $topX-count($topSearch);
|
|
if($rankEmpty>0){
|
|
for($i=1;$i<=$rankEmpty;$i++){
|
|
$bestSearch .= '<tr><td class="large">'.$rank++.'. -</td><td align="right" class="small">-</td></tr>';
|
|
}
|
|
}
|
|
$bestSearch .= '</table>';
|
|
|
|
// Taux de transformation
|
|
$nbOrders = Db::getInstance()->getValue('SELECT COUNT(o.`id_order`) as nbOrders
|
|
FROM '._DB_PREFIX_ .'orders o
|
|
WHERE o.`date_add` BETWEEN "'.pSQL($date_start).' 00:00:00" AND "'.pSQL($date_end).' 23:59:59"
|
|
AND o.`id_shop`="'.pSQL($this->context->shop->id).'"');
|
|
|
|
$conversionRate = ($nbOrders/$totalGuests)*100;
|
|
$conversionRate = $this->l('Nbre de commandes').' ('.$nbOrders.') / '.$this->l('Nbre total visiteurs').' ('.$totalGuests.') = '.Tools::ps_round($conversionRate,2).' % '.
|
|
'('.$this->l('Légende').' : < 1% '.$this->l('améliorable').', '.
|
|
' > 1% '.$this->l('correct').', '.
|
|
' > 3% '.$this->l('excellent').')';
|
|
|
|
$tableStats = '';
|
|
$tableStats .=
|
|
'<table id="table1">
|
|
<tr>
|
|
<td>
|
|
<table id="table_date" class="table">
|
|
<tr>
|
|
<th colspan="2" class="date">'.$this->l('Période concernée').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="very_small">'.$this->l('Date').'</td>
|
|
<td class="medium" align="right">'.$Statseasy->dateUsToFr($date_start).' '.$this->l('au').' '.$Statseasy->dateUsToFr($date_end).'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table id="table_conversion" class="table">
|
|
<tr>
|
|
<th class="date">'.$this->l('Taux de transformation').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="conversion_rate">'.$conversionRate.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table id="table2">
|
|
<tr>
|
|
<td class="shop_info" align="center">';
|
|
$Shop = new Shop(Shop::getContextShopID());
|
|
$logo = '<img src="'.$Shop->getBaseURL().'img/'.Configuration::get('PS_LOGO').'" />';
|
|
$shop_info = '';
|
|
$shop_info = Configuration::get('PS_SHOP_NAME').'<br/>'.
|
|
Tools::getHttpHost(true).__PS_BASE_URI__.'<br/>'.
|
|
Configuration::get('PS_SHOP_EMAIL');
|
|
$tableStats.=
|
|
$logo.'<br/>'.
|
|
$shop_info.'
|
|
</td>
|
|
<td>
|
|
<table id="table_trafic_customer" class="table">
|
|
<tr>
|
|
<th colspan="3" class="th_important">'.$this->l('Trafic & Clients').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th colspan="2">'.$this->l('Fréquentation').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total de visites').'</td>
|
|
<td class="small" align="right">'.$totalVisits.'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total de visiteurs').'</td>
|
|
<td class="small" align="right">'.$totalGuests.'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Nouveaux client inscrits').'</td>
|
|
<td class="small" align="right">'.$nbNewCustomers.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th colspan="2">'.$this->l('Age clients').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Tous').'</td>
|
|
<td class="small" align="right">'.Tools::ps_round($averageCustomerAgeG,2).' '.$this->l('ans').'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Hommes').'</td>
|
|
<td class="small" align="right">'.Tools::ps_round($averageCustomerAgeH,2).' '.$this->l('ans').'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Femmes').'</td>
|
|
<td class="small" align="right">'.Tools::ps_round($averageCustomerAgeF,2).' '.$this->l('ans').'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th colspan="2">'.$this->l('Sexe clients').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Hommes').'</td>
|
|
<td class="small" align="right">'.$nbCustomersHpercent.' % </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Femmes').'</td>
|
|
<td class="small" align="right">'.$nbCustomersFpercent.' % </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Inconnu').'</td>
|
|
<td class="small" align="right">'.$nbCustomersIpercent.' %</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table class="table" id="table_finance">
|
|
<tr>
|
|
<th colspan="3" class="th_important">'.$this->l('Finances').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th colspan="2">'.$this->l('Commandes payées').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Nombre de commandes').'</td>
|
|
<td class="small" align="right">'.$nbOrdersPaid.'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total bons de réduction').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrdersReducPaid,$Currency).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total CA').'</td>
|
|
<td class="small" align="right"><span class="txt_good">'.Tools::displayPrice($totalAllOrdersPaid,$Currency).'</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total frais de port').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrderShippingPaid,$Currency).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total taxes / TVA').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrderTvaPaid,$Currency).'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th colspan="2">'.$this->l('Commandes en attente de paiement').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Nombre de commandes').'</td>
|
|
<td class="small" align="right">'.$nbOrdersWait.'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total bons de réduction').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrdersReducWait,$Currency).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total CA').'</td>
|
|
<td class="small" align="right"><span class="txt_wait">'.Tools::displayPrice($totalAllOrdersWait,$Currency).'</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total frais de port').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrderShippingWait,$Currency).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total taxes / TVA').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrderTvaWait,$Currency).'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th colspan="2">'.$this->l('Commandes rejetées').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Nombre de commandes').'</td>
|
|
<td class="small" align="right">'.$nbOrdersDel.'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total bons de réduction').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrdersReducDel,$Currency).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total perte CA').'</td>
|
|
<td class="small" align="right"><span class="txt_bad">'.Tools::displayPrice($totalAllOrdersDel,$Currency).'</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total frais de port').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrderShippingDel,$Currency).'</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="medium">'.$this->l('Total taxes / TVA').'</td>
|
|
<td class="small" align="right">'.Tools::displayPrice($totalAllOrderTvaDel,$Currency).'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table id="table_best_sales">
|
|
<tr>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th class="th_important" colspan="2">'.$this->l('Les').' '.$topX.' '.$this->l('produits les plus vendus').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td>'.$productsBestSales.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr><th class="th_important" colspan="2">'.$this->l('Les').' '.$topX.' '.$this->l('produits les plus rémunérateurs').'</th></tr>
|
|
<tr>
|
|
<td>'.$productsMaxCash.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr><th class="th_important" colspan="2">'.$this->l('Les').' '.$topX.' '.$this->l('meilleurs clients').'</th></tr>
|
|
<tr>
|
|
<td>'.$bestCustomers.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th class="th_important" colspan="2">'.$this->l('Site de provenances').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td>'.$bestReferers.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th class="th_important" colspan="2">'.$this->l('Origine des clients').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td>'.$bestCustomersCountry.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<table class="table">
|
|
<tr>
|
|
<th class="th_important" colspan="2">'.$this->l('Les').' '.$topX.' '.$this->l('recherches populaires').'</th>
|
|
</tr>
|
|
<tr>
|
|
<td>'.$bestSearch.'</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>';
|
|
$this->_html .= $tableStats;
|
|
|
|
$this->_html.= '</div>'; // end panel
|
|
|
|
}
|
|
|
|
// pdf
|
|
if(Tools::getValue('export')=='pdf'){
|
|
ob_clean();
|
|
ini_set('display_errors','on');
|
|
require_once(_PS_ROOT_DIR_.'/modules/statseasy/libraries/html2pdf/html2pdf.class.php');
|
|
$Html2Pdf = new Html2Pdf('P','A4','fr');
|
|
$tableStats = '<link type="text/css" rel="stylesheet" href="'.dirname(__FILE__).'/css/pdf.css" />
|
|
<page orientation="paysage" format="A4">
|
|
'.$tableStats.'
|
|
</page>';
|
|
$Html2Pdf->WriteHTML($tableStats);
|
|
$Html2Pdf->Output($Statseasy->hyphen('stats_'.$date_start.'_-_'.$date_end).'.pdf');
|
|
}
|
|
echo $this->_html;
|
|
}
|
|
|
|
}
|
|
?>
|