diff --git a/application/controllers/projects/ProjectsController.php b/application/controllers/projects/ProjectsController.php index c1e0b2e..0c90994 100644 --- a/application/controllers/projects/ProjectsController.php +++ b/application/controllers/projects/ProjectsController.php @@ -212,6 +212,42 @@ class ProjectsController extends MY_Controller { $this->json( ['success' => TRUE, 'projecthourID' => $paymentID] ); } + public function saveForecast() + { + $forecastValidation = new ForecastValidation(); + + if ( ! $forecastValidation->getValidationResult() ) + return $this->json( [ + 'success' => FALSE, 'messages' => $forecastValidation->getErrorMessages()] ); + + $forecast = $this->input->post(); + + $forecastID = $forecast['id']; + unset( $forecast['id'] ); + + $forecastID = Forecast::saveForecast( $forecastID, $forecast ); + + $this->json( ['success' => TRUE, 'forecastID' => $forecastID] ); + } + + public function saveReservation() + { + $reservationValidation = new ReservationValidation(); + + if ( ! $reservationValidation->getValidationResult() ) + return $this->json( [ + 'success' => FALSE, 'messages' => $reservationValidation->getErrorMessages()] ); + + $reservation = $this->input->post(); + + $reservationID = $reservation['id']; + unset( $reservation['id'] ); + + $reservationID = Reservation::saveReservation( $reservationID, $reservation ); + + $this->json( ['success' => TRUE, 'reservationID' => $reservationID] ); + } + public function archiveProject( $projectID, $status ) { Project::whereId( $projectID )->update( ['archive' => $status] ); @@ -261,4 +297,26 @@ class ProjectsController extends MY_Controller { $this->json( ['result' => TRUE] ); } + public function removeForecast( $forecastID ) + { + $removeForecast = new RemoveForecast( $forecastID ); + + if ( $removeForecast->getAllowDelete() === FALSE ) return $this->json( ['result' => FALSE] ); + + Forecast::removeForecast( $forecastID ); + + $this->json( ['result' => TRUE] ); + } + + public function removeReservation( $reservationID ) + { + $removeReservation = new RemoveReservation( $reservationID ); + + if ( $removeReservation->getAllowDelete() === FALSE ) return $this->json( ['result' => FALSE] ); + + Forecast::removeReservation( $reservationID ); + + $this->json( ['result' => TRUE] ); + } + } \ No newline at end of file diff --git a/application/controllers/reports/EmployeeHoursController.php b/application/controllers/reports/EmployeeHoursController.php index 0bbf2b3..132bfaa 100644 --- a/application/controllers/reports/EmployeeHoursController.php +++ b/application/controllers/reports/EmployeeHoursController.php @@ -62,6 +62,17 @@ class EmployeeHoursController extends MY_Controller { $result = $query->result(); + foreach ( $result as $project ) + { + $sql = QinvoiceMonthOverview::fire( $project->id, $year ); + + $query = $this->db->query( $sql ); + + $months = $query->result(); + + $project->months = $months; + } + $this->json( $result ); } diff --git a/application/libraries/projects/RemoveForecast.php b/application/libraries/projects/RemoveForecast.php new file mode 100644 index 0000000..70f8f3b --- /dev/null +++ b/application/libraries/projects/RemoveForecast.php @@ -0,0 +1,36 @@ +setForecastID( $forecastID ); + + $this->handle(); + } + + public function getAllowDelete() + { + return $this->allowDelete; + } + + private function setForecastID( $forecastID ) + { + $this->forecastID = $forecastID; + } + + private function handle() + { + + } + +} \ No newline at end of file diff --git a/application/libraries/projects/RemoveReservation.php b/application/libraries/projects/RemoveReservation.php new file mode 100644 index 0000000..de13dca --- /dev/null +++ b/application/libraries/projects/RemoveReservation.php @@ -0,0 +1,36 @@ +setReservationID( $reservationID ); + + $this->handle(); + } + + public function getAllowDelete() + { + return $this->allowDelete; + } + + private function setReservationID( $reservationID ) + { + $this->reservationID = $reservationID; + } + + private function handle() + { + + } + +} \ No newline at end of file diff --git a/application/libraries/validation/inputValidations/ForecastValidation.php b/application/libraries/validation/inputValidations/ForecastValidation.php new file mode 100644 index 0000000..b70f9dc --- /dev/null +++ b/application/libraries/validation/inputValidations/ForecastValidation.php @@ -0,0 +1,40 @@ + [ + 'validations' => 'required|integer', + 'fieldname' => 'project' + ], + 'year' => [ + 'validations' => 'integer', + 'fieldname' => 'jaar' + ], + 'month_id' => [ + 'validations' => 'integer', + 'fieldname' => 'maand' + ], + 'forecastamount' => [ + 'validations' => 'number', + 'fieldname' => 'bedrag' + ] + ]; + + public function __construct() + { + parent::__construct(); + + $this->ci =& get_instance(); + } +} \ No newline at end of file diff --git a/application/libraries/validation/inputValidations/ReservationValidation.php b/application/libraries/validation/inputValidations/ReservationValidation.php new file mode 100644 index 0000000..7b72c54 --- /dev/null +++ b/application/libraries/validation/inputValidations/ReservationValidation.php @@ -0,0 +1,32 @@ + [ + 'validations' => 'required|integer', + 'fieldname' => 'project' + ], + 'reservationamount' => [ + 'validations' => 'number', + 'fieldname' => 'bedrag' + ] + ]; + + public function __construct() + { + parent::__construct(); + + $this->ci =& get_instance(); + } +} \ No newline at end of file diff --git a/application/models/eloquent/Forecast.php b/application/models/eloquent/Forecast.php new file mode 100644 index 0000000..ec3e733 --- /dev/null +++ b/application/models/eloquent/Forecast.php @@ -0,0 +1,38 @@ +belongsTo( 'Project' ); + } + + public static function saveForecast( $forecastID, $forecast ) + { + $forecast = (array) $forecast; + + if ( $forecastID == 0 ) + { + $forecast = self::create( $forecast ); + $forecastID = $forecast['id']; + } + else + { + self::whereId( $forecastID )->update( $forecast ); + } + + return $forecastID; + } + + public static function removeForecast( $forecastID ) + { + Forecast::whereId( $forecastID )->delete(); + } + +} \ No newline at end of file diff --git a/application/models/eloquent/Project.php b/application/models/eloquent/Project.php index 0182870..39d9362 100644 --- a/application/models/eloquent/Project.php +++ b/application/models/eloquent/Project.php @@ -31,6 +31,16 @@ class Project extends BaseModel { return $this->hasMany( 'Invoice' ); } + public function forecasts() + { + return $this->hasMany( 'Forecast' ); + } + + public function reservations() + { + return $this->hasMany( 'Reservation' ); + } + public function projectleader() { return $this->belongsTo( 'User', 'projectleader_id' ); @@ -96,6 +106,8 @@ class Project extends BaseModel { 'projectemployees.user' => function ( $q ) { $q->selectRaw( "id, CONCAT(firstname, ' ', middlename, ' ', lastname) AS fullname" ); }] ) + ->with(['forecasts']) + ->with(['reservations']) ->with( 'projectemployees.projecthours' ) ->with( 'projectcosts.external' ) ->with( 'invoices.payments' ) diff --git a/application/models/eloquent/Reservation.php b/application/models/eloquent/Reservation.php new file mode 100644 index 0000000..d3f6c49 --- /dev/null +++ b/application/models/eloquent/Reservation.php @@ -0,0 +1,38 @@ +belongsTo( 'Project' ); + } + + public static function saveReservation( $reservationID, $reservation ) + { + $reservation = (array) $reservation; + + if ( $reservationID == 0 ) + { + $reservation = self::create( $reservation ); + $reservationID = $reservation['id']; + } + else + { + self::whereId( $reservationID )->update( $reservation ); + } + + return $reservationID; + } + + public static function removeReservation( $reservationID ) + { + Reservation::whereId( $reservationID )->delete(); + } + +} \ No newline at end of file diff --git a/application/models/eloquent/queries/QinvoiceMonthOverview.php b/application/models/eloquent/queries/QinvoiceMonthOverview.php new file mode 100644 index 0000000..569dca9 --- /dev/null +++ b/application/models/eloquent/queries/QinvoiceMonthOverview.php @@ -0,0 +1,43 @@ += MONTH(NOW()) -1, forecastamount, 0), 0)) AS currentforecast, + SUM(IF(year > {$year}, forecastamount, 0)) AS otherforecast + FROM forecasts + GROUP BY project_id + ) AS Q3 + ON PRJ.id = Q3.project_id GROUP BY PRJ.projectnumber, PRJ.projectname "; return $sql; diff --git a/application/views/modals/partials/_forecasts.php b/application/views/modals/partials/_forecasts.php new file mode 100644 index 0000000..99b298e --- /dev/null +++ b/application/views/modals/partials/_forecasts.php @@ -0,0 +1,78 @@ +
+
+

+ prognoses +

+
+
+ + + + + + + + + + + + + + + + + + + + +
+ jaar + + maand + + bedrag +  
+ + + + + + + + + + + + + + +
+ +
+
+
\ No newline at end of file diff --git a/application/views/modals/partials/_invoices.php b/application/views/modals/partials/_invoices.php index 6579876..5addf2f 100644 --- a/application/views/modals/partials/_invoices.php +++ b/application/views/modals/partials/_invoices.php @@ -126,7 +126,6 @@ -   diff --git a/application/views/modals/partials/_reservations.php b/application/views/modals/partials/_reservations.php new file mode 100644 index 0000000..a8295ee --- /dev/null +++ b/application/views/modals/partials/_reservations.php @@ -0,0 +1,55 @@ +
+
+

+ Reserveringen +

+
+
+ + + + + + + + + + + + + + + + + + +
+ bedrag + + betaald +  
+ + + + + + + + + + + +
+ +
+
+
\ No newline at end of file diff --git a/application/views/modals/project_modal.php b/application/views/modals/project_modal.php index 43b01cd..24155a5 100644 --- a/application/views/modals/project_modal.php +++ b/application/views/modals/project_modal.php @@ -58,11 +58,17 @@
load->view( 'modals/partials/_projectcosts' ); ?>
+
+ load->view('modals/partials/_forecasts'); ?> +
-
+
load->view( 'modals/partials/_invoices' ); ?>
+
+ load->view( 'modals/partials/_reservations' ); ?> +
diff --git a/application/views/pages/outgoinginvoices_view.php b/application/views/pages/outgoinginvoices_view.php index c7f519e..3ab0340 100644 --- a/application/views/pages/outgoinginvoices_view.php +++ b/application/views/pages/outgoinginvoices_view.php @@ -14,91 +14,28 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
project
-
-
klant
-
-
status afgehandeld
-
-
projectleider
-
-
te factureren(excl btw)
-
-
te factureren(incl btw)
-
-
gefactureerd voorgaande jaren(incl btw)
-
-
gefactureerd lopend jaar(incl btw)
-
-
totaal gefactureerd(incl btw)
-
-
betaald voorgaande jaren
-
-
betaald lopend jaar
-
-
totaal betaald
-
- - - - - - - - - - - - - - - - - - - - - - - - -
+
\ No newline at end of file diff --git a/application/views/reports/invoices/_invoicetable.php b/application/views/reports/invoices/_invoicetable.php new file mode 100644 index 0000000..e3381e5 --- /dev/null +++ b/application/views/reports/invoices/_invoicetable.php @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
project
+
+
klant
+
+
status afgehandeld
+
+
projectleider
+
+
te factureren(excl btw)
+
+
te factureren(incl btw)
+
+
gefactureerd voorgaande jaren(incl btw)
+
+
gefactureerd lopend jaar(incl btw)
+
+
totaal gefactureerd(incl btw)
+
+
betaald voorgaande jaren
+
+
betaald lopend jaar
+
+
totaal betaald
+
+
nog niet betaald
+
+
nog te factureren
+
+
nog te factureren lopend jaar
+
+
nog te factureren na lopend jaar
+
+
verschil prognose - werkelijk
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ totaal + + + + + + +
\ No newline at end of file diff --git a/public/css/main.css b/public/css/main.css index de55d1a..a9f7440 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -99,6 +99,11 @@ th.rotate > div > span { height:20px; border:1px solid #777; } +th.focus-green{ + background-color:#dcf7b0; + border:0; + font-weight: bold; +} /*********SWITCH************/ .onoffswitch { diff --git a/public/js/lib/dataservices/invoiceDataService.js b/public/js/lib/dataservices/invoiceDataService.js index 16b553a..ca48069 100644 --- a/public/js/lib/dataservices/invoiceDataService.js +++ b/public/js/lib/dataservices/invoiceDataService.js @@ -13,6 +13,14 @@ dbo.invoiceDataService = { .done( function ( data ) { callback( data ); } ); + }, + + getMonthDetails: function ( year, callback ) { + $.getJSON( 'index.php/reports/employeeHoursController/getMonthDetails/' + year ) + .done( function ( data ) { + callback( data ); + } ); } + } \ No newline at end of file diff --git a/public/js/lib/dataservices/projectsDataservice.js b/public/js/lib/dataservices/projectsDataservice.js index 005dde6..758fd4b 100644 --- a/public/js/lib/dataservices/projectsDataservice.js +++ b/public/js/lib/dataservices/projectsDataservice.js @@ -41,12 +41,6 @@ dbo.projectDataService = { } ); }, - addProject: function ( callback ) { - $.getJSON( 'index.php/projects/projectsController/addProject', function ( data ) { - callback( data ); - } ); - }, - createProject: function ( offerID, callback ) { $.getJSON( 'index.php/projects/projectsController/creatProjectFromOffer/' + offerID ) .done( function ( data ) { @@ -99,6 +93,20 @@ dbo.projectDataService = { } ); }, + saveForecast: function ( submitDATA, callback ) { + $.post( 'index.php/projects/projectsController/saveForecast', submitDATA ) + .done( function ( data ) { + callback( data ); + } ); + }, + + saveReservation: function ( submitDATA, callback ) { + $.post( 'index.php/projects/projectsController/saveReservation', submitDATA ) + .done( function ( data ) { + callback( data ); + } ); + }, + archiveProject: function ( userID, status, callback ) { $.get( 'index.php/projects/projectsController/archiveProject/' + userID + '/' + status ) .done( function () { @@ -132,6 +140,20 @@ dbo.projectDataService = { .done( function ( data ) { callback( data ); } ); + }, + + removeForecast: function ( forecastID, callback ) { + $.getJSON( 'index.php/projects/projectsController/removeForecast/' + forecastID ) + .done( function ( data ) { + callback( data ); + } ); + }, + + removeReservation: function ( reservationID, callback ) { + $.getJSON( 'index.php/projects/projectsController/removeReservation/' + reservationID ) + .done( function ( data ) { + callback( data ); + } ); } diff --git a/public/js/lib/main.js b/public/js/lib/main.js index d2b758e..2440e14 100644 --- a/public/js/lib/main.js +++ b/public/js/lib/main.js @@ -31,17 +31,34 @@ $( function () { }; } ); -function uploadFile(file, foreignID, tablename, callback){ +function uploadFile( file, foreignID, tablename, callback ) { var url = 'index.php/utils/fileUpload/upload/' + foreignID + '/' + tablename; var xhr = new XMLHttpRequest(); var fd = new FormData(); - xhr.open("POST", url, true); - xhr.onreadystatechange = function() { - if (xhr.readyState == 4 && xhr.status == 200) { + xhr.open( "POST", url, true ); + xhr.onreadystatechange = function () { + if ( xhr.readyState == 4 && xhr.status == 200 ) { callback(); } }; - fd.append("userfile", file); + fd.append( "userfile", file ); + + xhr.send( fd ); +} + +dbo.monthLabels = ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december']; + +dbo.currentMonth = (new Date()).getMonth(); +dbo.monthArray = []; +for ( var I = 0; I < 12; I++ ) { + dbo.monthArray.push( {monthID: I, month: dbo.monthLabels[I]} ); +} + +dbo.currentYear = (new Date()).getFullYear(); +dbo.years = [] +for ( var I = (dbo.currentYear - 2); I <= dbo.currentYear + 2; I++ ) { + dbo.years.push( {year: I} ); +} + + - xhr.send(fd); -} \ No newline at end of file diff --git a/public/js/lib/modals/projectModal.js b/public/js/lib/modals/projectModal.js index f1ef923..5c7b786 100644 --- a/public/js/lib/modals/projectModal.js +++ b/public/js/lib/modals/projectModal.js @@ -23,6 +23,8 @@ $( function () { projectcosts : ko.observableArray( [] ), vats : ko.observableArray( [] ), availableEmployees: ko.observableArray( [] ), + forecasts : ko.observableArray( [] ), + reservations : ko.observableArray( [] ), showProject : ko.observable( false ), projectID : null, callback : null, @@ -37,6 +39,8 @@ $( function () { ownRevenue : ko.observable(), otherRevenue : ko.observable(), projectname : ko.observable(), + years : ko.observableArray( dbo.years ), + months : ko.observableArray( dbo.monthArray ), init: function () { var vm = dbo.editProjectModal; @@ -119,6 +123,14 @@ $( function () { vm.saveProjecthour( this ); }, + setPayment: function ( status ) { + var vm = dbo.editProjectModal; + + this.payed( status ); + + vm.saveReservation( this ); + }, + editProjecthour: function () { var self = this; var vm = dbo.editProjectModal; @@ -143,6 +155,30 @@ $( function () { } ); }, + editForecast: function () { + var self = this; + var vm = dbo.editProjectModal; + $.each( vm.forecasts(), function ( i, p ) { + if ( p.id == self.id ) { + p.inEdit( !p.inEdit() ); + } else { + p.inEdit( false ); + } + } ); + }, + + editReservation: function () { + var self = this; + var vm = dbo.editProjectModal; + $.each( vm.reservations(), function ( i, p ) { + if ( p.id == self.id ) { + p.inEdit( !p.inEdit() ); + } else { + p.inEdit( false ); + } + } ); + }, + newOffer: function () { var vm = dbo.editProjectModal; var service = dbo.offersService; @@ -244,6 +280,35 @@ $( function () { } ); }, + addForecast: function () { + var vm = dbo.editProjectModal; + + var forecast = { + id : 0, + project_id : vm.projectID, + year : dbo.currentYear, + month_id : dbo.currentMonth, + forecastamount: 0, + inEdit : true + }; + + vm.forecasts.push( new vm.Forecast( forecast ) ); + }, + + addReservation: function () { + var vm = dbo.editProjectModal; + + var reservation = { + id : 0, + project_id : vm.projectID, + reservationamount: 0, + payed : 'UNPAYED', + inEdit : true + }; + + vm.reservations.push( new vm.Reservation( reservation ) ); + }, + editProject: function ( projectID, callback ) { var vm = dbo.editProjectModal; @@ -394,6 +459,39 @@ $( function () { } ); }, + saveForecast: function () { + var vm = dbo.editProjectModal; + var self = this; + + var submitDATA = { + id : self.id, + project_id : self.project_id, + year : self.year(), + month_id : self.month_id(), + forecastamount: self.forecastamount() + } + + dbo.projectDataService.saveForecast( submitDATA, function ( data ) { + if ( data.success ) self.id = data.forecastID; + } ); + }, + + saveReservation: function ( self = false ) { + var vm = dbo.editProjectModal; + if ( !self ) self = this; + + var submitDATA = { + id : self.id, + project_id : self.project_id, + payed : self.payed(), + reservationamount: self.reservationamount() + } + + dbo.projectDataService.saveReservation( submitDATA, function ( data ) { + if ( data.success ) self.id = data.reservationID; + } ); + }, + removeProjectemployee: function () { var vm = dbo.editProjectModal; var self = this; @@ -510,6 +608,64 @@ $( function () { } ); }, + removeForecast: function () { + var vm = dbo.editProjectModal; + var self = this; + + tellMe( { + title : 'verwijderen prognose', + message : 'weet u zeker dat u deze prognose wilt verwijderen, dit kan niet ongedaan worden gemaakt', + notify : true, + noText : 'nee verwijder prognose niet', + yesText : 'ja verwijder de prognose', + modalClass: 'modal-warning' + }, function ( response ) { + console.log( response ); + if ( response ) { + dbo.projectDataService.removeForecast( self.id, function ( data ) { + if ( data.result ) { + vm.refreshProject(); + } else { + tellMe( { + title : 'fout bij verwijderen prognose', + message : 'de prognose kan niet worden verwijderd', + modalClass: 'modal-danger' + } ); + } + } ); + } + } ); + }, + + removeReservation: function () { + var vm = dbo.editProjectModal; + var self = this; + + tellMe( { + title : 'verwijderen reservering', + message : 'weet u zeker dat u deze reservering wilt verwijderen, dit kan niet ongedaan worden gemaakt', + notify : true, + noText : 'nee verwijder reservering niet', + yesText : 'ja verwijder de reservering', + modalClass: 'modal-warning' + }, function ( response ) { + console.log( response ); + if ( response ) { + dbo.projectDataService.removeReservation( self.id, function ( data ) { + if ( data.result ) { + vm.refreshProject(); + } else { + tellMe( { + title : 'fout bij verwijderen reserevring', + message : 'de reservering kan niet worden verwijderd', + modalClass: 'modal-danger' + } ); + } + } ); + } + } ); + }, + closeProject: function () { var vm = dbo.editProjectModal; @@ -577,6 +733,16 @@ $( function () { vm.invoices.push( new vm.Invoice( p ) ); } ); + vm.forecasts.removeAll(); + $.each( data.forecasts, function ( i, p ) { + vm.forecasts.push( new vm.Forecast( p ) ); + } ); + + vm.reservations.removeAll(); + $.each( data.reservations, function ( i, p ) { + vm.reservations.push( new vm.Reservation( p ) ); + } ); + vm.busy = false; dbo.charts.drawHoursVsBudget( 340, 230, 'hours-vs-budget' ); @@ -692,6 +858,23 @@ $( function () { this.paymentdate = ko.observable( dbo.helpers.mysql2date( data.paymentdate ) ); this.paymentamount = ko.observable( data.paymentamount ); this.inEdit = ko.observable( inEdit ); + }, + + Forecast: function ( data ) { + this.id = data.id; + this.project_id = data.project_id; + this.year = ko.observable( data.year ); + this.month_id = ko.observable( data.month_id ); + this.forecastamount = ko.observable( data.forecastamount ); + this.inEdit = ko.observable( data.inEdit || false ); + }, + + Reservation: function ( data ) { + this.id = data.id; + this.project_id = data.project_id; + this.reservationamount = ko.observable( data.reservationamount ); + this.payed = ko.observable( data.payed ); + this.inEdit = ko.observable( data.inEdit || false ); } }; @@ -704,7 +887,7 @@ $( function () { totalHours += Number( p.hours() ); } } ); - return totalHours.toFixed(2); + return totalHours.toFixed( 2 ); } ); dbo.editProjectModal.totalRevenue = ko.pureComputed( function () { diff --git a/public/js/lib/modules/reports/monthlyEmployeeHoursModule.js b/public/js/lib/modules/reports/monthlyEmployeeHoursModule.js index 269ba8d..832d32f 100644 --- a/public/js/lib/modules/reports/monthlyEmployeeHoursModule.js +++ b/public/js/lib/modules/reports/monthlyEmployeeHoursModule.js @@ -195,10 +195,10 @@ dbo.monthlyemployeehoursInit = function () { drawCharts: function ( self ) { if ( self.hourView() ) { - dbo.charts.drawHoursChart( 'hours-per-month-' + self.slug, self.chartData, dbo.charts.monthLabels, 'uren per maand', '#f28f25' ); + dbo.charts.drawHoursChart( 'hours-per-month-' + self.slug, self.chartData, dbo.monthLabels, 'uren per maand', '#f28f25' ); dbo.charts.drawHoursChart( 'hours-per-project-' + self.slug, self.totalHoursChart, self.projectChart, 'uren per project', '#0daef0' ); } else { - dbo.charts.drawHoursChart( 'revenue-per-month-' + self.slug, self.chartRevenueData, dbo.charts.monthLabels, 'omzet per maand', '#f28f25' ); + dbo.charts.drawHoursChart( 'revenue-per-month-' + self.slug, self.chartRevenueData, dbo.monthLabels, 'omzet per maand', '#f28f25' ); dbo.charts.drawHoursChart( 'revenue-per-project-' + self.slug, self.totalHoursRevenueChart, self.projectChart, 'omzet per project', '#0daef0' ); } }, diff --git a/public/js/lib/modules/reports/outgoingInvoices.js b/public/js/lib/modules/reports/outgoingInvoices.js index 0a47668..987434c 100644 --- a/public/js/lib/modules/reports/outgoingInvoices.js +++ b/public/js/lib/modules/reports/outgoingInvoices.js @@ -19,6 +19,8 @@ dbo.outgoinginvoicesInit = function () { selectedYear : ko.observable(), selectedMonthID: ko.observable(), projects : ko.observableArray( [] ), + invoiceTab : ko.observable( 'invoice' ), + months : ko.observableArray( dbo.monthArray ), init: function () { var vm = dbo.outgoinginvoicesModel; @@ -39,11 +41,16 @@ dbo.outgoinginvoicesInit = function () { } ); }, + setActivetab: function ( tab ) { + var vm = dbo.outgoinginvoicesModel; + + vm.invoiceTab( tab ); + }, + initModule: function () { var vm = dbo.outgoinginvoicesModel; vm.refreshInvoiceDetails(); - }, refreshInvoiceDetails: function () { @@ -56,27 +63,55 @@ dbo.outgoinginvoicesInit = function () { _.each( data, function ( p ) { vm.projects.push( new vm.Project( p ) ); } ); - } ); }, Project: function ( data ) { + var vm = dbo.outgoinginvoicesModel; + var self = this; var openstaand = data.revenues - (Number( data.currentyear ) + Number( data.otheryear )); - this.projectnumber = data.projectnumber; - this.customername = data.customername; - this.statusProject = Math.abs( openstaand ) > 2 ? 'OPEN' : 'CLOSED'; - this.fullname = data.fullname; - this.openstaand = dbo.helpers.numberWithPoints(Math.round(openstaand)); - this.openstaandIncl = dbo.helpers.numberWithPoints(Math.round(openstaand * 1.21)); - this.invoicedOtherYears = dbo.helpers.numberWithPoints(Math.round(data.otheryear)); - this.invoicedCurentYear = dbo.helpers.numberWithPoints(Math.round(data.currentyear)); - this.totalInvoiced = dbo.helpers.numberWithPoints(Math.round(data.currentyear) + Math.round(data.otheryear)); - this.invoicedOtherYearsPayed = dbo.helpers.numberWithPoints(Math.round(data.otheryearpayed)); - this.invoicedCurentYearPayed = dbo.helpers.numberWithPoints(Math.round(data.currentyearpayed)); - this.totalInvoicedPayed = dbo.helpers.numberWithPoints(Math.round(data.currentyearpayed) + Math.round(data.otheryearpayed)); + var totalInvoice = data.revenues * (1 + (data.vatrate / 100)); + var totalInvoiced = Math.round( data.currentyear ) + Math.round( data.otheryear ); + var totalInvoicedPayed = Math.round( data.currentyearpayed ) + Math.round( data.otheryearpayed ); + var notPayed = totalInvoiced - totalInvoicedPayed; + + self.projectnumber = data.projectnumber; + self.customername = data.customername; + self.statusProject = Math.abs( openstaand ) > 2 ? 'OPEN' : 'CLOSED'; + self.fullname = data.fullname; + self.revenues = dbo.helpers.numberWithPoints( data.revenues ); + self.totalInvoice = dbo.helpers.numberWithPoints( totalInvoice ); + self.openstaand = dbo.helpers.numberWithPoints( Math.round( openstaand ) ); + self.openstaandIncl = dbo.helpers.numberWithPoints( Math.round( openstaand * 1.21 ) ); + self.invoicedOtherYears = dbo.helpers.numberWithPoints( Math.round( data.otheryear ) ); + self.invoicedCurentYear = dbo.helpers.numberWithPoints( Math.round( data.currentyear ) ); + self.totalInvoiced = dbo.helpers.numberWithPoints( totalInvoiced ); + self.invoicedOtherYearsPayed = dbo.helpers.numberWithPoints( Math.round( data.otheryearpayed ) ); + self.invoicedCurentYearPayed = dbo.helpers.numberWithPoints( Math.round( data.currentyearpayed ) ); + self.totalInvoicedPayed = dbo.helpers.numberWithPoints( totalInvoicedPayed ); + self.notPayed = dbo.helpers.numberWithPoints( notPayed ); + self.toInvoice = dbo.helpers.numberWithPoints( totalInvoice - totalInvoiced ); + self.currentforecast = dbo.helpers.numberWithPoints( data.currentforecast ); + self.otherforecast = dbo.helpers.numberWithPoints( data.otherforecast ); + self.missingForecast = + dbo.helpers.numberWithPoints( totalInvoice - totalInvoiced - data.otherforecast ); + + self.months = ko.observableArray( [] ); + _.each( data.months, function ( p ) { + self.months.push( new vm.Month( p ) ); + + if ( !vm['forecast' + p.month] ) vm['forecast' + p.month] = ko.observable( 0 ); + vm['forecast' + p.month]( Number( vm['forecast' + p.month]() ) + Number( p.forecastamount ) ); + + if ( !vm['payment' + p.month] ) vm['payment' + p.month] = ko.observable( 0 ); + vm['payment' + p.month]( Number( vm['payment' + p.month]() ) + Number( p.paymentamount ) ); + } ); + }, + + Month: function ( data ) { + this.forecastamount = dbo.helpers.numberWithPoints( Number( data.forecastamount ).toFixed( 0 ) ); + this.paymentamount = dbo.helpers.numberWithPoints( Number( data.paymentamount ).toFixed( 0 ) ); } - - } dbo.outgoinginvoicesModel.init(); diff --git a/public/js/lib/services/chartService.js b/public/js/lib/services/chartService.js index 3ead5d4..ebb115a 100644 --- a/public/js/lib/services/chartService.js +++ b/public/js/lib/services/chartService.js @@ -9,7 +9,6 @@ dbo.charts = { pieColors : ['#ffcf30', '#06b2dc', '#048a44', '#a63305', '#a0c03b', '#ffcb22', '#89c540', '#f77c01', '#1094f6', '#6733ba'], barColor : ['#f3a921', '#f2770c', '#72221a', '#04843b', '#d63f2e', '#fec220'], - monthLabels: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], charts : [], drawHoursVsBudget: function ( hours, budget, element ) {