* @copyright 2007-2016 PrestaShop SA
* @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;
}
require_once _PS_MODULE_DIR_.'hotelreservationsystem/define.php';
class StatsCheckUp extends Module
{
private $html = '';
private $id_hotel = 0;
const ORDER_BY_ID = 1;
const ORDER_BY_NAME = 2;
const ORDER_BY_ORDERS = 3;
public function __construct()
{
$this->name = 'statscheckup';
$this->tab = 'analytics_stats';
$this->version = '1.5.1';
$this->author = 'PrestaShop';
$this->need_instance = 0;
parent::__construct();
$this->displayName = $this->l('Catalog evaluation');
$this->description = $this->l('Adds a quick evaluation of your catalog quality to the Stats dashboard.');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => '1.7.0.99');
}
public function install()
{
$confs = array(
'ROOM_TYPE_CHECKUP_DESCRIPTIONS_LT' => 100,
'ROOM_TYPE_CHECKUP_DESCRIPTIONS_GT' => 400,
'ROOM_TYPE_CHECKUP_IMAGES_LT' => 1,
'ROOM_TYPE_CHECKUP_IMAGES_GT' => 2,
'ROOM_TYPE_CHECKUP_ORDERS_LT' => 1,
'ROOM_TYPE_CHECKUP_ORDERS_GT' => 2,
'ROOM_TYPE_CHECKUP_TOTAL_ROOMS_LT' => 1,
'ROOM_TYPE_CHECKUP_TOTAL_ROOMS_GT' => 3,
'HOTEL_CHECKUP_DESCRIPTIONS_LT' => 100,
'HOTEL_CHECKUP_DESCRIPTIONS_GT' => 400,
'HOTEL_CHECKUP_IMAGES_LT' => 1,
'HOTEL_CHECKUP_IMAGES_GT' => 2,
'HOTEL_CHECKUP_ORDERS_LT' => 1,
'HOTEL_CHECKUP_ORDERS_GT' => 2,
'HOTEL_CHECKUP_TOTAL_ROOMS_LT' => 1,
'HOTEL_CHECKUP_TOTAL_ROOMS_GT' => 3,
);
foreach ($confs as $confname => $confdefault) {
if (!Configuration::get($confname)) {
Configuration::updateValue($confname, (int)$confdefault);
}
}
return (parent::install() && $this->registerHook('AdminStatsModules'));
}
public function hookAdminStatsModules()
{
$this->html = '
'
.$this->displayName.'
';
if (Tools::isSubmit('submitCheckupRoomType')) {
$confs = array(
'ROOM_TYPE_CHECKUP_DESCRIPTIONS_LT',
'ROOM_TYPE_CHECKUP_DESCRIPTIONS_GT',
'ROOM_TYPE_CHECKUP_IMAGES_LT',
'ROOM_TYPE_CHECKUP_IMAGES_GT',
'ROOM_TYPE_CHECKUP_ORDERS_LT',
'ROOM_TYPE_CHECKUP_ORDERS_GT',
'ROOM_TYPE_CHECKUP_TOTAL_ROOMS_LT',
'ROOM_TYPE_CHECKUP_TOTAL_ROOMS_GT',
);
foreach ($confs as $confname) {
Configuration::updateValue($confname, (int)Tools::getValue($confname));
}
$this->html .= $this->displayConfirmation($this->l('Configuration updated.'));
}
if (Tools::isSubmit('submitCheckupHotel')) {
$confs = array(
'HOTEL_CHECKUP_DESCRIPTIONS_LT',
'HOTEL_CHECKUP_DESCRIPTIONS_GT',
'HOTEL_CHECKUP_IMAGES_LT',
'HOTEL_CHECKUP_IMAGES_GT',
'HOTEL_CHECKUP_ORDERS_LT',
'HOTEL_CHECKUP_ORDERS_GT',
'HOTEL_CHECKUP_TOTAL_ROOMS_LT',
'HOTEL_CHECKUP_TOTAL_ROOMS_GT',
);
foreach ($confs as $confname) {
Configuration::updateValue($confname, (int)Tools::getValue($confname));
}
$this->html .= $this->displayConfirmation($this->l('Configuration updated.'));
}
if (Tools::isSubmit('submitCheckupOrder')) {
$this->context->cookie->checkup_order = (int)Tools::getValue('submitCheckupOrder');
$this->html .= $this->displayConfirmation($this->l('Configuration updated.'));
}
if (!isset($this->context->cookie->checkup_order)) {
$this->context->cookie->checkup_order = self::ORDER_BY_ID;
}
if (Tools::getValue('id_hotel')) {
$this->id_hotel = (int) Tools::getValue('id_hotel');
}
$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::getInstance()->executeS($sql);
$array_colors = array(
0 => '
',
1 => '
',
2 => '
'
);
$divisor = 4;
$totals = array('products' => 0, 'active' => 0, 'images' => 0, 'orders' => 0, 'total_rooms' => 0);
foreach ($languages as $language) {
$divisor++;
$totals['description_'.$language['iso_code']] = 0;
}
// set data from here
$result = null;
if ($this->id_hotel) {
$result = $this->getRoomTypeStats();
if (!$result) {
return $this->l('No room type was found.');
}
} else {
$result = $this->getHotelStats();
if (!$result) {
return $this->l('No hotel was found.');
}
}
$array_conf = array(
'DESCRIPTIONS' => array('name' => $this->l('Descriptions'), 'text' => $this->l('chars (without HTML)')),
'IMAGES' => array('name' => $this->l('Images'), 'text' => $this->l('images')),
'ORDERS' => array('name' => $this->l('Orders'), 'text' => $this->l('orders / month')),
'TOTAL_ROOMS' => array('name' => $this->l('Total rooms'), 'text' => $this->l('rooms')),
);
$this->html .= '
| '.$this->l('ID').' |
'.$this->l('Room type').' |
'.$this->l('Active').' | ';
foreach ($languages as $language) {
$this->html .= ''.$this->l('Desc.').' ('.Tools::strtoupper($language['iso_code']).') | ';
}
$this->html .= '
'.$this->l('Images').' |
'.$this->l('Orders').' |
'.$this->l('Total rooms').' |
'.$this->l('Overall status').' |
'.(!$this->id_hotel ? ''.$this->l('Action').' | ' : '').'
';
$confPrefix = $this->id_hotel ? 'ROOM_TYPE_' : 'HOTEL_';
$confCheckup = array(
'IMAGES_LT' => Configuration::get($confPrefix.'CHECKUP_IMAGES_LT'),
'IMAGES_GT' => Configuration::get($confPrefix.'CHECKUP_IMAGES_GT'),
'ORDERS_LT' => Configuration::get($confPrefix.'CHECKUP_ORDERS_LT'),
'ORDERS_GT' => Configuration::get($confPrefix.'CHECKUP_ORDERS_GT'),
'TOTAL_ROOMS_LT' => Configuration::get($confPrefix.'CHECKUP_TOTAL_ROOMS_LT'),
'TOTAL_ROOMS_GT' => Configuration::get($confPrefix.'CHECKUP_TOTAL_ROOMS_GT'),
'DESCRIPTIONS_LT' => Configuration::get($confPrefix.'CHECKUP_DESCRIPTIONS_LT'),
'DESCRIPTIONS_GT' => Configuration::get($confPrefix.'CHECKUP_DESCRIPTIONS_GT'),
);
foreach ($result as $row) {
$totals['products']++;
$scores = array(
'active' => ($row['active'] ? 2 : 0),
'images' => ($row['nbImages'] < $confCheckup['IMAGES_LT'] ? 0 : ($row['nbImages'] > $confCheckup['IMAGES_GT'] ? 2 : 1)),
'orders' => (($row['nbOrders'] * $prop30 < $confCheckup['ORDERS_LT']) ? 0 : (($row['nbOrders'] * $prop30 > $confCheckup['ORDERS_GT']) ? 2 : 1)),
'total_rooms' => (($row['totalRooms'] < $confCheckup['TOTAL_ROOMS_LT']) ? 0 : (($row['totalRooms'] > $confCheckup['TOTAL_ROOMS_GT']) ? 2 : 1)),
);
$totals['active'] += (int)$scores['active'];
$totals['images'] += (int)$scores['images'];
$totals['orders'] += (int)$scores['orders'];
$totals['total_rooms'] += (int)$scores['total_rooms'];
$descriptions = $this->getDescriptions($row['id_object']);
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']] < $confCheckup['DESCRIPTIONS_LT'] ? 0 : ($row['desclength_'.$description['iso_code']] > $confCheckup['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));
$objectLink = '';
if ($this->id_hotel) {
$objectLink = $this->context->link->getAdminLink('AdminProducts').'&updateproduct&id_product='.$row['id_object'];
} else {
$objectLink = $this->context->link->getAdminLink('AdminAddHotel').'&updatehtl_branch_info&id='.$row['id_object'];
}
$this->html .= '
| '.$row['id_object'].' |
'.Tools::substr($row['object_name'], 0, 42).' |
'.$array_colors[$scores['active']].' | ';
foreach ($languages as $language) {
if (isset($row['desclength_'.$language['iso_code']])) {
$this->html .= ''.(int)$row['desclength_'.$language['iso_code']].' '.$array_colors[$scores['description_'.$language['iso_code']]].' | ';
} else {
$this->html .= '0 '.$array_colors[0].' | ';
}
}
$objectViewLink = '';
if (!$this->id_hotel) {
$objectViewLink = $this->context->link->getAdminLink('AdminStats').'&module='.$this->name.'&id_hotel='.$row['id_object'];
}
$this->html .= '
'.(int)$row['nbImages'].' '.$array_colors[$scores['images']].' |
'.(int)$row['nbOrders'].' '.$array_colors[$scores['orders']].' |
'.(int)$row['totalRooms'].' '.$array_colors[$scores['total_rooms']].' |
'.$array_colors[$scores['average']].' |
'.(!$this->id_hotel ? ' | ' : '').'
';
}
$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['orders'] = $totals['orders'] / $totals['products'];
$totals['orders'] = ($totals['orders'] < 1 ? 0 : ($totals['orders'] > 1.5 ? 2 : 1));
$totals['total_rooms'] = $totals['total_rooms'] / $totals['products'];
$totals['total_rooms'] = ($totals['total_rooms'] < 1 ? 0 : ($totals['total_rooms'] > 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 .= '
|
'.$this->l('Active').' | ';
foreach ($languages as $language) {
$this->html .= ''.$this->l('Desc.').' ('.Tools::strtoupper($language['iso_code']).') | ';
}
$this->html .= '
'.$this->l('Images').' |
'.$this->l('Orders').' |
'.$this->l('Total rooms').' |
'.$this->l('Overall status').' |
'.(!$this->id_hotel ? ' | ' : '').'
|
'.$array_colors[$totals['active']].' | ';
foreach ($languages as $language) {
$this->html .= ''.$array_colors[$totals['description_'.$language['iso_code']]].' | ';
}
$this->html .= '
'.$array_colors[$totals['images']].' |
'.$array_colors[$totals['orders']].' |
'.$array_colors[$totals['total_rooms']].' |
'.$array_colors[$totals['average']].' |
'.(!$this->id_hotel ? ' | ' : '').'
';
return $this->html;
}
public function getHotelStats()
{
$date_from = date('Y-m-d', strtotime($this->context->employee->stats_date_from));
$date_to = date('Y-m-d', strtotime($this->context->employee->stats_date_to));
$id_lang = $this->context->language->id;
$order_by = 'hbi.`id`';
if ($this->context->cookie->checkup_order == self::ORDER_BY_NAME) {
$order_by = 'object_name';
} elseif ($this->context->cookie->checkup_order == self::ORDER_BY_ORDERS) {
$order_by = 'nbOrders DESC';
}
$sql = 'SELECT hbi.`id` AS id_object, hbil.`hotel_name` AS object_name, hbi.`active`,
(
SELECT COUNT(*)
FROM '._DB_PREFIX_.'htl_image hi
WHERE hi.`id_hotel` = hbi.`id`
) AS nbImages,
(
SELECT COUNT(DISTINCT hbd.`id_order`) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd
LEFT JOIN `'._DB_PREFIX_.'orders` o
ON (o.`id_order` = hbd.`id_order`)
WHERE hbd.`id_hotel` = hbi.`id` AND o.`valid` = 1
AND hbd.`date_to` > "'.pSQL($date_from).'" AND hbd.`date_from` < "'.pSQL($date_to).'"
) AS nbOrders,
(
SELECT COUNT(*)
FROM `'._DB_PREFIX_.'htl_room_information` hri
WHERE hri.`id_hotel` = hbi.`id`
) AS totalRooms
FROM `'._DB_PREFIX_.'htl_branch_info` hbi
LEFT JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbil
ON (hbil.`id` = hbi.`id` AND hbil.`id_lang` = '.(int) $id_lang .')
ORDER BY '.$order_by;
return Db::getInstance()->executeS($sql);
}
public function getRoomTypeStats()
{
$date_from = date('Y-m-d', strtotime($this->context->employee->stats_date_from));
$date_to = date('Y-m-d', strtotime($this->context->employee->stats_date_to));
$id_lang = $this->context->language->id;
$order_by = 'p.`id_product`';
if ($this->context->cookie->checkup_order == self::ORDER_BY_NAME) {
$order_by = 'object_name';
} elseif ($this->context->cookie->checkup_order == self::ORDER_BY_ORDERS) {
$order_by = 'nbOrders DESC';
}
$sql = 'SELECT p.`id_product` AS id_object, p.`active`, pl.`name` AS object_name,
(
SELECT COUNT(*)
FROM '._DB_PREFIX_.'image i
WHERE i.`id_product` = p.`id_product`
) AS nbImages,
(
SELECT COUNT(DISTINCT hbd.`id_order`) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd
LEFT JOIN `'._DB_PREFIX_.'orders` o ON (o.`id_order` = hbd.`id_order`)
WHERE hbd.`id_product` = p.`id_product` AND o.`valid` = 1
AND hbd.`date_to` > "'.pSQL($date_from).'" AND hbd.`date_from` < "'.pSQL($date_to).'"
) AS nbOrders,
(
SELECT COUNT(*)
FROM `'._DB_PREFIX_.'htl_room_information` hri
WHERE hri.`id_product` = p.`id_product`
) AS totalRooms
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl
ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int) $id_lang.')
LEFT JOIN '._DB_PREFIX_.'htl_room_type hrt
ON (hrt.`id_product` = p.`id_product`)
WHERE hrt.`id_hotel` = '.(int) $this->id_hotel.'
ORDER BY '.$order_by;
return Db::getInstance()->executeS($sql);
}
public function getDescriptions($id_object)
{
if ($this->id_hotel) {
return Db::getInstance()->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`
LEFT JOIN '._DB_PREFIX_.'htl_room_type hrt
ON (hrt.`id_product` = pl.`id_product`)
WHERE hrt.`id_hotel` = '.(int) $this->id_hotel.'
AND pl.`id_product` = '.(int) $id_object
);
} else {
return Db::getInstance()->executeS(
'SELECT l.`iso_code`, hbil.`description`
FROM '._DB_PREFIX_.'htl_branch_info_lang hbil
LEFT JOIN '._DB_PREFIX_.'lang l
ON hbil.`id_lang` = l.`id_lang`
WHERE hbil.`id` = '.(int) $id_object
);
}
}
}