diff --git a/include/controllers/default/cockpit2/api/report/index.php b/include/controllers/default/cockpit2/api/report/index.php
new file mode 100644
index 000000000..7d50d3e0b
--- /dev/null
+++ b/include/controllers/default/cockpit2/api/report/index.php
@@ -0,0 +1,44 @@
+permission()->check( [ 'global' ] ) ){
+ $this->_error();
+ }
+
+ switch ( c::getPagePiece( 2 ) ) {
+ case 'first-time-user-gift-codes-used-per-school-per-day':
+ $this->_first_time_user_gift_codes_used_per_school_per_day();
+ break;
+ default:
+ $this->_error();
+ break;
+ }
+ }
+
+ private function _first_time_user_gift_codes_used_per_school_per_day(){
+
+ $start = $this->request()[ 'start' ];
+ $end = $this->request()[ 'end' ];
+
+ if( !$start || !$end ){
+ $this->_error();
+ }
+
+ $start = explode( '/' , $start );
+ $start = $start[ 2 ] . $start[ 0 ] . $start[ 1 ];
+
+ $end = explode( '/' , $end );
+ $end = $end[ 2 ] . $end[ 0 ] . $end[ 1 ];
+
+ echo json_encode( Crunchbutton_Report_FirstTimeUserGiftCodesUsedPerSchoolPerDay::report( $start, $end ) );exit;;
+
+ }
+
+ private function _error( $error = 'invalid request' ){
+ echo json_encode( [ 'error' => $error ] );
+ exit();
+ }
+}
diff --git a/include/library/Crunchbutton/Report/FirstTimeUserGiftCodesUsedPerSchoolPerDay.php b/include/library/Crunchbutton/Report/FirstTimeUserGiftCodesUsedPerSchoolPerDay.php
new file mode 100644
index 000000000..1521e2b96
--- /dev/null
+++ b/include/library/Crunchbutton/Report/FirstTimeUserGiftCodesUsedPerSchoolPerDay.php
@@ -0,0 +1,55 @@
+get( $query );
+ if( count( $results ) ){
+ $formatted_date = new DateTime( $date, new DateTimeZone( c::config()->timezone ) );
+ $formatted_date = $formatted_date->format( 'M jS Y' );
+ foreach( $results as $result ){
+ $community = $result->community;
+ $users = intval( $result->users );
+ $communities[] = [ 'users' => $users, 'day' => $formatted_date, 'community' => $community ];
+ $days[] = [ 'users' => $users, 'day' => $formatted_date, 'community' => $community ];
+ }
+ }
+ }
+ return [ 'days' => $days, 'communities' => $communities ];
+ }
+
+ public function __construct(){}
+}
\ No newline at end of file
diff --git a/include/views/default/cockpit2/bundle/js.phtml b/include/views/default/cockpit2/bundle/js.phtml
index 56909f9e2..cb05fdaeb 100644
--- a/include/views/default/cockpit2/bundle/js.phtml
+++ b/include/views/default/cockpit2/bundle/js.phtml
@@ -68,6 +68,7 @@
+
@@ -111,4 +112,5 @@
+
diff --git a/include/views/default/cockpit2/frontend/report/report-first-time-users-gift-card.phtml b/include/views/default/cockpit2/frontend/report/report-first-time-users-gift-card.phtml
new file mode 100644
index 000000000..741da69f7
--- /dev/null
+++ b/include/views/default/cockpit2/frontend/report/report-first-time-users-gift-card.phtml
@@ -0,0 +1,91 @@
+
+
+
+
+
First time user gift codes used per school per day
+
+
+
+
+
+
+
+
+
+
+ By Community
+
+
+
+
+
+ | Community |
+ Day |
+ Users |
+
+
+
+
+ | {{c.community}} |
+ {{c.day}} |
+ {{c.users}} |
+
+
+
+
+
+ By Day
+
+
+
+
+
+ | Community |
+ Day |
+ Users |
+
+
+
+
+ | {{d.community}} |
+ {{d.day}} |
+ {{d.users}} |
+
+
+
+
+
+
+
diff --git a/include/views/default/cockpit2/frontend/report/report.phtml b/include/views/default/cockpit2/frontend/report/report.phtml
new file mode 100644
index 000000000..d51c125d0
--- /dev/null
+++ b/include/views/default/cockpit2/frontend/report/report.phtml
@@ -0,0 +1,15 @@
+
+
+
diff --git a/include/views/default/cockpit2/frontend/tools/tools.phtml b/include/views/default/cockpit2/frontend/tools/tools.phtml
index f74c98b25..05bddfb6e 100644
--- a/include/views/default/cockpit2/frontend/tools/tools.phtml
+++ b/include/views/default/cockpit2/frontend/tools/tools.phtml
@@ -9,6 +9,7 @@
| Make a call / Send SMS |
| Blasts |
| Marketing: Outgoing Emails/Texts |
+ | Reports |
diff --git a/www/assets/cockpit/js/controllers.report.js b/www/assets/cockpit/js/controllers.report.js
new file mode 100644
index 000000000..b27f216b6
--- /dev/null
+++ b/www/assets/cockpit/js/controllers.report.js
@@ -0,0 +1,363 @@
+NGApp.config(['$routeProvider', function($routeProvider) {
+ $routeProvider
+ .when('/reports', {
+ action: 'tools',
+ controller: 'ReportsCtrl',
+ templateUrl: 'assets/view/report.html',
+ reloadOnSearch: false
+ })
+ .when('/report/first-time-users-gift-card', {
+ action: 'tools',
+ controller: 'ReportFirstTimeUserGiftCodesUsedPerSchoolPerDayCtrl',
+ templateUrl: 'assets/view/report-first-time-users-gift-card.html'
+ })
+}]);
+
+NGApp.controller( 'ReportsCtrl', function(){} );
+
+NGApp.controller( 'ReportFirstTimeUserGiftCodesUsedPerSchoolPerDayCtrl', function ( $scope, $filter, ReportService ) {
+
+ $scope.range = {};
+
+ var start = new Date();
+ start.setDate( start.getDate() - 14 );
+ $scope.range.start = start;
+
+ var end = new Date();
+ end.setDate( end.getDate() - 1 );
+ $scope.range.end = end;
+
+ $scope.result = null;
+
+ $scope.report = function(){
+
+ $scope.result = false;
+
+ if( $scope.form.$invalid ){
+ $scope.submitted = true;
+ return;
+ }
+
+ $scope.isProcessing = true;
+
+ var params = { 'start': $filter( 'date' )( $scope.range.start, 'MM/dd/yyyy'),
+ 'end': $filter( 'date' )( $scope.range.end, 'MM/dd/yyyy') };
+
+ ReportService.first_time_user_gift_codes_used_per_school_per_day( params, function( json ){
+ console.log('json',json);
+ $scope.isProcessing = false;
+ $scope.result = json;
+ } );
+ }
+
+} );
+
+NGApp.controller( 'PexCardIdCtrl', function ( $scope, $routeParams, $route, PexCardService, DriverOnboardingService ) {
+
+ $scope.submitted = false;
+ $scope.isSearching = false;
+
+ $scope.status = PexCardService.status;
+
+ $scope._id_admin = false;
+
+ $scope.search = function() {
+
+ $scope.card = null;
+
+ if( $scope.isSearching ){
+ return;
+ }
+
+ if( $scope && $scope.form && $scope.form.$invalid ){
+ $scope.submitted = true;
+ $scope.isSearching = false;
+ return;
+ }
+
+ $scope.isSearching = true;
+
+ PexCardService.pex_id( $scope.crunchbutton_card_id,
+ function( json ){
+ $scope.isSearching = false;
+ $scope.submitted = false;
+ if( json.id ){
+ $scope.card = json;
+ if( $scope._id_admin ){
+ $scope.card.id_admin = $scope._id_admin;
+ }
+ console.log('$scope._id_admin',$scope._id_admin);
+ console.log('$scope.card',$scope.card);
+ } else {
+ $scope.flash.setMessage( json.error, 'error' );
+ $scope.crunchbutton_card_id = '';
+ }
+ }
+ );
+ };
+
+ $scope.payinfo = function(){
+ if( $scope.card.admin_login ){
+ $scope.navigation.link( '/staff/' + $scope.card.admin_login + '/payinfo' );
+ }
+ }
+
+ $scope.remove_assignment = function(){
+ if( confirm( 'Confirm remove assignment?' ) ){
+ PexCardService.admin_pexcard_remove( $scope.card.id, function( json ){
+ if( json.success ){
+ $scope.card.id_admin = null;
+ $scope.card.admin_name = null;
+ $scope.card.admin_login = null;
+ $scope.flash.setMessage( 'Driver assigned removed!', 'success' );
+ } else {
+ $scope.flash.setMessage( 'Error removing assignment!', 'error' );
+ }
+
+ } );
+ }
+ }
+
+ $scope.open_card = function( id_card ){
+ change_card_status( id_card, PexCardService.status.OPEN );
+ }
+
+ $scope.block_card = function( id_card ){
+ change_card_status( id_card, PexCardService.status.BLOCKED );
+ }
+
+ var change_card_status = function( id_card, status ){
+ if( confirm( 'Confirm change card status to ' + status + '?' ) ){
+ PexCardService.pex_change_card_status( { id_card: id_card, status: status },
+ function( json ){
+ if( json.id ){
+ $scope.card = json;
+ $scope.flash.setMessage( 'Card status changed to ' + status, 'success' );
+ } else {
+ $scope.flash.setMessage( json.error, 'error' );
+ }
+ }
+ );
+ }
+ }
+
+ $scope.assign = function(){
+
+ if( $scope.isSaving ){
+ return;
+ }
+
+ if( $scope.formAssign.$invalid ){
+ $scope.assignedSubmitted = true;
+ $scope.isSaving = false;
+ return;
+ }
+ var last_four = $scope.card.cards[ 0 ].cardNumber;
+ var data = { 'id_pexcard': $scope.card.id, 'id_admin': $scope.card.id_admin, 'card_serial': $scope.card.lastName, 'last_four': last_four };
+ PexCardService.admin_pexcard( data, function( json ){
+ $scope.isSaving = false;
+ if( json.success ){
+ $scope.card.admin_name = json.success.name;
+ $scope.card.admin_login = json.success.login;
+ $scope.flash.setMessage( 'Driver assigned!', 'success' );
+ } else {
+ $scope.flash.setMessage( 'Error assigning driver!', 'error' );
+ }
+
+ } );
+ }
+
+ DriverOnboardingService.pexcard( function( json ){ $scope.drivers = json; } );
+
+ if( $routeParams.id ){
+ if( $route.current.driver ){
+ setTimeout( function() {
+ $scope._id_admin = parseInt( $routeParams.id );
+ console.log('$scope._id_admin',$scope._id_admin);
+ }, 50 );
+ } else {
+ setTimeout( function() {
+ $scope.crunchbutton_card_id = parseInt( $routeParams.id );
+ App.rootScope.$safeApply();
+ $scope.search();
+ }, 500 );
+ }
+ }
+
+} );
+
+
+NGApp.controller('PexCardLogViewCtrl', function ($scope, $routeParams, PexCardService) {
+
+ $scope.loading = true;
+
+ PexCardService.action( $routeParams.id, function( action ){
+ $scope.action = action.success;
+ $scope.loading = false;
+ } );
+
+} );
+
+NGApp.controller('PexConfigCtrl', function ($scope, PexCardService) {
+
+ $scope.yesNo = PexCardService.yesNo();
+
+ $scope.business = { 'serial': '' };
+ $scope.test = { 'serial': '' };
+
+ var load = function(){
+ PexCardService.config.load( function( json ){
+ if( !json.error ){
+ $scope.config = json;
+ $scope.business.cards = json.cards.business;
+ $scope.test.cards = json.cards.test;
+ $scope.ready = true;
+ }
+ } );
+ }
+
+ $scope.add_business = function(){
+
+ if( $scope.idAdding ){
+ return;
+ }
+
+ if( $scope.formBusiness.$invalid ){
+ App.alert( 'Please fill in all required fields' );
+ $scope.businessSubmitted = true;
+ return;
+ }
+ $scope.idAdding = true;
+ PexCardService.config.add_business( { 'serial' : $scope.business.serial }, function( data ){
+ $scope.idAdding = false;
+ if( data.error ){
+ App.alert( data.error);
+ return;
+ } else {
+ $scope.business.serial = '';
+ $scope.business.cards = data.cards.business;
+ $scope.saved = true;
+ $scope.flash.setMessage( 'Business card addedd!' );
+ }
+ } );
+ }
+
+ $scope.remove_business = function( id_config ){
+ if( confirm( 'Confirm remove the Business Card?' ) ){
+ PexCardService.config.remove_business( { 'id_config' : id_config }, function( data ){
+ if( data.error ){
+ App.alert( data.error);
+ return;
+ } else {
+ $scope.business.cards = data.cards.business;
+ $scope.flash.setMessage( 'Business card removed!' );
+ }
+ } );
+ }
+ }
+
+ $scope.add_test = function(){
+
+ if( $scope.idAdding ){
+ return;
+ }
+
+ if( $scope.formTest.$invalid ){
+ App.alert( 'Please fill in all required fields' );
+ $scope.testSubmitted = true;
+ return;
+ }
+ $scope.idAdding = true;
+ console.log('$scope.test',$scope.test);
+ PexCardService.config.add_test( { 'serial' : $scope.test.serial }, function( data ){
+ $scope.idAdding = false;
+ if( data.error ){
+ App.alert( data.error);
+ return;
+ } else {
+ $scope.test.serial = '';
+ $scope.test.cards = data.cards.test;
+ $scope.saved = true;
+ $scope.flash.setMessage( 'Test card addedd!' );
+ }
+ } );
+ }
+
+ $scope.remove_test = function( id_config ){
+ if( confirm( 'Confirm remove the Test Card?' ) ){
+ PexCardService.config.remove_test( { 'id_config' : id_config }, function( data ){
+ if( data.error ){
+ App.alert( data.error);
+ return;
+ } else {
+ $scope.test.cards = data.cards.test;
+ $scope.flash.setMessage( 'Test card removed!' );
+ }
+ } );
+ }
+ }
+
+ $scope.save = function(){
+ if( $scope.form.$invalid ){
+ App.alert( 'Please fill in all required fields' );
+ $scope.submitted = true;
+ return;
+ }
+ $scope.isSaving = true;
+ PexCardService.config.save( $scope.config, function( data ){
+ $scope.isSaving = false;
+ if( data.error ){
+ App.alert( data.error);
+ return;
+ } else {
+ $scope.basicInfo = data;
+ $scope.saved = true;
+ $scope.flash.setMessage( 'Information saved!' );
+ setTimeout( function() { $scope.saved = false; }, 1500 );
+ }
+ } );
+ }
+
+ if( $scope.account.isLoggedIn() ){
+ load();
+ }
+
+} );
+
+NGApp.controller('PexCardLogCtrl', function ($scope, PexCardService, ViewListService) {
+
+ angular.extend( $scope, ViewListService );
+
+ $scope.view({
+ scope: $scope,
+ watch: {
+ search: '',
+ status: 'all',
+ type: 'all',
+ _action: 'all'
+ },
+ update: function() {
+ PexCardService.logs($scope.query, function(d) {
+ $scope.logs = d.results;
+ $scope.complete(d);
+ });
+ }
+ });
+});
+
+NGApp.controller('PexCardCardLogCtrl', function ($scope, PexCardService, ViewListService) {
+ angular.extend( $scope, ViewListService );
+ $scope.view({
+ scope: $scope,
+ watch: {
+ search: '',
+ type: 'card_assign',
+ },
+ update: function() {
+ PexCardService.cardlog($scope.query, function(d) {
+ $scope.logs = d.results;
+ $scope.complete(d);
+ });
+ }
+ });
+});
diff --git a/www/assets/cockpit/js/service.report.js b/www/assets/cockpit/js/service.report.js
new file mode 100644
index 000000000..e02833180
--- /dev/null
+++ b/www/assets/cockpit/js/service.report.js
@@ -0,0 +1,19 @@
+NGApp.factory( 'ReportService', function( $resource, $http, $routeParams ) {
+
+ var service = { };
+
+ var report = $resource( App.service + 'report/:action/', { action: '@action' }, {
+ 'first_time_user_gift_codes_used_per_school_per_day' : { 'method': 'POST', params : { action: 'first-time-user-gift-codes-used-per-school-per-day' } },
+ } );
+
+
+ service.first_time_user_gift_codes_used_per_school_per_day = function( params, callback ){
+ report.first_time_user_gift_codes_used_per_school_per_day( params, function( data ){
+ console.log('data',data);
+ callback( data );
+ } );
+ }
+
+ return service;
+
+} );
\ No newline at end of file