* @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 statscheckup extends Module { private $html = ''; public function __construct() { $this->name = 'statscheckup'; $this->tab = 'administration'; $this->version = '2.0.3'; $this->author = 'PrestaShop'; $this->need_instance = 0; parent::__construct(); $this->displayName = $this->trans('Catalog evaluation', [], 'Modules.Statscheckup.Admin'); $this->description = $this->trans('Enrich your stats, give your catalog a quick evaluation to better analyze your activity.', [], 'Modules.Statscheckup.Admin'); $this->ps_versions_compliancy = ['min' => '1.7.1.0', 'max' => _PS_VERSION_]; } public function install() { $confs = [ 'CHECKUP_DESCRIPTIONS_LT' => 100, 'CHECKUP_DESCRIPTIONS_GT' => 400, 'CHECKUP_IMAGES_LT' => 1, 'CHECKUP_IMAGES_GT' => 2, 'CHECKUP_SALES_LT' => 1, 'CHECKUP_SALES_GT' => 2, 'CHECKUP_STOCK_LT' => 1, 'CHECKUP_STOCK_GT' => 3, ]; foreach ($confs as $confname => $confdefault) { if (!Configuration::get($confname)) { Configuration::updateValue($confname, (int) $confdefault); } } return parent::install() && $this->registerHook('displayAdminStatsModules'); } public function hookDisplayAdminStatsModules() { if (Tools::isSubmit('submitCheckup')) { $confs = [ 'CHECKUP_DESCRIPTIONS_LT', 'CHECKUP_DESCRIPTIONS_GT', 'CHECKUP_IMAGES_LT', 'CHECKUP_IMAGES_GT', 'CHECKUP_SALES_LT', 'CHECKUP_SALES_GT', 'CHECKUP_STOCK_LT', 'CHECKUP_STOCK_GT', ]; foreach ($confs as $confname) { Configuration::updateValue($confname, (int) Tools::getValue($confname)); } echo '
' . $this->trans('Settings updated', [], 'Admin.Global') . '
'; } if (Tools::isSubmit('submitCheckupOrder')) { $this->context->cookie->checkup_order = (int) Tools::getValue('submitCheckupOrder'); echo '
' . $this->trans('Settings updated', [], 'Admin.Global') . '
'; } if (!isset($this->context->cookie->checkup_order)) { $this->context->cookie->checkup_order = 1; } $db = Db::getInstance((bool) _PS_USE_SQL_SLAVE_); $employee = Context::getContext()->employee; $prop30 = ((strtotime($employee->stats_date_to . ' 23:59:59') - strtotime($employee->stats_date_from . ' 00:00:00')) / 60 / 60 / 24) / 30; // Get languages $sql = 'SELECT l.* FROM ' . _DB_PREFIX_ . 'lang l' . Shop::addSqlAssociation('lang', 'l'); $languages = $db->executeS($sql); $array_colors = [ 0 => '' . $this->trans('Bad', [], 'Modules.Statscheckup.Admin') . '', 1 => '' . $this->trans('Average', [], 'Modules.Statscheckup.Admin') . '', 2 => '' . $this->trans('Good', [], 'Modules.Statscheckup.Admin') . '', ]; $token_products = Tools::getAdminToken('AdminProducts' . (int) Tab::getIdFromClassName('AdminProducts') . (int) Context::getContext()->employee->id); $divisor = 4; $totals = ['products' => 0, 'active' => 0, 'images' => 0, 'sales' => 0, 'stock' => 0]; foreach ($languages as $language) { ++$divisor; $totals['description_' . $language['iso_code']] = 0; } $order_by = 'p.id_product'; if ($this->context->cookie->checkup_order == 2) { $order_by = 'pl.name'; } elseif ($this->context->cookie->checkup_order == 3) { $order_by = 'nbSales DESC'; } // Get products stats $sql = 'SELECT p.id_product, product_shop.active, pl.name, ( SELECT COUNT(*) FROM ' . _DB_PREFIX_ . 'image i ' . Shop::addSqlAssociation('image', 'i') . ' WHERE i.id_product = p.id_product ) as nbImages, ( SELECT SUM(od.product_quantity) FROM ' . _DB_PREFIX_ . 'orders o LEFT JOIN ' . _DB_PREFIX_ . 'order_detail od ON o.id_order = od.id_order WHERE od.product_id = p.id_product AND o.invoice_date BETWEEN ' . ModuleGraph::getDateBetween() . ' ' . Shop::addSqlRestriction(Shop::SHARE_ORDER, 'o') . ' ) as nbSales, IFNULL(stock.quantity, 0) as stock FROM ' . _DB_PREFIX_ . 'product p ' . Shop::addSqlAssociation('product', 'p') . ' ' . Product::sqlStock('p', 0) . ' LEFT JOIN ' . _DB_PREFIX_ . 'product_lang pl ON (p.id_product = pl.id_product AND pl.id_lang = ' . (int) $this->context->language->id . Shop::addSqlRestrictionOnLang('pl') . ') ORDER BY ' . $order_by; $result = $db->executeS($sql); if (!$result) { return $this->trans('No product was found.', [], 'Modules.Statscheckup.Admin'); } $array_conf = [ 'DESCRIPTIONS' => ['name' => $this->trans('Descriptions', [], 'Modules.Statscheckup.Admin'), 'text' => $this->trans('chars (without HTML)', [], 'Modules.Statscheckup.Admin')], 'IMAGES' => ['name' => $this->trans('Images', [], 'Admin.Global'), 'text' => $this->trans('images', [], 'Admin.Global')], 'SALES' => ['name' => $this->trans('Sales', [], 'Admin.Global'), 'text' => $this->trans('orders / month', [], 'Modules.Statscheckup.Admin')], 'STOCK' => ['name' => $this->trans('Available quantity for sale', [], 'Admin.Global'), 'text' => $this->trans('items', [], 'Modules.Statscheckup.Admin')], ]; $this->html = '
' . $this->displayName . '
'; foreach ($array_conf as $conf => $translations) { $this->html .= ' '; } $this->html .= '
' . $array_colors[0] . ' ' . $this->trans('Not enough', [], 'Modules.Statscheckup.Admin') . ' ' . $array_colors[2] . ' ' . $this->trans('Alright', [], 'Modules.Statscheckup.Admin') . '
' . $this->trans('Less than', [], 'Modules.Statscheckup.Admin') . ' ' . $translations['text'] . '
' . $this->trans('Greater than', [], 'Modules.Statscheckup.Admin') . ' ' . $translations['text'] . '
'; foreach ($languages as $language) { $this->html .= ''; } $this->html .= ' '; foreach ($result as $row) { ++$totals['products']; $scores = [ 'active' => ($row['active'] ? 2 : 0), 'images' => ($row['nbImages'] < Configuration::get('CHECKUP_IMAGES_LT') ? 0 : ($row['nbImages'] > Configuration::get('CHECKUP_IMAGES_GT') ? 2 : 1)), 'sales' => (($row['nbSales'] * $prop30 < Configuration::get('CHECKUP_SALES_LT')) ? 0 : (($row['nbSales'] * $prop30 > Configuration::get('CHECKUP_SALES_GT')) ? 2 : 1)), 'stock' => (($row['stock'] < Configuration::get('CHECKUP_STOCK_LT')) ? 0 : (($row['stock'] > Configuration::get('CHECKUP_STOCK_GT')) ? 2 : 1)), ]; $totals['active'] += (int) $scores['active']; $totals['images'] += (int) $scores['images']; $totals['sales'] += (int) $scores['sales']; $totals['stock'] += (int) $scores['stock']; $descriptions = $db->executeS(' SELECT l.iso_code, pl.description FROM ' . _DB_PREFIX_ . 'product_lang pl LEFT JOIN ' . _DB_PREFIX_ . 'lang l ON pl.id_lang = l.id_lang WHERE id_product = ' . (int) $row['id_product'] . Shop::addSqlRestrictionOnLang('pl')); foreach ($descriptions as $description) { if (isset($description['iso_code']) && isset($description['description'])) { $row['desclength_' . $description['iso_code']] = Tools::strlen(strip_tags($description['description'])); } if (isset($description['iso_code'])) { $scores['description_' . $description['iso_code']] = ($row['desclength_' . $description['iso_code']] < Configuration::get('CHECKUP_DESCRIPTIONS_LT') ? 0 : ($row['desclength_' . $description['iso_code']] > Configuration::get('CHECKUP_DESCRIPTIONS_GT') ? 2 : 1)); $totals['description_' . $description['iso_code']] += $scores['description_' . $description['iso_code']]; } } $scores['average'] = array_sum($scores) / $divisor; $scores['average'] = ($scores['average'] < 1 ? 0 : ($scores['average'] > 1.5 ? 2 : 1)); $this->html .= ' '; foreach ($languages as $language) { if (isset($row['desclength_' . $language['iso_code']])) { $this->html .= ''; } else { $this->html .= ''; } } $this->html .= ' '; } $this->html .= ''; $totals['active'] = $totals['active'] / $totals['products']; $totals['active'] = ($totals['active'] < 1 ? 0 : ($totals['active'] > 1.5 ? 2 : 1)); $totals['images'] = $totals['images'] / $totals['products']; $totals['images'] = ($totals['images'] < 1 ? 0 : ($totals['images'] > 1.5 ? 2 : 1)); $totals['sales'] = $totals['sales'] / $totals['products']; $totals['sales'] = ($totals['sales'] < 1 ? 0 : ($totals['sales'] > 1.5 ? 2 : 1)); $totals['stock'] = $totals['stock'] / $totals['products']; $totals['stock'] = ($totals['stock'] < 1 ? 0 : ($totals['stock'] > 1.5 ? 2 : 1)); foreach ($languages as $language) { $totals['description_' . $language['iso_code']] = $totals['description_' . $language['iso_code']] / $totals['products']; $totals['description_' . $language['iso_code']] = ($totals['description_' . $language['iso_code']] < 1 ? 0 : ($totals['description_' . $language['iso_code']] > 1.5 ? 2 : 1)); } $totals['average'] = array_sum($totals) / $divisor; $totals['average'] = ($totals['average'] < 1 ? 0 : ($totals['average'] > 1.5 ? 2 : 1)); $this->html .= ' '; foreach ($languages as $language) { $this->html .= ''; } $this->html .= ' '; foreach ($languages as $language) { $this->html .= ''; } $this->html .= '
' . $this->trans('ID', [], 'Admin.Global') . ' ' . $this->trans('Item', [], 'Admin.Global') . ' ' . $this->trans('Active', [], 'Admin.Global') . '' . $this->trans('Desc.', [], 'Modules.Statscheckup.Admin') . ' (' . Tools::strtoupper($language['iso_code']) . ')' . $this->trans('Images', [], 'Admin.Global') . ' ' . $this->trans('Sales', [], 'Admin.Global') . ' ' . $this->trans('Available quantity for sale', [], 'Admin.Global') . ' ' . $this->trans('Global', [], 'Modules.Statscheckup.Admin') . '
' . $row['id_product'] . ' ' . Tools::substr($row['name'], 0, 42) . ' ' . $array_colors[$scores['active']] . '' . (int) $row['desclength_' . $language['iso_code']] . ' ' . $array_colors[$scores['description_' . $language['iso_code']]] . '0 ' . $array_colors[0] . '' . (int) $row['nbImages'] . ' ' . $array_colors[$scores['images']] . ' ' . (int) $row['nbSales'] . ' ' . $array_colors[$scores['sales']] . ' ' . (int) $row['stock'] . ' ' . $array_colors[$scores['stock']] . ' ' . $array_colors[$scores['average']] . '
' . $this->trans('Active', [], 'Admin.Global') . '' . $this->trans('Desc.', [], 'Modules.Statscheckup.Admin') . ' (' . Tools::strtoupper($language['iso_code']) . ')' . $this->trans('Images', [], 'Admin.Global') . ' ' . $this->trans('Sales', [], 'Admin.Global') . ' ' . $this->trans('Available quantity for sale', [], 'Admin.Global') . ' ' . $this->trans('Global', [], 'Modules.Statscheckup.Admin') . '
' . $array_colors[$totals['active']] . '' . $array_colors[$totals['description_' . $language['iso_code']]] . '' . $array_colors[$totals['images']] . ' ' . $array_colors[$totals['sales']] . ' ' . $array_colors[$totals['stock']] . ' ' . $array_colors[$totals['average']] . '
'; return $this->html; } }