invoice report
This commit is contained in:
@@ -54,4 +54,15 @@ class EmployeeHoursController extends MY_Controller {
|
|||||||
$this->json( $result );
|
$this->json( $result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInvoiceOverview( $year )
|
||||||
|
{
|
||||||
|
$sql = Qinvoiceoverview::fire( $year );
|
||||||
|
|
||||||
|
$query = $this->db->query( $sql );
|
||||||
|
|
||||||
|
$result = $query->result();
|
||||||
|
|
||||||
|
$this->json( $result );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -30,8 +30,9 @@ class QEmployeeHours {
|
|||||||
0 AS revenues,
|
0 AS revenues,
|
||||||
SUM(hours) AS nonprojecthours
|
SUM(hours) AS nonprojecthours
|
||||||
FROM employeehours
|
FROM employeehours
|
||||||
WHERE YEAR(hourdate) = '{$year}'
|
WHERE YEAR(hourdate) = '{$year}' ";
|
||||||
AND MONTH(hourdate) = '$month'
|
if( $month != 0 ) $sql .= "AND MONTH(hourdate) = '$month' ";
|
||||||
|
$sql .= "
|
||||||
GROUP BY employee_id, MONTH(hourdate)
|
GROUP BY employee_id, MONTH(hourdate)
|
||||||
UNION
|
UNION
|
||||||
SELECT PEM.user_id,
|
SELECT PEM.user_id,
|
||||||
@@ -44,13 +45,14 @@ class QEmployeeHours {
|
|||||||
FROM projecthours PH
|
FROM projecthours PH
|
||||||
JOIN projectemployees PEM
|
JOIN projectemployees PEM
|
||||||
ON PEM.id = PH.projectemployee_id
|
ON PEM.id = PH.projectemployee_id
|
||||||
WHERE YEAR(hourdate) = '{$year}'
|
WHERE YEAR(hourdate) = '{$year}' ";
|
||||||
AND MONTH(hourdate) = '$month'
|
if( $month != 0 ) $sql .= "AND MONTH(hourdate) = '$month' ";
|
||||||
|
$sql .= "
|
||||||
GROUP BY PEM.user_id, MONTH(hourdate)
|
GROUP BY PEM.user_id, MONTH(hourdate)
|
||||||
) AS Q1
|
) AS Q1
|
||||||
JOIN users AS USR
|
JOIN users AS USR
|
||||||
ON USR.id = Q1.user_id
|
ON USR.id = Q1.user_id
|
||||||
GROUP BY monthID, user_id ";
|
GROUP BY user_id ";
|
||||||
|
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by Pensare Software.
|
||||||
|
* User: Theo Weijmer
|
||||||
|
* Date: 02/03/2018
|
||||||
|
* Time: 15:56
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Qinvoiceoverview {
|
||||||
|
|
||||||
|
|
||||||
|
public static function fire( $year )
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT PRJ.id, PRJ.projectnumber,
|
||||||
|
PRJ.projectname,
|
||||||
|
(own_revenue + other_revenue ) AS revenues,
|
||||||
|
CUS.name AS customername,
|
||||||
|
IF( YEAR(invoicedate) = {$year},SUM(invoiceamount), 0) AS currentyear,
|
||||||
|
IF( YEAR(invoicedate) != {$year},SUM(invoiceamount), 0) AS otheryear,
|
||||||
|
COALESCE(Q1.currentyearpayed, 0) AS currentyearpayed,
|
||||||
|
COALESCE(Q1.otheryearpayed, 0) AS otheryearpayed,
|
||||||
|
CONCAT(firstname, ' ', middlename, ' ', lastname) AS fullname
|
||||||
|
FROM invoices INV
|
||||||
|
RIGHT JOIN projects PRJ
|
||||||
|
ON PRJ.id = INV.project_id
|
||||||
|
JOIN offers OFF
|
||||||
|
ON PRJ.id = OFF.project_id
|
||||||
|
JOIN customers CUS
|
||||||
|
ON CUS.id = PRJ.customer_id
|
||||||
|
JOIN users USR
|
||||||
|
ON USR.id = PRJ.projectleader_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT invoice_id,
|
||||||
|
SUM(IF(YEAR(paymentdate) = {$year},paymentamount, 0)) AS currentyearpayed,
|
||||||
|
SUM(IF(YEAR(paymentdate) != {$year},paymentamount, 0)) AS otheryearpayed
|
||||||
|
FROM payments
|
||||||
|
GROUP BY invoice_id
|
||||||
|
) AS Q1
|
||||||
|
ON INV.id = Q1.invoice_id
|
||||||
|
GROUP BY PRJ.projectnumber, PRJ.projectname ";
|
||||||
|
|
||||||
|
return $sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
<div id="OUTGOINGINVOICES">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-1">
|
||||||
|
<label>jaar</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-3">
|
||||||
|
<select class="form-control form-control-sm"
|
||||||
|
data-bind="options:years,
|
||||||
|
optionsText:'year',
|
||||||
|
optionsValue: 'id',
|
||||||
|
value:selectedYear,
|
||||||
|
event:{change:refreshInvoiceDetails}"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<table class="table table-condensed" style="font-size:0.8em;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>project</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>klant</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>status afgehandeld</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>projectleider</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>te factureren(excl btw)</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>te factureren(incl btw)</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>gefactureerd voorgaande jaren(incl btw)</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>gefactureerd lopend jaar(incl btw)</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>totaal gefactureerd(incl btw)</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>betaald voorgaande jaren</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>betaald lopend jaar</span></div>
|
||||||
|
</th>
|
||||||
|
<th class="rotate">
|
||||||
|
<div><span>totaal betaald</span></div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- ko foreach: projects -->
|
||||||
|
<tr>
|
||||||
|
<td><span data-bind="text:projectnumber"></span></td>
|
||||||
|
<td><span data-bind="text:customername"></span></td>
|
||||||
|
<td><span data-bind="text:statusProject == 'CLOSED' ? 'afgesloten' : 'open'"></span></td>
|
||||||
|
<td><span data-bind="text:fullname"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:openstaand"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:openstaandIncl"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:invoicedOtherYears"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:invoicedCurentYear"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:totalInvoiced"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:invoicedOtherYearsPayed"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:invoicedCurentYearPayed"></span>
|
||||||
|
</td>
|
||||||
|
<td class="align-right">
|
||||||
|
<i class="icon fa-euro"></i>
|
||||||
|
<span data-bind="text:totalInvoicedPayed"></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- /ko -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -71,6 +71,7 @@
|
|||||||
<script src="js/lib/modules/projects/employeehoursModule.js?version=<?= $this->version ?>"></script>
|
<script src="js/lib/modules/projects/employeehoursModule.js?version=<?= $this->version ?>"></script>
|
||||||
<script src="js/lib/modules/reports/monthlyEmployeeHoursModule.js?version=<?= $this->version ?>"></script>
|
<script src="js/lib/modules/reports/monthlyEmployeeHoursModule.js?version=<?= $this->version ?>"></script>
|
||||||
<script src="js/lib/modules/reports/employeeHours.js?version=<?= $this->version ?>"></script>
|
<script src="js/lib/modules/reports/employeeHours.js?version=<?= $this->version ?>"></script>
|
||||||
|
<script src="js/lib/modules/reports/outgoingInvoices.js?version=<?= $this->version ?>"></script>
|
||||||
|
|
||||||
<!-- ***********MODALS************* -->
|
<!-- ***********MODALS************* -->
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@
|
|||||||
<script src="js/lib/dataservices/vatDataservice.js"></script>
|
<script src="js/lib/dataservices/vatDataservice.js"></script>
|
||||||
<script src="js/lib/dataservices/employeehoursDataService.js"></script>
|
<script src="js/lib/dataservices/employeehoursDataService.js"></script>
|
||||||
<script src="js/lib/dataservices/reportsDataService.js"></script>
|
<script src="js/lib/dataservices/reportsDataService.js"></script>
|
||||||
|
<script src="js/lib/dataservices/invoiceDataService.js"></script>
|
||||||
|
|
||||||
<script src="js/lib/services/chartService.js"></script>
|
<script src="js/lib/services/chartService.js"></script>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Created by Pensare Software.
|
||||||
|
* User: Theo Weijmer
|
||||||
|
* Date: 02/03/2018
|
||||||
|
* Time: 16:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
dbo.invoiceDataService = {
|
||||||
|
|
||||||
|
getInvoiceOverview: function ( year, callback ) {
|
||||||
|
$.getJSON( 'index.php/reports/employeeHoursController/getInvoiceOverview/' + year )
|
||||||
|
.done( function ( data ) {
|
||||||
|
callback( data );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ dbo.employeehoursreportInit = function () {
|
|||||||
dbo.employeeHoursreportModel = {
|
dbo.employeeHoursreportModel = {
|
||||||
|
|
||||||
months : ko.observableArray( [
|
months : ko.observableArray( [
|
||||||
|
{monthID: 0, monthName : 'totaal'},
|
||||||
{monthID: 1, monthName: 'jan'},
|
{monthID: 1, monthName: 'jan'},
|
||||||
{monthID: 2, monthName: 'febr'},
|
{monthID: 2, monthName: 'febr'},
|
||||||
{monthID: 3, monthName: 'mrt'},
|
{monthID: 3, monthName: 'mrt'},
|
||||||
@@ -55,7 +56,7 @@ dbo.employeehoursreportInit = function () {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
vm.selectedYear( (new Date()).getFullYear() );
|
vm.selectedYear( (new Date()).getFullYear() );
|
||||||
vm.selectedMonthID( 1 );
|
vm.selectedMonthID( 0 );
|
||||||
|
|
||||||
vm.initialize = false;
|
vm.initialize = false;
|
||||||
|
|
||||||
@@ -103,10 +104,10 @@ dbo.employeehoursreportInit = function () {
|
|||||||
_.each( data, function ( p ) {
|
_.each( data, function ( p ) {
|
||||||
vm.employees.push( new vm.Employee( p ) );
|
vm.employees.push( new vm.Employee( p ) );
|
||||||
|
|
||||||
vm.profitablehoursTotaal( vm.profitablehoursTotaal() + Number( p.profitablehours ) );
|
vm.profitablehoursTotaal( Math.round(vm.profitablehoursTotaal() + Number( p.profitablehours )) );
|
||||||
vm.nonprofitablehoursTotaal( vm.nonprofitablehoursTotaal() + Number( p.nonprofitablehours ) );
|
vm.nonprofitablehoursTotaal( Math.round(vm.nonprofitablehoursTotaal() + Number( p.nonprofitablehours ) ));
|
||||||
vm.nonprojecthoursTotaal( vm.nonprojecthoursTotaal() + Number( p.nonprojecthours ) );
|
vm.nonprojecthoursTotaal( Math.round(vm.nonprojecthoursTotaal() + Number( p.nonprojecthours ) ));
|
||||||
vm.totalhoursTotaal( vm.totalhoursTotaal() + Number( p.totalhours ) );
|
vm.totalhoursTotaal( Math.round(vm.totalhoursTotaal() + Number( p.totalhours )) );
|
||||||
vm.targetTotaal( Math.round( vm.targetTotaal() + Number( p.targethours / 12 ) ) );
|
vm.targetTotaal( Math.round( vm.targetTotaal() + Number( p.targethours / 12 ) ) );
|
||||||
vm.revenuesTotaal( Number( vm.revenuesTotaal() ) + Number( p.revenues ) );
|
vm.revenuesTotaal( Number( vm.revenuesTotaal() ) + Number( p.revenues ) );
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ dbo.employeehoursreportInit = function () {
|
|||||||
this.profitablehours = data.profitablehours;
|
this.profitablehours = data.profitablehours;
|
||||||
this.nonprofitablehours = data.nonprofitablehours;
|
this.nonprofitablehours = data.nonprofitablehours;
|
||||||
this.nonprojecthours = data.nonprojecthours;
|
this.nonprojecthours = data.nonprojecthours;
|
||||||
this.totalhours = data.totalhours;
|
this.totalhours = Math.round(data.totalhours);
|
||||||
this.target = Math.round( data.targethours / 12 );
|
this.target = Math.round( data.targethours / 12 );
|
||||||
this.occupancyRateTotal = Math.round( (data.totalhours / (data.targethours / 12)) * 100 );
|
this.occupancyRateTotal = Math.round( (data.totalhours / (data.targethours / 12)) * 100 );
|
||||||
this.occupancyRateHours = Math.round( (data.profitablehours / data.totalhours ) * 100 );
|
this.occupancyRateHours = Math.round( (data.profitablehours / data.totalhours ) * 100 );
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* Created by Pensare Software.
|
||||||
|
* User: Theo Weijmer
|
||||||
|
* Date: 02/03/2018
|
||||||
|
* Time: 11:43
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
dbo.outgoinginvoicesInit = function () {
|
||||||
|
|
||||||
|
if ( dbo.outgoinginvoicesModel !== undefined ) {
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
dbo.outgoinginvoicesModel = {
|
||||||
|
|
||||||
|
initialize : null,
|
||||||
|
years : ko.observableArray( [] ),
|
||||||
|
selectedYear : ko.observable(),
|
||||||
|
selectedMonthID: ko.observable(),
|
||||||
|
projects : ko.observableArray( [] ),
|
||||||
|
|
||||||
|
init: function () {
|
||||||
|
var vm = dbo.outgoinginvoicesModel;
|
||||||
|
|
||||||
|
vm.initialize = true;
|
||||||
|
dbo.reportsDataService.getUsedYears( function ( data ) {
|
||||||
|
vm.years.removeAll();
|
||||||
|
_.each( data, function ( p ) {
|
||||||
|
vm.years.push( {id: p.year, year: p.year} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
vm.selectedYear( (new Date()).getFullYear() );
|
||||||
|
vm.selectedMonthID( 0 );
|
||||||
|
|
||||||
|
vm.initialize = false;
|
||||||
|
|
||||||
|
vm.initModule();
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
|
||||||
|
initModule: function () {
|
||||||
|
var vm = dbo.outgoinginvoicesModel;
|
||||||
|
|
||||||
|
vm.refreshInvoiceDetails();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
refreshInvoiceDetails: function () {
|
||||||
|
var vm = dbo.outgoinginvoicesModel;
|
||||||
|
|
||||||
|
if ( vm.initialize ) return;
|
||||||
|
|
||||||
|
dbo.invoiceDataService.getInvoiceOverview( vm.selectedYear(), function ( data ) {
|
||||||
|
vm.projects.removeAll();
|
||||||
|
_.each( data, function ( p ) {
|
||||||
|
vm.projects.push( new vm.Project( p ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
|
||||||
|
Project: function ( data ) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dbo.outgoinginvoicesModel.init();
|
||||||
|
|
||||||
|
ko.applyBindings(
|
||||||
|
dbo.outgoinginvoicesModel, document.getElementById( "OUTGOINGINVOICES" ) );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user