// Service is any PHP class with methods related to some topic or model, like Invoice, in this case
// Notice: there's no Artisan command like "php artisan make:service".
// You need to create it manually as a simple PHP class in whatever folder you want.
// Usually it's app/Services, which may be further divided into subfolders
class InvoiceCalculator
{
private $tax;
public function __construct($invoice)
{
if(!$invoice instanceof Invoice && !$invoice instanceof Offer ) {
throw new \Exception("Not correct type for Invoice Calculator");
}
$this->tax = new Tax();
$this->invoice = $invoice;
}
public function getVatTotal()
{
$price = $this->getSubTotal()->getAmount();
return new Money($price * $this->tax->vatRate());
}
public function getTotalPrice(): Money
{
$price = 0;
$invoiceLines = $this->invoice->invoiceLines;
foreach ($invoiceLines as $invoiceLine) {
$price += $invoiceLine->quantity * $invoiceLine->price;
}
return new Money($price);
}
public function getSubTotal(): Money
{
$price = 0;
$invoiceLines = $this->invoice->invoiceLines;
foreach ($invoiceLines as $invoiceLine) {
$price += $invoiceLine->quantity * $invoiceLine->price;
}
return new Money($price / $this->tax->multipleVatRate());
}
public function getAmountDue()
{
return new Money($this->getTotalPrice()->getAmount() - $this->invoice->payments()->sum('amount'));
}
}