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="Coming soon"}

+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CustomerProductsTotalDate
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
John Smith10$1200July 8th, 2013 // 10:42 am Today
-

Coming soon

-

Coming soon

- -

Coming soon

\ No newline at end of file