* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class statsproduct extends ModuleGraph
{
private $html = '';
private $query = [];
private $option = 0;
private $id_product = 0;
public function __construct()
{
$this->name = 'statsproduct';
$this->tab = 'administration';
$this->version = '2.1.3';
$this->author = 'PrestaShop';
$this->need_instance = 0;
parent::__construct();
$this->displayName = $this->trans('Product details', [], 'Modules.Statsproduct.Admin');
$this->description = $this->trans('Enrich your stats, add detailed statistics for each product of your catalog.', [], 'Modules.Statsproduct.Admin');
$this->ps_versions_compliancy = ['min' => '1.7.6.0', 'max' => _PS_VERSION_];
}
public function install()
{
return parent::install() && $this->registerHook('displayAdminStatsModules');
}
public function getTotalBought($id_product)
{
$date_between = ModuleGraph::getDateBetween();
$sql = 'SELECT SUM(od.`product_quantity`) AS total
FROM `' . _DB_PREFIX_ . 'order_detail` od
LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON o.`id_order` = od.`id_order`
WHERE od.`product_id` = ' . (int) $id_product . '
' . Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o') . '
AND o.valid = 1
AND o.`date_add` BETWEEN ' . $date_between;
return (int) Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getValue($sql);
}
public function getTotalSales($id_product)
{
$date_between = ModuleGraph::getDateBetween();
$sql = 'SELECT SUM(od.`total_price_tax_excl`) AS total
FROM `' . _DB_PREFIX_ . 'order_detail` od
LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON o.`id_order` = od.`id_order`
WHERE od.`product_id` = ' . (int) $id_product . '
' . Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o') . '
AND o.valid = 1
AND o.`date_add` BETWEEN ' . $date_between;
return (float) Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getValue($sql);
}
public function getTotalViewed($id_product)
{
$date_between = ModuleGraph::getDateBetween();
$sql = 'SELECT SUM(pv.`counter`) AS total
FROM `' . _DB_PREFIX_ . 'page_viewed` pv
LEFT JOIN `' . _DB_PREFIX_ . 'date_range` dr ON pv.`id_date_range` = dr.`id_date_range`
LEFT JOIN `' . _DB_PREFIX_ . 'page` p ON pv.`id_page` = p.`id_page`
LEFT JOIN `' . _DB_PREFIX_ . 'page_type` pt ON pt.`id_page_type` = p.`id_page_type`
WHERE pt.`name` = \'product\'
' . Shop::addSqlRestriction(false, 'pv') . '
AND p.`id_object` = ' . (int) $id_product . '
AND dr.`time_start` BETWEEN ' . $date_between . '
AND dr.`time_end` BETWEEN ' . $date_between;
$result = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getRow($sql);
return isset($result['total']) ? $result['total'] : 0;
}
private function getProducts($id_lang)
{
$sql = 'SELECT p.`id_product`, p.reference, pl.`name`, IFNULL(stock.quantity, 0) as quantity
FROM `' . _DB_PREFIX_ . 'product` p
' . Product::sqlStock('p', 0) . '
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON p.`id_product` = pl.`id_product`' . Shop::addSqlRestrictionOnLang('pl') . '
' . Shop::addSqlAssociation('product', 'p') . '
' . (Tools::getValue('id_category') ? 'LEFT JOIN `' . _DB_PREFIX_ . 'category_product` cp ON p.`id_product` = cp.`id_product`' : '') . '
WHERE pl.`id_lang` = ' . (int) $id_lang . '
' . (Tools::getValue('id_category') ? 'AND cp.id_category = ' . (int) Tools::getValue('id_category') : '');
if (version_compare(_PS_VERSION_, '1.7.0.0', '>=')) {
$sql .= ' AND p.state = ' . Product::STATE_SAVED;
}
$sql .= ' ORDER BY pl.`name`';
return Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS($sql);
}
private function getSales($id_product)
{
$sql = 'SELECT o.date_add, o.id_order, o.id_customer, od.product_quantity, (od.unit_price_tax_excl * od.product_quantity) as total, od.tax_name, od.product_name
FROM `' . _DB_PREFIX_ . 'orders` o
LEFT JOIN `' . _DB_PREFIX_ . 'order_detail` od ON o.id_order = od.id_order
WHERE o.date_add BETWEEN ' . $this->getDate() . '
' . Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o') . '
AND o.valid = 1
AND od.product_id = ' . (int) $id_product;
return Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS($sql);
}
private function getCrossSales($id_product, $id_lang)
{
$sql = 'SELECT pl.name as pname, pl.id_product, SUM(od.product_quantity) as pqty, AVG(od.unit_price_tax_excl) as pprice
FROM `' . _DB_PREFIX_ . 'orders` o
LEFT JOIN `' . _DB_PREFIX_ . 'order_detail` od ON o.id_order = od.id_order
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.id_product = od.product_id AND pl.id_lang = ' . (int) $id_lang . Shop::addSqlRestrictionOnLang('pl') . ')
WHERE o.id_customer IN (
SELECT o.id_customer
FROM `' . _DB_PREFIX_ . 'orders` o
LEFT JOIN `' . _DB_PREFIX_ . 'order_detail` od ON o.id_order = od.id_order
WHERE o.date_add BETWEEN ' . $this->getDate() . '
AND o.valid = 1
AND od.product_id = ' . (int) $id_product . '
)
' . Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o') . '
AND o.date_add BETWEEN ' . $this->getDate() . '
AND o.valid = 1
AND od.product_id != ' . (int) $id_product . '
GROUP BY od.product_id
ORDER BY pqty DESC';
return Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS($sql);
}
public function hookDisplayAdminStatsModules()
{
$id_category = (int) Tools::getValue('id_category');
$currency = Context::getContext()->currency;
if (Tools::getValue('export')) {
if (!Tools::getValue('exportType')) {
$this->csvExport([
'layers' => 2,
'type' => 'line',
'option' => '42',
]);
}
}
$this->html = '
' . $this->displayName . '
' . $this->trans('Guide', [], 'Admin.Global') . '
' . $this->trans('Number of purchases compared to number of views', [], 'Modules.Statsproduct.Admin') . '
' . $this->trans('After choosing a category and selecting a product, informational graphs will appear.', [], 'Modules.Statsproduct.Admin') . '
' . $this->trans('If you notice that a product is often purchased but viewed infrequently, you should display it more prominently in your Front Office.', [], 'Modules.Statsproduct.Admin') . '
' . $this->trans('On the other hand, if a product has many views but is not often purchased, we advise you to check or modify this product\'s information, description and photography again, see if you can find something better.', [], 'Modules.Statsproduct.Admin') . '