added basic invoice rendering #97 #93 (#99)

This commit is contained in:
Kevin Papst
2018-01-21 22:50:46 +01:00
committed by GitHub
parent 9a161b8fd9
commit 4cbc5391c0
73 changed files with 2986 additions and 918 deletions

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Invoice;
use App\Model\InvoiceModel;
/**
* CalculatorInterface defines all methods for any invoice price calculator.
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
interface CalculatorInterface
{
/**
* @param InvoiceModel $model
*/
public function setModel(InvoiceModel $model);
/**
* @return float
*/
public function getSubtotal(): float;
/**
* @return float
*/
public function getTax(): float;
/**
* @return float
*/
public function getTotal(): float;
/**
* @return string
*/
public function getCurrency(): string;
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Invoice;
use App\Model\InvoiceModel;
/**
* Class DateNumberGenerator generates the invoice number based on the current day.
* It will create duplicate IDs if you create multiple invoices per day.
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
class DateNumberGenerator implements NumberGeneratorInterface
{
/**
* @var InvoiceModel
*/
protected $model;
/**
* @param InvoiceModel $model
*/
public function setModel(InvoiceModel $model)
{
$this->model = $model;
}
/**
* @return string
*/
public function getInvoiceNumber(): string
{
return date('ymd');
}
}

View File

@@ -0,0 +1,94 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Invoice;
use App\Model\InvoiceModel;
/**
* Class DefaultCalculator works on all given entries using:
* - the customers currency
* - the invoice template vat rate
* - the entries rate
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
class DefaultCalculator implements CalculatorInterface
{
/**
* @var string
*/
protected $currency;
/**
* @var InvoiceModel
*/
protected $model;
/**
* @param InvoiceModel $model
*/
public function setModel(InvoiceModel $model)
{
$this->model = $model;
}
/**
* @return float
*/
public function getSubtotal(): float
{
$amount = 0;
foreach ($this->model->getEntries() as $entry) {
$amount += $entry->getRate();
}
return round($amount, 2);
}
/**
* @return float
*/
public function getVat()
{
return $this->model->getTemplate()->getVat();
}
/**
* @return float
*/
public function getTax(): float
{
$vat = $this->getVat();
if ($vat == 0) {
return 0;
}
$percent = $vat / 100.00;
return round($this->getSubtotal() * $percent, 2);
}
/**
* @return float
*/
public function getTotal(): float
{
return $this->getSubtotal() + $this->getTax();
}
/**
* @return string
*/
public function getCurrency(): string
{
return $this->model->getCustomer()->getCurrency();
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Invoice;
use App\Model\InvoiceModel;
/**
* Class NumberGeneratorInterface defines all methods that invoice number generator have to implement.
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
interface NumberGeneratorInterface
{
/**
* @param InvoiceModel $model
*/
public function setModel(InvoiceModel $model);
/**
* @return string
*/
public function getInvoiceNumber(): string;
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Invoice;
use App\Model\InvoiceModel;
/**
* Class RandomNumberGenerator is meant for testing purpose only.
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
class RandomNumberGenerator implements NumberGeneratorInterface
{
/**
* @var InvoiceModel
*/
protected $model;
/**
* @param InvoiceModel $model
*/
public function setModel(InvoiceModel $model)
{
$this->model = $model;
}
/**
* @return string
*/
public function getInvoiceNumber(): string
{
return rand(1000000, 9999999);
}
}

View File

@@ -0,0 +1,106 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Invoice;
/**
* A service to manage the invoice configuration:
* - invoice number generator
* - invoice sum calculator
* - template renderer
*
* @author Kevin Papst <kevin@kevinpapst.de>
*/
class ServiceInvoice
{
/**
* @var array
*/
protected $config = [];
/**
* ServiceInvoice constructor.
* @param array $invoiceConfig
*/
public function __construct(array $invoiceConfig)
{
$this->config = $invoiceConfig;
}
/**
* @return array
*/
public function getNumberGenerator()
{
return $this->config['number_generator'];
}
/**
* @param string $name
* @return NumberGeneratorInterface|null
*/
public function getNumberGeneratorByName(string $name)
{
foreach ($this->getNumberGenerator() as $key => $class) {
if ($key === $name) {
return new $class();
}
}
return null;
}
/**
* @return array
*/
public function getCalculator()
{
return $this->config['calculator'];
}
/**
* @param string $name
* @return CalculatorInterface|null
*/
public function getCalculatorByName(string $name)
{
foreach ($this->getCalculator() as $key => $class) {
if ($key === $name) {
return new $class();
}
}
return null;
}
/**
* Returns an array of invoice renderer, which will consist of a unique name and a controller action.
*
* @return array
* @throws \Exception
*/
public function getRenderer()
{
return $this->config['renderer'];
}
/**
* @param $renderer
* @return string|null
*/
public function getRendererActionByName($renderer)
{
foreach ($this->config['renderer'] as $name => $action) {
if ($name == $renderer) {
return $action;
}
}
return null;
}
}