* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision: 7104 $
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_'))
exit;
class StatsForecast extends Module
{
private $_html = '';
private $t1 = 0;
private $t2 = 0;
private $t3 = 0;
private $t4 = 0;
private $t5 = 0;
private $t6 = 0;
private $t7 = 0;
private $t8 = 0;
public function __construct()
{
$this->name = 'statsforecast';
$this->tab = 'analytics_stats';
$this->version = 1.0;
$this->author = 'PrestaShop';
$this->need_instance = 0;
parent::__construct();
$this->displayName = $this->l('Stats Dashboard');
$this->description = '';
}
public function install()
{
return (parent::install() && $this->registerHook('AdminStatsModules'));
}
public function getContent()
{
Tools::redirectAdmin('index.php?tab=AdminStats&module=statsforecast&token='.Tools::getAdminTokenLite('AdminStats'));
}
public function hookAdminStatsModules()
{
$ru = AdminTab::$currentIndex.'&module='.$this->name.'&token='.Tools::getValue('token');
$db = Db::getInstance();
if (!isset($this->context->cookie->stats_granularity))
$this->context->cookie->stats_granularity = 10;
if (Tools::isSubmit('submitIdZone'))
$this->context->cookie->stats_id_zone = (int)Tools::getValue('stats_id_zone');
if (Tools::isSubmit('submitGranularity'))
$this->context->cookie->stats_granularity = Tools::getValue('stats_granularity');
$currency = $this->context->currency;
$employee = $this->context->employee;
// @todo use PHP functions to get timestamp ...
$result = $db->getRow('SELECT UNIX_TIMESTAMP(\'2009-06-05 00:00:00\') as t1, UNIX_TIMESTAMP(\''.$employee->stats_date_from.' 00:00:00\') as t2');
$from = max($result['t1'], $result['t2']);
$to = strtotime($employee->stats_date_to.' 23:59:59');
$result2 = $db->getRow('SELECT UNIX_TIMESTAMP(NOW()) as t1, UNIX_TIMESTAMP(\''.$employee->stats_date_to.' 23:59:59\') as t2');
$to2 = min($result2['t1'], $result2['t2']);
$interval = ($to - $from) / 60 / 60 / 24;
$interval2 = ($to2 - $from) / 60 / 60 / 24;
$prop30 = $interval / $interval2;
if ($this->context->cookie->stats_granularity == 7)
$intervalAvg = $interval2 / 30;
if ($this->context->cookie->stats_granularity == 4)
$intervalAvg = $interval2 / 365;
if ($this->context->cookie->stats_granularity == 10)
$intervalAvg = $interval2;
if ($this->context->cookie->stats_granularity == 42)
$intervalAvg = $interval2 / 7;
define('PS_BASE_URI', '/');
$result = $db->getRow('SELECT UNIX_TIMESTAMP(\'2009-06-05\') as t1, UNIX_TIMESTAMP(\''.$employee->stats_date_from.'\') as t2');
$from = max($result['t1'], $result['t2']);
$to = strtotime($employee->stats_date_to.'');
$dateFromGAdd = ($this->context->cookie->stats_granularity != 42
? 'SUBSTRING(date_add, 1, '.(int)$this->context->cookie->stats_granularity.')'
: 'IFNULL(MAKEDATE(YEAR(date_add),DAYOFYEAR(date_add)-WEEKDAY(date_add)), CONCAT(YEAR(date_add),"-01-01*"))');
$dateFromGInvoice = ($this->context->cookie->stats_granularity != 42
? 'SUBSTRING(invoice_date, 1, '.(int)$this->context->cookie->stats_granularity.')'
: 'IFNULL(MAKEDATE(YEAR(invoice_date),DAYOFYEAR(invoice_date)-WEEKDAY(invoice_date)), CONCAT(YEAR(invoice_date),"-01-01*"))');
$sql = 'SELECT
'.$dateFromGInvoice.' as fix_date,
COUNT(DISTINCT o.id_order) as countOrders,
SUM(od.product_quantity) as countProducts,
SUM(od.product_price * od.product_quantity / o.conversion_rate) as totalProducts
FROM '._DB_PREFIX_.'orders o
LEFT JOIN '._DB_PREFIX_.'order_detail od ON o.id_order = od.id_order
LEFT JOIN '._DB_PREFIX_.'product p ON od.product_id = p.id_product
WHERE o.valid = 1
AND o.invoice_date BETWEEN '.ModuleGraph::getDateBetween().'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o').'
GROUP BY '.$dateFromGInvoice.'
ORDER BY fix_date';
$result = $db->executeS($sql, false);
$dataTable = array();
if ($this->context->cookie->stats_granularity == 10)
{
$dateEnd = strtotime($employee->stats_date_to.' 23:59:59');
$dateToday = time();
for ($i = strtotime($employee->stats_date_from.' 00:00:00'); $i <= $dateEnd AND $i <= $dateToday; $i += 86400)
$dataTable[$i] = array('fix_date' => date('Y-m-d', $i), 'countOrders' => 0, 'countProducts' => 0, 'totalProducts' => 0);
}
while ($row = $db->nextRow($result))
$dataTable[strtotime($row['fix_date'])] = $row;
$this->_html .= '
';
$ca = $this->getRealCA();
$sql = 'SELECT COUNT(DISTINCT c.id_guest)
FROM '._DB_PREFIX_.'connections c
WHERE c.date_add BETWEEN '.ModuleGraph::getDateBetween()
.$this->sqlShopRestriction(false, 'c');
$visitors = Db::getInstance()->getValue($sql);
$sql = 'SELECT COUNT(DISTINCT g.id_customer)
FROM '._DB_PREFIX_.'connections c
INNER JOIN '._DB_PREFIX_.'guest g ON c.id_guest = g.id_guest
WHERE g.id_customer != 0
AND c.date_add BETWEEN '.ModuleGraph::getDateBetween()
.$this->sqlShopRestriction(false, 'c');
$customers = Db::getInstance()->getValue($sql);
$sql = 'SELECT COUNT(*)
FROM '._DB_PREFIX_.'cart
WHERE id_cart IN (
SELECT id_cart FROM '._DB_PREFIX_.'cart_product
) AND (
date_add BETWEEN '.ModuleGraph::getDateBetween().' OR date_upd BETWEEN '.ModuleGraph::getDateBetween().'
)'.$this->sqlShopRestriction();
$carts = Db::getInstance()->getValue($sql);
$sql = 'SELECT COUNT(*)
FROM '._DB_PREFIX_.'cart
WHERE id_cart IN (
SELECT id_cart FROM '._DB_PREFIX_.'cart_product
) AND id_address_invoice != 0
AND (
date_add BETWEEN '.ModuleGraph::getDateBetween().' OR date_upd BETWEEN '.ModuleGraph::getDateBetween().'
)'.$this->sqlShopRestriction();
$fullcarts = Db::getInstance()->getValue($sql);
$sql = 'SELECT COUNT(*)
FROM '._DB_PREFIX_.'orders o
WHERE o.valid = 1
AND o.date_add BETWEEN '.ModuleGraph::getDateBetween()
.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o');
$orders = Db::getInstance()->getValue($sql);
$this->_html .= '
';
return $this->_html;
}
private function getRealCA()
{
$employee = $this->context->employee;
$ca = array();
$where = $join = '';
if ((int)$this->context->cookie->stats_id_zone)
{
$join = ' LEFT JOIN `'._DB_PREFIX_.'address` a ON o.id_address_invoice = a.id_address LEFT JOIN `'._DB_PREFIX_.'country` co ON co.id_country = a.id_country';
$where = ' AND co.id_zone = '.(int)$this->context->cookie->stats_id_zone.' ';
}
$sql = 'SELECT SUM(od.`product_price` * od.`product_quantity` / o.conversion_rate) as orderSum, COUNT(*) AS orderQty, cl.name, AVG(od.`product_price` / o.conversion_rate) as priveAvg
FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
LEFT JOIN `'._DB_PREFIX_.'product` p ON p.id_product = od.product_id
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.id_category_default = cl.id_category AND cl.id_lang = '.(int)$this->context->language->id.$this->context->shop->addSqlRestrictionOnLang('cl').')
'.$join.'
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$where.'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o').'
GROUP BY p.id_category_default';
$ca['cat'] = Db::getInstance()->executeS($sql);
uasort($ca['cat'], 'statsforecast_sort');
$langValues = '';
$sql = 'SELECT l.id_lang, l.iso_code
FROM `'._DB_PREFIX_.'lang` l
'.$this->context->shop->addSqlAssociation('lang', 'l').'
WHERE l.active = 1';
$languages = Db::getInstance()->executeS($sql);
foreach ($languages as $language)
$langValues .= 'SUM(IF(o.id_lang = '.(int)$language['id_lang'].', total_products / o.conversion_rate, 0)) as '.pSQL($language['iso_code']).',';
$langValues = rtrim($langValues, ',');
if ($langValues)
{
$sql = 'SELECT '.$langValues.'
FROM `'._DB_PREFIX_.'orders` o
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o');
$ca['lang'] = Db::getInstance()->getRow($sql);
arsort($ca['lang']);
$sql = 'SELECT '.$langValues.'
FROM `'._DB_PREFIX_.'orders` o
WHERE o.valid = 1
AND ADDDATE(o.`invoice_date`, interval 30 day) BETWEEN \''.$employee->stats_date_from.' 00:00:00\' AND \''.min(date('Y-m-d H:i:s'), $employee->stats_date_to.' 23:59:59').'\'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o');
$ca['langprev'] = Db::getInstance()->getRow($sql);
}
else
{
$ca['lang'] = array();
$ca['langprev'] = array();
}
$sql = 'SELECT module, SUM(total_products / o.conversion_rate) as total, COUNT(*) as nb, AVG(total_products / o.conversion_rate) as cart
FROM `'._DB_PREFIX_.'orders` o
'.$join.'
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$where.'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o').'
GROUP BY o.module
ORDER BY total DESC';
$ca['payment'] = Db::getInstance()->executeS($sql);
$sql = 'SELECT z.name, SUM(o.total_products / o.conversion_rate) as total, COUNT(*) as nb
FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'address` a ON o.id_address_invoice = a.id_address
LEFT JOIN `'._DB_PREFIX_.'country` c ON c.id_country = a.id_country
LEFT JOIN `'._DB_PREFIX_.'zone` z ON z.id_zone = c.id_zone
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o').'
GROUP BY c.id_zone
ORDER BY total DESC';
$ca['zones'] = Db::getInstance()->executeS($sql);
$sql = 'SELECT cu.name, SUM(o.total_products / o.conversion_rate) as total, COUNT(*) as nb
FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'currency` cu ON o.id_currency = cu.id_currency
'.$join.'
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$where.'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o').'
GROUP BY o.id_currency
ORDER BY total DESC';
$ca['currencies'] = Db::getInstance()->executeS($sql);
$sql = 'SELECT SUM(total_products / o.conversion_rate) as total, COUNT(*) AS nb
FROM `'._DB_PREFIX_.'orders` o
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o');
$ca['ventil'] = Db::getInstance()->getRow($sql);
$sql = 'SELECT /*pac.id_attribute,*/ agl.name as gname, al.name as aname, COUNT(*) as total
FROM '._DB_PREFIX_.'orders o
LEFT JOIN '._DB_PREFIX_.'order_detail od ON o.id_order = od.id_order
INNER JOIN '._DB_PREFIX_.'product_attribute_combination pac ON od.product_attribute_id = pac.id_product_attribute
INNER JOIN '._DB_PREFIX_.'attribute a ON pac.id_attribute = a.id_attribute
INNER JOIN '._DB_PREFIX_.'attribute_group_lang agl ON (a.id_attribute_group = agl.id_attribute_group AND agl.id_lang = '.(int)$this->context->language->id.')
INNER JOIN '._DB_PREFIX_.'attribute_lang al ON (a.id_attribute = al.id_attribute AND al.id_lang = '.(int)$this->context->language->id.')
WHERE o.valid = 1
AND o.`invoice_date` BETWEEN '.ModuleGraph::getDateBetween().'
'.$this->sqlShopRestriction(Shop::SHARE_ORDER, 'o').'
GROUP BY pac.id_attribute';
$ca['attributes'] = Db::getInstance()->executeS($sql);
return $ca;
}
}
function statsforecast_sort($a, $b)
{
if ($a['orderSum'] == $b['orderSum'])
return 0;
return ($a['orderSum'] > $b['orderSum']) ? -1 : 1;
}