diff --git a/admin-dev/themes/default/template/controllers/dashboard/helpers/view/view.tpl b/admin-dev/themes/default/template/controllers/dashboard/helpers/view/view.tpl
index 73e662a44..fe7d76e13 100644
--- a/admin-dev/themes/default/template/controllers/dashboard/helpers/view/view.tpl
+++ b/admin-dev/themes/default/template/controllers/dashboard/helpers/view/view.tpl
@@ -25,6 +25,7 @@
diff --git a/js/admin-dashboard.js b/js/admin-dashboard.js
index 5229d0324..96c040210 100644
--- a/js/admin-dashboard.js
+++ b/js/admin-dashboard.js
@@ -52,30 +52,72 @@ function refreshDashbard(module_name)
}
},
error : function(data){
- alert("[TECHNICAL ERROR]");
+ //@TODO display errors
}
});
}
-function data_value(datas)
+function data_value(data)
{
- for (var data_id in datas)
+ for (var data_id in data)
{
- $('#'+data_id).html(datas[data_id]);
+ $('#'+data_id).html(data[data_id]);
$('#'+data_id).closest('section').removeClass('loading');
}
}
-function data_trends(datas)
+function data_trends(data)
{
- for (var data_id in datas)
+ for (var data_id in data)
{
- $('#'+data_id).html(datas[data_id]['value']);
- if (datas[data_id]['way'] == 'down')
+ $('#'+data_id).html(data[data_id]['value']);
+ if (data[data_id]['way'] == 'down')
$('#'+data_id).parent().removeClass('dash_trend_up').addClass('dash_trend_down');
else
$('#'+data_id).parent().removeClass('dash_trend_down').addClass('dash_trend_up');
$('#'+data_id).closest('section').removeClass('loading');
}
-
+}
+
+function data_table(data)
+{
+ for (var data_id in data)
+ {
+ //fill header
+ tr = '
';
+ for (var header in data[data_id].header)
+ {
+ head = data[data_id].header[header];
+ th = '| ';
+ th += (head.wrapper_start ? ' '+head.wrapper_start+' ' : '' );
+ th += head.title;
+ th += (head.wrapper_stop ? ' '+head.wrapper_stop+' ' : '' );
+ th += ' | ';
+ tr += th;
+ }
+ tr += '
';
+ $('#'+data_id+' thead').html(tr);
+
+ //fill body
+ $('#'+data_id+' tbody').html('');
+ if (data[data_id].body.length)
+ for (var body_content_id in data[data_id].body)
+ {
+ tr = '
';
+ for (var body_content in data[data_id].body[body_content_id])
+ {
+ body = data[data_id].body[body_content_id][body_content];
+ td = '| ';
+ td += (body.wrapper_start ? ' '+body.wrapper_start+' ' : '' );
+ td += body.value;
+ td += (body.wrapper_stop ? ' '+body.wrapper_stop+' ' : '' );
+ td += ' | ';
+ tr += td;
+ }
+ tr += '
';
+ $('#'+data_id+' tbody').append(tr);
+ }
+ else
+ $('#'+data_id+' tbody').html('
| '+no_results_translation+' |
');
+ }
}
\ No newline at end of file
diff --git a/modules/dashproducts/dashproducts.php b/modules/dashproducts/dashproducts.php
index 9615d79ed..64112e410 100644
--- a/modules/dashproducts/dashproducts.php
+++ b/modules/dashproducts/dashproducts.php
@@ -42,11 +42,17 @@ class Dashproducts extends Module
public function install()
{
- if (!parent::install() || !$this->registerHook('dashboardZoneTwo') || !$this->registerHook('dashboardData'))
+ if (!parent::install() || !$this->registerHook('dashboardZoneTwo') || !$this->registerHook('dashboardData') || !$this->registerHook('displayBackOfficeHeader'))
return false;
return true;
}
+ public function hookDisplayBackOfficeHeader()
+ {
+ if (get_class($this->context->controller) == 'AdminDashboardController')
+ $this->context->controller->addJqueryPlugin('timeago');
+ }
+
public function hookDashboardZoneTwo($params)
{
return $this->display(__FILE__, 'dashboard_zone_two.tpl');
@@ -54,7 +60,409 @@ class Dashproducts extends Module
public function hookDashboardData($params)
{
- return array();
+ $table_recent_orders = $this->getTableRecentOrders();
+ $table_best_sellers = $this->getTableBestSellers($params['date_from'], $params['date_to']);
+ $table_most_viewed = $this->getTableMostViewed($params['date_from'], $params['date_to']);
+ $table_top_10_most_search = $this->getTableTop10MostSearch($params['date_from'], $params['date_to']);
+ $table_top_5_search = $this->getTableTop5Search();
+ $table_best_sales = $this->getTableBestSales();
+
+ return array(
+ 'data_table' => array(
+ 'table_recent_orders' => $table_recent_orders,
+ 'table_best_sellers' => $table_best_sellers,
+ 'table_most_viewed' => $table_most_viewed,
+ 'table_top_10_most_search' => $table_top_10_most_search,
+ 'table_top_5_search' => $table_top_5_search,
+ 'table_best_sales' => $table_best_sales,
+ )
+ );
}
+
+ public function getTableRecentOrders()
+ {
+ $header = array(
+ array('title' => $this->l('Customer Name'), 'class' => 'text-left'),
+ array('title' => $this->l('Products'), 'class' => 'text-center'),
+ array('title' => $this->l('Total'), 'class' => 'text-center'),
+ array('title' => $this->l('Date'), 'class' => 'text-center'),
+ array('title' => $this->l('Action'), 'class' => 'text-center'),
+ );
+
+ $orders = Order::getOrdersWithInformations(10);
+
+ $body = array();
+ foreach ($orders as $order)
+ {
+ $currency = Currency::getCurrency((int)$order['id_currency']);
+ $tr = array();
+ $tr[] = array(
+ 'id' => 'firstname_lastname',
+ 'value' => Tools::htmlentitiesUTF8($order['firstname']).' '.Tools::htmlentitiesUTF8($order['lastname']),
+ 'class' => 'text-left',
+ );
+ $tr[] = array(
+ 'id' => 'state_name',
+ 'value' => count(OrderDetail::getList((int)$order['id_order'])),
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'total_paid',
+ 'value' => Tools::displayPrice((float)$order['total_paid'], $currency),
+ 'class' => 'text-center',
+ 'wrapper_start' => '
',
+ 'wrapper_end' => '',
+ );
+ $tr[] = array(
+ 'id' => 'date_add',
+ 'value' => Tools::displayDate($order['date_add']),
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'details',
+ 'value' => $this->l('Details'),
+ 'class' => 'text-center',
+ 'wrapper_start' => '',
+ 'wrapper_end' => ''
+ );
+ $body[] = $tr;
+ }
+ return array('header' => $header, 'body' => $body);
+ }
+
+ public function getTableBestSellers($date_from, $date_to)
+ {
+
+ $header = array(
+ array(
+ 'id' => 'image',
+ 'title' => $this->l('Image'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'product',
+ 'title' => $this->l('Product'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'category',
+ 'title' => $this->l('Category'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'total_sold',
+ 'title' => $this->l('Total sold'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'sales',
+ 'title' => $this->l('Sales'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'net_profit',
+ 'title' => $this->l('Net Profit'),
+ 'class' => 'text-center',
+ )
+ );
+
+ $products = ProductSale::getBestSalesLight($this->context->language->id);
+
+ $body = array();
+ if (is_array($products) && count($products))
+ foreach ($products as $product)
+ {
+ $product_obj = new Product((int)$product['id_product']);
+ if (!Validate::isLoadedObject($product_obj))
+ continue;
+
+ $tr = array();
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => '
',
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => Tools::htmlentitiesUTF8($product['name']).'
'.Tools::displayPrice(Product::getPriceStatic((int)$product['id_product'])),
+ 'class' => 'text-center',
+ );
+ $category = new Category($product_obj->getDefaultCategory(), $this->context->language->id);
+ $tr[] = array(
+ 'id' => 'category',
+ 'value' => $category->name,
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'total_sold',
+ 'value' => $product['sales'],
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'sales',
+ 'value' => Tools::displayPrice($this->getTotalProductSales($date_from, $date_to, (int)$product['id_product'])),
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'net_profit',
+ 'value' => 'coming soon',
+ 'class' => 'text-center',
+ );
+ $body[] = $tr;
+ }
+ return array('header' => $header, 'body' => $body);
+ }
+
+ public function getTableMostViewed($date_from, $date_to)
+ {
+ $header = array(
+ array(
+ 'id' => 'image',
+ 'title' => $this->l('Image'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'product',
+ 'title' => $this->l('Product'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'views',
+ 'title' => $this->l('Views'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'added_to_cart',
+ 'title' => $this->l('Added to cart'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'purchased',
+ 'title' => $this->l('Purchased'),
+ 'class' => 'text-center',
+ ),
+ array(
+ 'id' => 'rate',
+ 'title' => $this->l('Rate'),
+ 'class' => 'text-center',
+ )
+ );
+
+ $products = $this->getTotalViewed($date_from, $date_to);
+ $body = array();
+ if (is_array($products) && count($products))
+ foreach ($products as $product)
+ {
+ $product_obj = new Product((int)$product['id_object'], true, $this->context->language->id);
+ if (!Validate::isLoadedObject($product_obj))
+ continue;
+
+ $tr = array();
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => '
',
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => Tools::htmlentitiesUTF8($product_obj->name).'
'.Tools::displayPrice(Product::getPriceStatic((int)$product_obj->id)),
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'views',
+ 'value' => $product['counter'],
+ 'class' => 'text-center',
+ );
+ $added_cart = $this->getTotalProductAddedCart($date_from, $date_to, (int)$product_obj->id);
+ $tr[] = array(
+ 'id' => 'added_to_cart',
+ 'value' => $added_cart,
+ 'class' => 'text-center',
+ );
+ $purchased = $this->getTotalProductPurchased($date_from, $date_to, (int)$product_obj->id);
+ $tr[] = array(
+ 'id' => 'purchased',
+ 'value' => $this->getTotalProductPurchased($date_from, $date_to, (int)$product_obj->id),
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'rate',
+ 'value' => (!$purchased ? '-' : ($added_cart*100)/$purchased.'%'),
+ 'class' => 'text-center',
+ );
+ $body[] = $tr;
+ }
+
+ return array('header' => $header, 'body' => $body);
+ }
+
+ public function getTableTop10MostSearch($date_from, $date_to)
+ {
+ $header = array(
+ array(
+ 'id' => 'reference',
+ 'title' => $this->l('Term'),
+ 'class' => 'text-left'
+ ),
+ array(
+ 'id' => 'name',
+ 'title' => $this->l('Search'),
+ 'class' => 'text-center'
+ ),
+ array(
+ 'id' => 'totalQuantitySold',
+ 'title' => $this->l('Results'),
+ 'class' => 'text-center'
+ )
+ );
+
+ $terms = $this->getMostSearchTerms($date_from, $date_to);
+
+ $body = array();
+ if (is_array($terms) && count($terms))
+ foreach ($terms as $term)
+ {
+ $tr = array();
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => $term['keywords'],
+ 'class' => 'text-left',
+ );
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => $term['count_keywords'],
+ 'class' => 'text-center',
+ );
+ $tr[] = array(
+ 'id' => 'product',
+ 'value' => $term['results'],
+ 'class' => 'text-center',
+ );
+ $body[] = $tr;
+ }
+
+ return array('header' => $header, 'body' => $body);
+ }
+
+ public function getTableTop5Search()
+ {
+ $header = array(
+ array(
+ 'id' => 'reference',
+ 'title' => $this->l('Product'),
+ )
+ );
+
+ $body = array();
+
+ return array('header' => $header, 'body' => $body);
+ }
+
+ public function getTableBestSales()
+ {
+ $header = array(
+ array(
+ 'id' => 'reference',
+ 'title' => $this->l('Ref.'),
+ ),
+ array(
+ 'id' => 'name',
+ 'title' => $this->l('Name'),
+ ),
+ array(
+ 'id' => 'totalQuantitySold',
+ 'title' => $this->l('Quantity sold'),
+ ),
+ array(
+ 'id' => 'avg_price_sold',
+ 'title' => $this->l('Price sold'),
+ ),
+ array(
+ 'id' => 'total_price_sold',
+ 'title' => $this->l('Sales'),
+ ),
+ array(
+ 'id' => 'average_quantity_sold',
+ 'title' => $this->l('Qty sold in a day.'),
+ ),
+ array(
+ 'id' => 'total_page_viewed',
+ 'title' => $this->l('Page views'),
+ ),
+ array(
+ 'id' => 'quantity',
+ 'title' => $this->l('Available qty for sale.'),
+ )
+ );
+
+ $body = array();
+
+ return array('header' => $header, 'body' => $body);
+ }
+
+ public function getTotalProductSales($date_from, $date_to, $id_product)
+ {
+ $sql = 'SELECT SUM(od.`product_quantity` * od.`product_price`) AS total
+ FROM `'._DB_PREFIX_.'order_detail` od
+ 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 "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"';
+
+ return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
+ }
+
+ public function getTotalProductAddedCart($date_from, $date_to, $id_product)
+ {
+ $sql = 'SELECT count(`id_product`) as count
+ FROM `'._DB_PREFIX_.'cart_product` cp
+ WHERE cp.`id_product` = '.(int)$id_product.'
+ '.Shop::addSqlRestriction(false, 'cp').'
+ AND cp.`date_add` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"';
+
+ return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
+ }
+
+ public function getTotalProductPurchased($date_from, $date_to, $id_product)
+ {
+ $sql = 'SELECT count(`product_id`) as count
+ FROM `'._DB_PREFIX_.'order_detail` od
+ JOIN `'._DB_PREFIX_.'orders` o ON o.`id_order` = od.`id_order`
+ WHERE od.`product_id` = '.(int)$id_product.'
+ '.Shop::addSqlRestriction(false, 'od').'
+ AND o.valid = 1
+ AND o.`date_add` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"';
+
+ return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
+ }
+
+ public function getTotalViewed($date_from, $date_to)
+ {
+ $sql = 'SELECT *
+ 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 dr.`time_start` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"
+ AND dr.`time_end` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"';
+
+ return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
+ }
+
+ public function getMostSearchTerms($date_from, $date_to, $limit = 10)
+ {
+ $sql = 'SELECT `keywords`, count(`id_statssearch`) as count_keywords, `results`
+ FROM `'._DB_PREFIX_.'statssearch` ss
+ WHERE ss.`date_add` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"
+ '.Shop::addSqlRestriction(false, 'ss').'
+ GROUP BY ss.`keywords`
+ ORDER BY `count_keywords` DESC
+ LIMIT 0, '.(int)$limit;
+
+ return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
+ }
}
\ No newline at end of file
diff --git a/modules/dashproducts/views/templates/hook/dashboard_zone_two.tpl b/modules/dashproducts/views/templates/hook/dashboard_zone_two.tpl
index b3a3eb5e9..15ad68a4f 100644
--- a/modules/dashproducts/views/templates/hook/dashboard_zone_two.tpl
+++ b/modules/dashproducts/views/templates/hook/dashboard_zone_two.tpl
@@ -38,7 +38,7 @@
-
Last 10 orders: Overall | Pending
-
+ {l s="Last 10 orders:"}
+
+
+
+
{l s="Top 5 products:"}
+
+
+
+
{l s="Coming soon"}
+
+
+
+
+
+
{l s="Top 10 most search terms:"}
+
+
+
+
{l s="Coming soon"}
+
+
+
+
+
+
{l s="Coming soon"}
+
-
- | Customer |
- Products |
- Total |
- Date |
- |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
-
- | John Smith |
- 10 |
- $1200 |
- July 8th, 2013 // 10:42 am |
- Today |
-
- Coming soon
- Coming soon
- Coming soon
- Coming soon
\ No newline at end of file