diff --git a/application/controllers/reports/ReportsController.php b/application/controllers/reports/ReportsController.php index efece4a..925ca3a 100644 --- a/application/controllers/reports/ReportsController.php +++ b/application/controllers/reports/ReportsController.php @@ -59,26 +59,22 @@ class ReportsController extends MY_Controller { $this->json( $result ); } - public function getInvoiceOverview( $year ) + public function getInvoiceOverview( $year = FALSE ) { - $sql = Qinvoiceoverview::fire( $year ); + $invoices = new Invoices( $year ); - $query = $this->db->query( $sql ); + $invoiceReport = $invoices->getInvoiceReport(); - $result = $query->result(); + $this->json( $invoiceReport ); + } - foreach ( $result as $project ) - { - $sql = QinvoiceMonthOverview::fire( $project->id, $year ); + public function createInvoicesSpreadsheet( $year = FALSE ) + { + $invoices = new Invoices( $year ); - $query = $this->db->query( $sql ); + $invoiceReport = $invoices->getInvoiceReport(); - $months = $query->result(); - - $project->months = $months; - } - - $this->json( $result ); + new InvoiceSpreadsheet($invoiceReport); } public function saveCurrentFinnacialYear( $projectID ) diff --git a/application/libraries/reports/invoice/Excel/InvoiceSheet.php b/application/libraries/reports/invoice/Excel/InvoiceSheet.php new file mode 100644 index 0000000..6aed139 --- /dev/null +++ b/application/libraries/reports/invoice/Excel/InvoiceSheet.php @@ -0,0 +1,80 @@ + 'project', + 'B' => 'klant', + 'C' => 'Totaal te factureren excl. btw', + 'D' => 'Totaal te factureren incl. btw', + 'E' => 'Gefactureerd overige jaren incl. btw', + 'F' => 'Gefactureerd lopende boekjaar incl. btw', + 'G' => 'Gefactureerd totaal incl. btw', + 'H' => 'Nog te factureren incl. btw' + ]; + + private $invoiceOverview; + private $sheet; + private $row; + + public function __construct( $invoiceOverview, $sheet ) + { + $this->invoiceOverview = $invoiceOverview; + $this->sheet = $sheet; + + $this->handle(); + } + + private function handle() + { + $this->setHeader(); + + $this->setBody(); + + $this->setTotals(); + } + + private function setHeader() + { + foreach ( self::HEADERS as $cell => $header ) + { + $this->sheet->setCellValue( $cell . '1', $header ); + $this->sheet->getColumnDimension( $cell )->setAutoSize( TRUE ); + } + } + + private function setBody() + { + $this->row = 2; + foreach ( $this->invoiceOverview AS $project ) + { + $this->sheet->setCellValue( 'A' . $this->row, $project['projectname'] ); + $this->sheet->setCellValue( 'B' . $this->row, $project['customer'] ); + $this->sheet->setCellValue( 'C' . $this->row, str_replace( '.', '', $project['totalToInvoicingExcl'] ) ); + $this->sheet->setCellValue( 'D' . $this->row, str_replace( '.', '', $project['totalToInvoicingIncl'] ) ); + $this->sheet->setCellValue( 'E' . $this->row, str_replace( '.', '', $project['totalInvoicedOtherYears'] ) ); + $this->sheet->setCellValue( 'F' . $this->row, str_replace( '.', '', $project['totalInvoicedThisYear'] ) ); + $this->sheet->setCellValue( 'G' . $this->row, str_replace( '.', '', $project['invoicesTotal'] ) ); + $this->sheet->setCellValue( 'H' . $this->row, str_replace( '.', '', $project['needInvoice'] ) ); + + $this->row ++; + } + } + + private function setTotals() + { + $lastRow = $this->row - 1; + $this->sheet->setCellValue( 'C' . $this->row, '=SUM(C2:C' . $lastRow . ')' ); + $this->sheet->setCellValue( 'D' . $this->row, '=SUM(D2:D' . $lastRow . ')' ); + $this->sheet->setCellValue( 'E' . $this->row, '=SUM(E2:E' . $lastRow . ')' ); + $this->sheet->setCellValue( 'F' . $this->row, '=SUM(F2:F' . $lastRow . ')' ); + $this->sheet->setCellValue( 'G' . $this->row, '=SUM(G2:G' . $lastRow . ')' ); + $this->sheet->setCellValue( 'H' . $this->row, '=SUM(H2:H' . $lastRow . ')' ); + } +} \ No newline at end of file diff --git a/application/libraries/reports/invoice/Excel/InvoiceSpreadsheet.php b/application/libraries/reports/invoice/Excel/InvoiceSpreadsheet.php new file mode 100644 index 0000000..bb73646 --- /dev/null +++ b/application/libraries/reports/invoice/Excel/InvoiceSpreadsheet.php @@ -0,0 +1,88 @@ +ci =& get_instance(); + + $this->invoiceReport = $invoiceReport; + + $this->ci->load->helper( 'download' ); + + $this->handle(); + } + + private function handle() + { + $this->setSpreadsheet(); + + $this->setInvoiceSheet(); + + $this->setFilename(); + + $this->setFullPathname(); + + $this->createFile(); + + $this->downloadSpreadsheet(); + } + + private function setSpreadsheet() + { + $this->spreadsheet = new Spreadsheet(); + } + + private function setInvoiceSheet() + { + $invoiceSheet = new Worksheet( $this->spreadsheet, 'Facturen' ); + + $this->invoiceSheet = + $this->spreadsheet->addSheet( $invoiceSheet ); + + new InvoiceSheet( $this->invoiceReport['invoiceOverview'], $this->invoiceSheet ); + } + + private function setFilename() + { + $this->filename = 'facturen' . date( 'YmdHis' ) . '.xlsx'; + } + + private function setFullPathname() + { + $this->fullpathname = MYROOTPATH . 'documents/spreadsheets/' . $this->filename; + } + + private function createFile() + { + $writer = new Xlsx( $this->spreadsheet ); + + $writer->save( $this->fullpathname ); + } + + private function downloadSpreadsheet() + { + $data = file_get_contents( $this->fullpathname ); + + force_download( $this->filename, $data ); + } + + +} \ No newline at end of file diff --git a/application/libraries/reports/invoice/InvoiceForecast.php b/application/libraries/reports/invoice/InvoiceForecast.php new file mode 100644 index 0000000..89ad696 --- /dev/null +++ b/application/libraries/reports/invoice/InvoiceForecast.php @@ -0,0 +1,124 @@ +project = $project; + $this->needInvoice = $needInvoice; + $this->year = $year; + + $this->handle(); + } + + public function getProjectDetails() + { + return $this->projectDetails; + } + + public function getNeedInvoice() + { + return $this->needInvoice; + } + + public function getForecastOtherYear() + { + return $this->forecastOtherYears; + } + + public function getForecastRemaining() + { + return $this->forecastRemaining; + } + + private function handle() + { + $this->setCurrentyear(); + + $this->setProjectname(); + + $this->setCustomer(); + + $this->loopForecasts(); + + $this->setForecastRemaining(); + + $this->setProjectDetails(); + } + + private function setCurrentyear() + { + $this->currentYear = date( 'Y' ); + } + + private function setProjectname() + { + $this->projectname = $this->project->projectname . '(' . $this->project->projectnumber . ')'; + } + + private function setCustomer() + { + $this->customer = $this->project->customer->name; + } + + private function loopForecasts() + { + if ( is_null( $this->project->forecasts ) ) return $this->forecastThisYear = 0; + + foreach ( $this->project->forecasts as $this->forecast ) + { + $this->setForecastThisYear(); + + $this->setForecastOtherYears(); + } + } + + private function setForecastThisYear() + { + if ( $this->forecast->year == $this->year ) + $this->forecastThisYear += $this->forecast->forecastamount; + } + + private function setForecastOtherYears() + { + if ( $this->forecast->year != $this->year ) + $this->forecastOtherYears += $this->forecast->forecastamount; + } + + private function setForecastRemaining() + { + $this->forecastRemaining = + $this->needInvoice - $this->forecastThisYear - $this->forecastOtherYears; + } + + private function setProjectDetails() + { + $this->projectDetails = [ + 'projectname' => $this->projectname, + 'customer' => $this->customer, + 'needInvoice' => number_format( $this->needInvoice, 0, ',', '.' ), + 'forecastThisYear' => number_format( $this->forecastThisYear, 0, ',', '.' ), + 'forecastOtherYears' => number_format( $this->forecastOtherYears, 0, ',', '.' ), + 'forecastRemaining' => number_format( $this->forecastRemaining, 0, ',', '.' ), + ]; + } + +} \ No newline at end of file diff --git a/application/libraries/reports/invoice/InvoiceOverview.php b/application/libraries/reports/invoice/InvoiceOverview.php new file mode 100644 index 0000000..b0f1397 --- /dev/null +++ b/application/libraries/reports/invoice/InvoiceOverview.php @@ -0,0 +1,129 @@ +project = $project; + + $this->handle(); + } + + public function getProjectDetails() + { + return $this->projectDetails; + } + + public function getNeedinvoice( ) + { + return $this->needInvoice; + } + + private function handle() + { + $this->setCurrentyear(); + + $this->setProjectname(); + + $this->setCustomer(); + + $this->setTotalToInvoicingExcl(); + + $this->setTotalToInvoicingIncl(); + + $this->setTotalInvoicedOtherYears(); + + $this->setTotalInvoicedThisYear(); + + $this->setInvoicesTotal(); + + $this->setNeedInvoice(); + + $this->setProjectDetails(); + } + + private function setCurrentyear() + { + $this->currentYear = date( 'Y' ); + } + + private function setProjectname() + { + $this->projectname = $this->project->projectname . '(' . $this->project->projectnumber . ')'; + } + + private function setCustomer() + { + $this->customer = $this->project->customer->name; + } + + private function setTotalToInvoicingExcl() + { + $offer = $this->project->offer; + + $this->totalToInvoicingExcl = + $offer->own_revenue + $offer->other_revenue + $offer->costs; + } + + private function setTotalToInvoicingIncl() + { + $this->totalToInvoicingIncl = + $this->totalToInvoicingExcl * ( 1 + ( $this->project->vat->vatrate / 100 ) ); + } + + private function setTotalInvoicedOtherYears() + { + $this->totalInvoicedOtherYears = + Invoice::invoicePerYear( $this->project->id, $this->currentYear, FALSE ); + } + + private function setTotalInvoicedThisYear() + { + $this->totalInvoicedThisYear = + Invoice::invoicePerYear( $this->project->id, $this->currentYear, TRUE ); + } + + private function setInvoicesTotal() + { + $this->invoicesTotal = + $this->totalInvoicedOtherYears + $this->totalInvoicedThisYear; + } + + private function setNeedInvoice() + { + $this->needInvoice = + $this->totalToInvoicingIncl - $this->invoicesTotal; + } + + private function setProjectDetails() + { + $this->projectDetails = [ + 'projectname' => $this->projectname, + 'customer' => $this->customer, + 'totalToInvoicingExcl' => number_format( $this->totalToInvoicingExcl, 0, ',', '.' ), + 'totalToInvoicingIncl' => number_format( $this->totalToInvoicingIncl, 0, ',', '.' ), + 'totalInvoicedOtherYears' => number_format( $this->totalInvoicedOtherYears, 0, ',', '.' ), + 'totalInvoicedThisYear' => number_format( $this->totalInvoicedThisYear, 0, ',', '.' ), + 'invoicesTotal' => number_format( $this->invoicesTotal, 0, ',', '.' ), + 'needInvoice' => number_format( $this->needInvoice, 0, ',', '.' ) + ]; + } +} \ No newline at end of file diff --git a/application/libraries/reports/invoice/Invoices.php b/application/libraries/reports/invoice/Invoices.php new file mode 100644 index 0000000..dcbc909 --- /dev/null +++ b/application/libraries/reports/invoice/Invoices.php @@ -0,0 +1,104 @@ +year = $year; + + $this->handle(); + } + + public function getInvoiceReport() + { + return $this->invoiceReport; + } + + private function handle() + { + $this->setProjects(); + + $this->loopProjects(); + + $this->setInvoiceReport(); + } + + private function setProjects() + { + $this->projects = Project::getProjectsForReport(); + } + + private function loopProjects() + { + foreach ( $this->projects as $this->project ) + { + $this->setInvoiceOverview(); + + $this->setInvoiceForecasts(); + + $this->setMonthForecasts(); + + $this->setMonthPayments(); + } + } + + private function setInvoiceOverview() + { + $this->invoiceOverview = new InvoiceOverview( $this->project, $this->year ); + + $this->invoiceOverviews[] = $this->invoiceOverview->getProjectDetails(); + } + + private function setInvoiceForecasts() + { + $this->invoiceForecast = + new InvoiceForecast( $this->project, $this->invoiceOverview->getNeedinvoice(), $this->year ); + + $this->invoiceForecasts[] = $this->invoiceForecast->getProjectDetails(); + } + + public function setMonthForecasts() + { + $this->monthForecast = + new MonthForecast( $this->invoiceForecast, $this->project, $this->year ); + + $this->monthForecasts[] = $this->monthForecast->getProjectDetails(); + } + + public function setMonthPayments() + { + $this->monthPayment = + new MonthPayments( $this->project, $this->year ); + + $this->monthPayments[] = $this->monthPayment->getProjectDetails(); + } + + private function setInvoiceReport() + { + $this->invoiceReport = [ + 'invoiceOverview' => $this->invoiceOverviews, + 'forecasts' => $this->invoiceForecasts, + 'monthForecasts' => $this->monthForecasts, + 'monthPayments' => $this->monthPayments + ]; + } +} \ No newline at end of file diff --git a/application/libraries/reports/invoice/MonthForecast.php b/application/libraries/reports/invoice/MonthForecast.php new file mode 100644 index 0000000..8fa6f8c --- /dev/null +++ b/application/libraries/reports/invoice/MonthForecast.php @@ -0,0 +1,91 @@ +project = $project; + $this->invoiceForecast = $invoiceForecast; + $this->year = $year; + + $this->handle(); + } + + public function getProjectDetails() + { + return $this->projectDetails; + } + + private function handle() + { + $this->setProjectname(); + + $this->setCustomer(); + + $this->setInitialsForecastMonths(); + + $this->loopForecasts(); + + $this->setProjectDetails(); + } + + private function setProjectname() + { + $this->projectname = $this->project->projectname . '(' . $this->project->projectnumber . ')'; + } + + private function setCustomer() + { + $this->customer = $this->project->customer->name; + } + + private function setInitialsForecastMonths() + { + for ( $i = 1; $i <= 12; $i ++ ) + { + $this->forecastMonths[ $i ] = ['forecastamount' => 0]; + } + } + + private function loopForecasts() + { + foreach ( $this->project->forecasts as $this->forecast ) + { + $this->setMonthForecast(); + } + } + + private function setMonthForecast() + { + if ( $this->forecast->year == $this->year ) + $this->forecastMonths[ $this->forecast->month_id ]['forecastamount'] += $this->forecast->forecastamount; + } + + private function setProjectDetails() + { + $this->projectDetails = [ + 'projectname' => $this->projectname, + 'customer' => $this->customer, + 'needInvoice' => number_format( $this->invoiceForecast->getNeedInvoice(), 0, ',', '.' ), + 'forecastOtherYears' => number_format( $this->invoiceForecast->getForecastOtherYear(), 0, ',', '.' ), + 'forecastRemaining' => number_format( $this->invoiceForecast->getForecastRemaining(), 0, ',', '.' ), + 'forecastMonths' => $this->forecastMonths + ]; + } + +} \ No newline at end of file diff --git a/application/libraries/reports/invoice/MonthPayments.php b/application/libraries/reports/invoice/MonthPayments.php new file mode 100644 index 0000000..023e25f --- /dev/null +++ b/application/libraries/reports/invoice/MonthPayments.php @@ -0,0 +1,100 @@ +project = $project; + $this->year = $year; + + $this->handle(); + } + + public function getProjectDetails() + { + return $this->projectDetails; + } + + private function handle() + { + $this->setProjectname(); + + $this->setCustomer(); + + $this->setInitialsMonthPayments(); + + $this->loopPayments(); + + $this->setProjectDetails(); + } + + private function setProjectname() + { + $this->projectname = $this->project->projectname . '(' . $this->project->projectnumber . ')'; + } + + private function setCustomer() + { + $this->customer = $this->project->customer->name; + } + + private function setInitialsMonthPayments() + { + for ( $i = 1; $i <= 12; $i ++ ) + { + $this->monthPayments[ $i ] = ['paymentamount' => 0]; + } + } + + private function loopPayments() + { + foreach ( $this->project->invoices as $invoice ) + { + foreach($invoice->payments as $this->payment) + { + $this->setMonthPayments(); + + $this->setTotalProjectPayments(); + } + } + } + + private function setMonthPayments() + { + $paymentYear = date( 'Y', strtotime( $this->payment->paymentdate ) ); + $paymentMonth = date( 'n', strtotime( $this->payment->paymentdate ) ); + + if ( $paymentYear == $this->year ) + $this->monthPayments[ $paymentMonth ]['paymentamount'] += $this->payment->paymentamount; + } + + private function setTotalProjectPayments() + { + $this->totalProjectPayments += $this->payment->paymentamount; + } + + private function setProjectDetails() + { + $this->projectDetails = [ + 'projectname' => $this->projectname, + 'customer' => $this->customer, + 'monthPayments' => $this->monthPayments, + 'totalProjectPayments' => number_format( $this->totalProjectPayments, 0, ',', '.' ) + ]; + } +} \ No newline at end of file diff --git a/application/models/eloquent/Invoice.php b/application/models/eloquent/Invoice.php index dbcf462..6430b1e 100644 --- a/application/models/eloquent/Invoice.php +++ b/application/models/eloquent/Invoice.php @@ -24,6 +24,28 @@ class Invoice extends BaseModel { return $this->belongsTo( 'Vat' ); } + public static function invoicePerYear( $projectID, $year, $thatYear = TRUE ) + { + $invoices = Invoice::selectRAW( 'SUM(invoiceamount * ( 1 +(vatrate / 100))) AS invoicetotal' ) + ->join( 'vats', 'vats.id', '=', 'invoices.vat_id' ) + ->whereProjectId( $projectID ); + + if ( $thatYear ) + { + $invoices = $invoices->whereRaw( "YEAR(invoicedate) = {$year}" ); + } + else + { + $invoices = $invoices->whereRaw( "YEAR(invoicedate) != {$year}" ); + } + + if ( $invoices->count() == 0 ) return 0; + + $invoices = $invoices->first(); + + return $invoices->invoicetotal; + } + public static function saveInvoice( $invoiceID, $invoice ) { $invoice = (array) $invoice; diff --git a/application/models/eloquent/Project.php b/application/models/eloquent/Project.php index 2fddfc4..86bd800 100644 --- a/application/models/eloquent/Project.php +++ b/application/models/eloquent/Project.php @@ -104,6 +104,13 @@ class Project extends BaseModel { return $projects; } + public static function getProjectsForReport() + { + $projects = self::getBaseProject()->get(); + + return $projects; + } + public static function getBaseProject() { $project = Project::with( [ @@ -115,6 +122,7 @@ class Project extends BaseModel { 'projectemployees.user' => function ( $q ) { $q->selectRaw( "id, CONCAT(firstname, ' ', middlename, ' ', lastname) AS fullname" ); }] ) + ->with('vat') ->with(['forecasts']) ->with(['reservations']) ->with( 'projectemployees.projecthours' ) diff --git a/application/views/pages/invoicereport_view.php b/application/views/pages/invoicereport_view.php new file mode 100644 index 0000000..6dc15c0 --- /dev/null +++ b/application/views/pages/invoicereport_view.php @@ -0,0 +1,61 @@ +
|
- project
- |
-
- klant
- |
-
- status afgehandeld
- |
-
-
-
-
-
- te factureren(excl btw)
- |
-
- te factureren(incl btw)
- |
-
- gefactureerd
- voorgaande jaren(incl btw) |
-
- gefactureerd
- lopend jaar(incl btw) |
-
- totaal gefactureerd
- |
-
- betaald voorgaande jaren
- |
-
- betaald lopend jaar
- |
-
- totaal betaald
- |
-
- nog niet betaald
- |
-
-
-
- nog te factureren (incl.btw)
- |
-
- nog te factureren lopend jaar
- |
-
- nog te factureren na lopend jaar
- |
-
- nog te prognotiseren
- |
-
-
-
- te factureren(incl btw)
- |
-
-
- te factureren volgende jaren
- |
-
-
-
- ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - - - - | - - - | -- - - | -- - - | -- - - | -- - - | -- - - | -- - - | -- - - | -- - - | - - -- - - | -- - - | -- - - | -- - - | - - -- - - | - -- - - | - -- - - - | - - - -- - - | - - -
| - totaal - | - -- - - | -- - - | -- - - | -- - - | - - -- - - | - -- - - | - -- - - | - - - -- - - | - - -|||||||||||
|
+ project
+ |
+
+ klant
+ |
+
+ Totaal te factureren
+ excl. btw |
+
+ Totaal te factureren
+ incl. btw |
+
+ Gefactureerd overige jaren
+ incl. btw |
+
+ Gefactureerd lopende boekjaar
+ incl. btw |
+
+ Gefactureerd totaal
+ incl. btw |
+
+ Nog te factureren
+ incl. btw |
+
|---|---|---|---|---|---|---|---|
| + | + | + | + | + | + | + | + |
| + totaal + | ++ + | ++ + | ++ + | ++ + | ++ + | ++ + | +|
|
+ project
+ |
+
+ klant
+ |
+
+ Nog te factureren
+ incl. btw |
+
+
+
+ |
+
+
+ Nog te factureren
+ na lopend boekjaar incl. btw |
+
+ Nog te prognotiseren
+ incl. btw |
+
|---|---|---|---|---|---|
| + | + | + + | + + | + | + |
| + + | ++ + | + ++ + | + ++ + | ++ + | +|
|
+ project
+ |
+
+ klant
+ |
+
+
+
+ |
+
+
+ Totaal gefactureerd
+ lopend boekjaar incl. btw |
+
|---|---|---|---|
| + | + + | + + | + |
| + totaal + | + ++ + | + ++ + | +|