From c8b1086fcde42ce7a3b7d1f2c9ddbcbbe8501b36 Mon Sep 17 00:00:00 2001 From: Daniel Camargo Date: Thu, 27 Jun 2013 20:01:40 -0300 Subject: [PATCH] partial #1464 --- .../default/cockpit/home/charts.php | 157 ++++++++++-------- .../default/cockpit/home/index.php | 21 +-- include/library/Crunchbutton/Chart.php | 99 +++++++++-- include/library/Crunchbutton/Chart/User.php | 96 +++++------ .../views/default/cockpit/charts/column.phtml | 10 ++ .../views/default/cockpit/home/index.phtml | 2 +- 6 files changed, 241 insertions(+), 144 deletions(-) diff --git a/include/controllers/default/cockpit/home/charts.php b/include/controllers/default/cockpit/home/charts.php index e4371966c..b13f618d0 100644 --- a/include/controllers/default/cockpit/home/charts.php +++ b/include/controllers/default/cockpit/home/charts.php @@ -12,21 +12,81 @@ class Controller_home_charts extends Crunchbutton_Controller_Account { $this->chart = new Crunchbutton_Chart; - $query = ''; - $union = ''; - switch ( $this->chartId ) { - case 'new-users-per-week': + /* Users */ + case 'users-reclaimed-per-week': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->reclaimedByWeek( true ) ); + break; + + case 'users-active-per-week': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->activeByWeek( true ) ); + break; + + case 'users-new-per-day': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->newByDay( true ) ); + break; + + case 'users-new-per-week': $chart = new Crunchbutton_Chart_User(); $this->renderColumn( $chart->newByWeek( true ) ); break; - case 'new-users-per-month': + case 'users-new-per-month': $chart = new Crunchbutton_Chart_User(); $this->renderColumn( $chart->newByMonth( true ) ); break; + case 'users-active-per-month': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->activeByMonth( true ) ); + break; + + case 'users-new-per-active-users-per-week': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->newPerActiveByWeek( true ) ); + break; + + case 'users-new-per-active-users-per-month': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->newPerActiveByMonth( true ) ); + break; + + case 'users-unique-per-week': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->uniqueByWeek( true ) ); + break; + + case 'users-unique-per-month': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->uniqueByMonth( true ) ); + break; + + case 'users-new-per-week-by-community': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->newByWeekByCommunity( true ) ); + break; + + case 'users-active-per-week-by-community': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->activeByWeekByCommunity( true ) ); + break; + + case 'users-new-per-active-users-by-community': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->newPerActiveByWeekByCommunity( true ) ); + break; + + case 'users-unique-per-week-by-community': + $chart = new Crunchbutton_Chart_User(); + $this->renderColumn( $chart->uniqueByWeekByCommunity( true ) ); + break; + + /* Revenue */ + case 'gross-revenue-per-week': $chart = new Crunchbutton_Chart_Revenue(); $this->renderColumn( $chart->byWeek( true ) ); @@ -37,35 +97,7 @@ class Controller_home_charts extends Crunchbutton_Controller_Account { $this->renderColumn( $chart->byMonth( true ) ); break; - case 'active-users-per-week': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->activeByWeek( true ) ); - break; - - case 'active-users-per-month': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->activeByMonth( true ) ); - break; - - case 'new-users-per-active-users-per-week': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->newPerActiveByWeek( true ) ); - break; - - case 'new-users-per-active-users-per-month': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->newPerActiveByMonth( true ) ); - break; - - case 'unique-users-per-week': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->uniqueByWeek( true ) ); - break; - - case 'unique-users-per-month': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->uniqueByMonth( true ) ); - break; + /* Orders */ case 'orders-by-user-per-week': $chart = new Crunchbutton_Chart_Order(); @@ -92,61 +124,39 @@ class Controller_home_charts extends Crunchbutton_Controller_Account { $this->renderColumn( $order->byWeekPerCommunity( true ) ); break; - case 'new-users-per-week-by-community': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->newByWeekByCommunity( true ) ); - break; - - case 'active-users-per-week-by-community': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->activeByWeekByCommunity( true ) ); - break; - - case 'new-users-per-active-users-by-community': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->newPerActiveByWeekByCommunity( true ) ); - break; - - case 'unique-users-per-week-by-community': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->uniqueByWeekByCommunity( true ) ); - break; - case 'orders-by-weekday-by-community': $order = new Crunchbutton_Chart_Order(); $this->renderArea( $order->byWeekdayByCommunity( true ) ); break; - case 'repeat-orders-per-active-user': + case 'orders-repeat-per-active-user': $order = new Crunchbutton_Chart_Order(); $this->renderColumn( $order->repeatByActiveuserByWeek( true ) ); break; - case 'reclaimed-users-per-week': - $chart = new Crunchbutton_Chart_User(); - $this->renderColumn( $chart->reclaimedByWeek( true ) ); - break; + /* Churn */ case 'churn-rate-per-active-user-per-month': - $chart = new Crunchbutton_Chart_Churn(); - $this->renderColumn( $chart->activeByMonth( true ) ); - break; + $chart = new Crunchbutton_Chart_Churn(); + $this->renderColumn( $chart->activeByMonth( true ) ); + break; case 'churn-rate-per-active-user-per-week': - $chart = new Crunchbutton_Chart_Churn(); - $this->renderColumn( $chart->activeByWeek( true ) ); - break; + $chart = new Crunchbutton_Chart_Churn(); + $this->renderColumn( $chart->activeByWeek( true ) ); + break; case 'churn-rate-per-week': - $chart = new Crunchbutton_Chart_Churn(); - $this->renderColumn( $chart->byWeek( true ) ); - break; + $chart = new Crunchbutton_Chart_Churn(); + $this->renderColumn( $chart->byWeek( true ) ); + break; case 'churn-rate-per-month': - $chart = new Crunchbutton_Chart_Churn(); - $this->renderColumn( $chart->byMonth( true ) ); - break; + $chart = new Crunchbutton_Chart_Churn(); + $this->renderColumn( $chart->byMonth( true ) ); + break; + /* Others */ case 'weeks': echo $this->chart->weeksToJson(); break; @@ -178,11 +188,14 @@ class Controller_home_charts extends Crunchbutton_Controller_Account { 'from' => $this->chart->from, 'to_month' => $this->chart->to_month, 'from_month' => $this->chart->from_month, + 'to_day' => $this->chart->to_day, + 'from_day' => $this->chart->from_day, 'months' => $months, 'number' => $this->number, 'unit' => $params[ 'unit' ] , 'totalWeeks' => $this->chart->totalWeeks(), - 'totalMonths' => $this->chart->totalMonths() + 'totalMonths' => $this->chart->totalMonths(), + 'totalDays' => $this->chart->totalDays(), ]]); } } \ No newline at end of file diff --git a/include/controllers/default/cockpit/home/index.php b/include/controllers/default/cockpit/home/index.php index 3bf786fa0..4c366a6ae 100644 --- a/include/controllers/default/cockpit/home/index.php +++ b/include/controllers/default/cockpit/home/index.php @@ -42,8 +42,9 @@ class Controller_home extends Crunchbutton_Controller_Account { 'month' => 'Month', ), /* OK */ - 'new-users-per-' => array( + 'users-new-per-' => array( '_title' => 'New Users per', + 'day' => 'Day', 'week' => 'Week', 'month' => 'Month', ), @@ -54,13 +55,13 @@ class Controller_home extends Crunchbutton_Controller_Account { 'month' => 'Month', ), /* OK */ - 'active-users-per-' => array( + 'users-active-per-' => array( '_title' => 'Active users per', 'week' => 'Week', 'month' => 'Month', ), /* OK */ - 'unique-users-per-' => array( + 'users-unique-per-' => array( '_title' => 'Unique Users per', 'week' => 'Week', 'month' => 'Month', @@ -72,7 +73,7 @@ class Controller_home extends Crunchbutton_Controller_Account { 'month' => 'Month', ), /* OK */ - 'new-users-per-active-users-per-' => array( + 'users-new-per-active-users-per-' => array( '_title' => 'New Users per Active Users per', 'week' => 'Week', 'month' => 'Month', @@ -90,12 +91,12 @@ class Controller_home extends Crunchbutton_Controller_Account { 'month' => 'Month', ), - 'active-users-per-week-by-community' => 'Active Users per Week by Community', - 'new-users-per-week-by-community' => 'New Users per Week by Community', - 'new-users-per-active-users-by-community' => 'New Users per Active Users By Community', - 'unique-users-per-week-by-community' => 'Unique Users per Week by Community', - 'repeat-orders-per-active-user' => 'Repeat Orders per Active User', - 'reclaimed-users-per-week' => 'Reclaimed Users per Week', + 'users-active-per-week-by-community' => 'Active Users per Week by Community', + 'users-new-per-week-by-community' => 'New Users per Week by Community', + 'users-new-per-active-users-by-community' => 'New Users per Active Users By Community', + 'users-unique-per-week-by-community' => 'Unique Users per Week by Community', + 'orders-repeat-per-active-user' => 'Repeat Orders per Active User', + 'users-reclaimed-per-week' => 'Reclaimed Users per Week', ), 'Tracking Marketing Efforts' => array( 'active-users-per-week' => 'Active Users per Week', diff --git a/include/library/Crunchbutton/Chart.php b/include/library/Crunchbutton/Chart.php index c563c87d0..57e2f588e 100644 --- a/include/library/Crunchbutton/Chart.php +++ b/include/library/Crunchbutton/Chart.php @@ -22,15 +22,34 @@ class Crunchbutton_Chart extends Cana_Model { $this->activeUsersInterval = ( $_REQUEST[ 'activeUserDays' ] ? $_REQUEST[ 'activeUserDays' ] : $this->activeUsersInterval ); + $this->allDays = $this->allDays(); + $this->allWeeks = $this->allWeeks(); + $this->allMonths = $this->allMonths(); + switch ( $interval ) { + case 'day': + + $this->from_day = ( $_REQUEST[ 'from' ] ? $_REQUEST[ 'from' ] : 1 ); + $this->from_day = ( ( $this->from_day < 1 ) ? 1 : $this->from_day ); + $this->to_day = ( $_REQUEST[ 'to' ] ? $_REQUEST[ 'to' ] : 1 ); + + $this->dayFrom = $this->allDays[ $this->from_day - 1 ]; + $this->dayTo = $this->allDays[ $this->to_day - 1 ]; + + $this->from = array_search( $this->dayToWeek( $this->monthFrom ), $this->allWeeks() ); + $this->to = array_search( $this->dayToWeek( $this->monthTo ), $this->allWeeks() ); + + break; + case 'month': + $this->from_month = ( $_REQUEST[ 'from' ] ? $_REQUEST[ 'from' ] : 1 ); $this->from_month = ( ( $this->from_month < 1 ) ? 1 : $this->from_month ); $this->to_month = ( $_REQUEST[ 'to' ] ? $_REQUEST[ 'to' ] : 1 ); - $this->monthFrom = $this->allMonths()[ $this->from_month - 1 ]; - $this->monthTo = $this->allMonths()[ $this->to_month - 1 ]; + $this->monthFrom = $this->allMonths[ $this->from_month - 1 ]; + $this->monthTo = $this->allMonths[ $this->to_month - 1 ]; $this->from = array_search( $this->monthToWeek( $this->monthFrom ), $this->allWeeks() ); $this->to = array_search( $this->monthToWeek( $this->monthTo ), $this->allWeeks() ); @@ -39,21 +58,42 @@ class Crunchbutton_Chart extends Cana_Model { case 'week': default: + $this->from = ( $_REQUEST[ 'from' ] ? $_REQUEST[ 'from' ] : 1 ); $this->from = ( ( $this->from < 1 ) ? 1 : $this->from ); $this->to = ( $_REQUEST[ 'to' ] ? $_REQUEST[ 'to' ] : $this->totalWeeks() ); - $this->weekFrom = $this->allWeeks()[ $this->from - 1 ]; - $this->weekTo = $this->allWeeks()[ $this->to - 1 ]; + $this->weekFrom = $this->allWeeks[ $this->from - 1 ]; + $this->weekTo = $this->allWeeks[ $this->to - 1 ]; $this->from_month = array_search( $this->weekToMonth( $this->weekFrom ), $this->allMonths() ); $this->to_month = array_search( $this->weekToMonth( $this->weekTo ), $this->allMonths() ); $this->monthFrom = $this->allMonths()[ $this->from_month ]; - $this->monthTo = $this->allMonths()[ $this->to_month ]; + $this->monthTo = $this->allMonths[ $this->to_month ]; + $this->from_month++; $this->to_month++; + $this->from_day = array_search( $this->weekToDay( $this->weekFrom ), $this->allDays() ); + $this->to_day = array_search( $this->weekToDay( $this->weekTo ), $this->allDays() ); + + if( $this->from_day ){ + $this->dayFrom = $this->allDays[ $this->from_day ]; + $this->from_day++; + } else { + $this->dayFrom = $this->allDays()[ 0 ]; + $this->from_day = 1; + } + + if( $this->to_day ){ + $this->dayTo = $this->allDays[ $this->to_day ]; + $this->to_day++; + } else { + $this->dayTo = $this->allDays[ $this->totalDays() - 1 ]; + $this->to_day = $this->totalDays() + 1; + } + break; } } @@ -98,6 +138,11 @@ class Crunchbutton_Chart extends Cana_Model { return $days; } + public function totalDays(){ + $days = $this->allDays(); + return sizeof( $days ); + } + public function allWeeks(){ if( !$this->_weeks ){ $query = "SELECT DISTINCT( YEARWEEK( o.date ) ) week FROM `order` o WHERE YEARWEEK( o.date ) IS NOT NULL ORDER BY week ASC"; @@ -114,6 +159,11 @@ class Crunchbutton_Chart extends Cana_Model { return $this->_weeks; } + public function totalWeeks(){ + $weeks = $this->allWeeks(); + return sizeof( $weeks ); + } + public function weeksToJson(){ $allWeeks = $this->allWeeks(); $weeks = []; @@ -123,19 +173,23 @@ class Crunchbutton_Chart extends Cana_Model { return json_encode( $weeks ); } - public function totalWeeks(){ - $weeks = $this->allWeeks(); - return sizeof( $weeks ); + public function weekToMonth( $week ){ + return date( 'Y-m', strtotime( 'sunday ' . substr( $week, 0, 4 ) . 'W' . substr( $week, 4, 2 ) ) ); } - public function weekToMonth( $week ){ - return date( 'Y-m', strtotime( substr( $week, 0, 4 ) . 'W' . substr( $week, 4, 2 ) . ' Sunday' ) ); + public function weekToDay( $week, $day = 'first' ){ + $day = ( $day == 'first' ) ? '-0' : '-6'; + return date( 'Y-m-d', strtotime( substr( $week, 0, 4 ) . 'W' . substr( $week, 4, 2 ) . $day ) ); } public function monthToWeek( $month ){ return date( 'YW', strtotime( $month . '-01' ) ); } + public function dayToWeek( $day ){ + return date( 'YW', strtotime( $day ) ); + } + public function getMonthsFromWeeks(){ $months = []; $allWeeks = $this->allWeeks(); @@ -155,9 +209,32 @@ class Crunchbutton_Chart extends Cana_Model { public function parseWeek( $week, $showYear = false ){ $dateStr = ( $showYear ) ? 'M d Y' : 'M d'; - return date( $dateStr, strtotime( substr( $week, 0, 4 ) . 'W' . substr( $week, 4, 2 ) . '-7' ) ); + return date( $dateStr, strtotime( substr( $week, 0, 4 ) . 'W' . substr( $week, 4, 2 ) . '-0' ) ); } + public function parseDay( $day, $showYear = false ){ + $dateStr = ( $showYear ) ? 'M d Y' : 'M d'; + return date( $dateStr, strtotime( $day ) ); + } + + public function parseDataDaysSimple( $query, $type = 'Total' ){ + + $data = c::db()->get( $query ); + + $_days = []; + foreach ( $data as $item ) { + $_days[ $item->Day ] = $item->Total; + } + + $allDays = $this->allDays(); + $data = []; + for( $i = $this->from_day -1 ; $i < $this->to_day; $i++ ){ + $day = $allDays[ $i ]; + $total = ( $_days[ $day ] ) ? $_days[ $day ] : 0; + $data[] = ( object ) array( 'Label' => $this->parseDay( $day ), 'Total' => $total, 'Type' => $type ); + } + return $data; + } public function parseDataWeeksSimple( $query, $type = 'Total' ){ diff --git a/include/library/Crunchbutton/Chart/User.php b/include/library/Crunchbutton/Chart/User.php index e6327d8b7..25db6a45c 100644 --- a/include/library/Crunchbutton/Chart/User.php +++ b/include/library/Crunchbutton/Chart/User.php @@ -44,31 +44,21 @@ class Crunchbutton_Chart_User extends Crunchbutton_Chart { } public function newByMonth( $render = false ){ - $query = ''; - $union = ''; - - $allMonths = $this->allMonths(); - - for( $i = $this->from_month -1 ; $i < $this->to_month; $i++ ){ - $month = $allMonths[ $i ]; - $query .= $union . "SELECT '{$month}' AS Month, - COUNT(*) AS Total - FROM - (SELECT COUNT(*) orders, - u.phone, - o.date, - u.id_user - FROM `order` o - INNER JOIN user u ON u.id_user = o.id_user - LEFT JOIN community c ON o.id_community = c.id_community - WHERE o.date <= LAST_DAY( STR_TO_DATE( '{$month}', '%Y-%m' ) ) - {$this->queryExcludeCommunties} - {$this->queryExcludeUsers} - GROUP BY u.phone HAVING orders = 1) Orders - WHERE Orders.date BETWEEN '{$month}-01' AND LAST_DAY( STR_TO_DATE( '{$month}', '%Y-%m' ) )"; - $union = ' UNION '; - } + $query = "SELECT SUM(1) AS Total, + DATE_FORMAT(o.date ,'%Y-%m') AS Month + FROM `order` o + INNER JOIN + (SELECT min(id_order) id_order, + u.phone + FROM `order` o + INNER JOIN USER u ON u.id_user = o.id_user + LEFT JOIN community c ON o.id_community = c.id_community + {$this->queryExcludeCommunties} + {$this->queryExcludeUsers} + GROUP BY u.phone) orders ON o.id_order = orders.id_order + GROUP BY DATE_FORMAT(o.date ,'%Y-%m') HAVING Month BETWEEN '{$this->monthFrom}' AND '{$this->monthTo}'"; + $parsedData = $this->parseDataMonthSimple( $query, $this->description ); if( $render ){ return array( 'data' => $parsedData, 'unit' => $this->unity, 'interval' => 'month' ); @@ -167,39 +157,45 @@ class Crunchbutton_Chart_User extends Crunchbutton_Chart { return $parsedData; } + public function newByDay( $render = false ){ + $query = "SELECT SUM(1) AS Total, + DATE_FORMAT(o.date ,'%Y-%m-%d') AS Day + FROM `order` o + INNER JOIN + (SELECT min(id_order) id_order, + u.phone + FROM `order` o + INNER JOIN USER u ON u.id_user = o.id_user + LEFT JOIN community c ON o.id_community = c.id_community + GROUP BY u.phone) orders ON o.id_order = orders.id_order + GROUP BY DATE_FORMAT(o.date ,'%Y-%m-%d') HAVING Day BETWEEN '{$this->dayFrom}' AND '{$this->dayTo}'"; + + $parsedData = $this->parseDataDaysSimple( $query, $this->description ); + if( $render ){ + return array( 'data' => $parsedData, 'unit' => $this->unity, 'interval' => 'day' ); + } + return $parsedData; + } + public function newByWeek( $render = false ){ - $query = ''; - $union = ''; - - $allWeeks = $this->allWeeks(); - - for( $i = $this->from -1 ; $i < $this->to; $i++ ){ - $week = $allWeeks[ $i ]; - $query .= $union . "SELECT '{$week}' AS Week, - COUNT(*) AS Total - FROM - (SELECT COUNT(*) orders, - u.phone, - o.date, - u.id_user - FROM `order` o - INNER JOIN user u ON u.id_user = o.id_user - LEFT JOIN community c ON o.id_community = c.id_community - WHERE o.date <= STR_TO_DATE('{$week} Saturday', '%X%V %W') - {$this->queryExcludeCommunties} - {$this->queryExcludeUsers} - GROUP BY u.phone HAVING orders = 1) Orders - WHERE Orders.date BETWEEN STR_TO_DATE('{$week} Sunday', '%X%V %W') AND STR_TO_DATE('{$week} Saturday', '%X%V %W')"; - $union = ' UNION '; - } - + $query = "SELECT SUM(1) AS Total, + YEARWEEK(o.date) AS Week + FROM `order` o + INNER JOIN + (SELECT min(id_order) id_order, + u.phone + FROM `order` o + INNER JOIN USER u ON u.id_user = o.id_user + LEFT JOIN community c ON o.id_community = c.id_community + GROUP BY u.phone) orders ON o.id_order = orders.id_order + GROUP BY YEARWEEK(o.date) HAVING Week BETWEEN '{$this->weekFrom}' AND '{$this->weekTo}'"; + $parsedData = $this->parseDataWeeksSimple( $query, $this->description ); if( $render ){ return array( 'data' => $parsedData, 'unit' => $this->unity ); } return $parsedData; - } public function newPerActiveByWeekByCommunity( $render = false ){ diff --git a/include/views/default/cockpit/charts/column.phtml b/include/views/default/cockpit/charts/column.phtml index 0fe50fa76..c745249ca 100644 --- a/include/views/default/cockpit/charts/column.phtml +++ b/include/views/default/cockpit/charts/column.phtml @@ -93,6 +93,10 @@ ?> Months from to (of ): + Months from to (of ): +
@@ -120,6 +124,7 @@ $(function () { labels : { rotation: -45, align: 'right' + ,step:10 } }, yAxis: { @@ -162,6 +167,11 @@ $(function () { values: [ , ], max: , + values: [ , ], + max: , + change: function( event, ui ) { var activeUserDays = $( '#active-user-days' ).val(); diff --git a/include/views/default/cockpit/home/index.phtml b/include/views/default/cockpit/home/index.phtml index 804b92329..802cada6e 100644 --- a/include/views/default/cockpit/home/index.phtml +++ b/include/views/default/cockpit/home/index.phtml @@ -305,7 +305,7 @@ $( '#button-reload' ).click( function(){ $( '.chart' ).each( function(){ var chart = $( this ); - if( chart.attr( 'opened' ) ){ + if( chart.attr( 'opened' ) == 'true' ){ loadChart( chart.attr( 'id' ), true ); $( '#button-reload' ).find( 'i' ).addClass( 'icon-spin ' ); setTimeout( function(){