162 lines
4.2 KiB
PHP
162 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Ramcar\InvoiceCriteria;
|
|
use App\Ramcar\TradeInType;
|
|
|
|
use App\Entity\Invoice;
|
|
use App\Entity\InvoiceItem;
|
|
use App\Entity\User;
|
|
|
|
use Doctrine\Common\Util\Debug;
|
|
|
|
class InvoiceCreator
|
|
{
|
|
const VAT_RATE = 0.12;
|
|
const TIRATE_MOTOLITE = 200.00;
|
|
const TIRATE_OTHER = 100.00;
|
|
|
|
// creates invoice based on the criteria sent
|
|
public function __construct()
|
|
{
|
|
}
|
|
|
|
public function getVATAmount($price)
|
|
{
|
|
$vat_ex_price = $this->getVATExclusivePrice($price);
|
|
return round($vat_ex_price * self::VAT_RATE, 2);
|
|
}
|
|
|
|
public function getVATExclusivePrice($price)
|
|
{
|
|
return round($price / (1 + self::VAT_RATE), 2);
|
|
}
|
|
|
|
public function getTradeInRate($trade_in)
|
|
{
|
|
if ($trade_in == 'motolite')
|
|
return self::TIRATE_MOTOLITE;
|
|
|
|
return self::TIRATE_OTHER;
|
|
}
|
|
|
|
protected function processBatteries(&$total, InvoiceCriteria $criteria, Invoice $invoice)
|
|
{
|
|
// get batteries
|
|
$batts = $criteria->getBatteries();
|
|
|
|
// consolidate batteries
|
|
$con_batts = [];
|
|
foreach ($batts as $batt)
|
|
{
|
|
$batt_id = $batt->getID();
|
|
|
|
// initialize
|
|
if (!isset($con_batts[$batt_id]))
|
|
$con_batts[$batt->getID()] = [
|
|
'batt' => $batt,
|
|
'qty' => 0
|
|
];
|
|
|
|
// increment quantity
|
|
$con_batts[$batt_id]['qty']++;
|
|
}
|
|
|
|
// process batteries
|
|
foreach ($con_batts as $con_data)
|
|
{
|
|
$batt = $con_data['batt'];
|
|
$qty = $con_data['qty'];
|
|
|
|
$sell_price = $batt->getSellingPrice();
|
|
$vat = $this->getVATAmount($sell_price);
|
|
// $vat_ex_price = $this->getVATExclusivePrice($sell_price);
|
|
|
|
$total['sell_price'] += $sell_price * $qty;
|
|
$total['vat'] += $vat * $qty;
|
|
$total['vat_ex_price'] += ($sell_price - $vat) * $qty;
|
|
|
|
$total['total_price'] += $sell_price * $qty;
|
|
|
|
// add item
|
|
$item = new InvoiceItem();
|
|
$item->setInvoice($invoice)
|
|
->setTitle($batt->getModel()->getName() . ' ' . $batt->getSize()->getName())
|
|
->setQuantity($qty)
|
|
->setPrice($sell_price);
|
|
|
|
$invoice->addItem($item);
|
|
}
|
|
}
|
|
|
|
protected function processTradeIns(&$total, InvoiceCriteria $criteria, Invoice $invoice)
|
|
{
|
|
// get trade-ins
|
|
$trade_ins = $criteria->getTradeIns();
|
|
|
|
// consolidate
|
|
$con_tis = [];
|
|
foreach ($trade_ins as $ti)
|
|
{
|
|
if (!isset($con_tis[$ti]))
|
|
$con_tis[$ti] = 0;
|
|
|
|
$con_tis[$ti]++;
|
|
}
|
|
|
|
// process
|
|
foreach ($con_tis as $ti => $qty)
|
|
{
|
|
$ti_rate = $this->getTradeInRate($ti);
|
|
|
|
$total['ti_rate'] += $ti_rate * $qty;
|
|
$total['total_price'] -= $ti_rate * $qty;
|
|
|
|
// add item
|
|
$item = new InvoiceItem();
|
|
$item->setInvoice($invoice)
|
|
->setTitle('Trade-in ' . TradeInType::getName($ti) . ' battery')
|
|
->setQuantity($qty)
|
|
->setPrice($ti_rate * -1);
|
|
|
|
$invoice->addItem($item);
|
|
}
|
|
}
|
|
|
|
protected function processDiscount(&$total, InvoiceCriteria $criteria, Invoice $invoice)
|
|
{
|
|
}
|
|
|
|
public function processCriteria(InvoiceCriteria $criteria)
|
|
{
|
|
$invoice = new Invoice();
|
|
|
|
$total = [
|
|
'sell_price' => 0.0,
|
|
'vat' => 0.0,
|
|
'vat_ex_price' => 0.0,
|
|
'ti_rate' => 0.0,
|
|
'total_price' => 0.0,
|
|
];
|
|
|
|
$this->processBatteries($total, $criteria, $invoice);
|
|
$this->processTradeIns($total, $criteria, $invoice);
|
|
$this->processDiscount($total, $criteria, $invoice);
|
|
|
|
// TODO: check if any promo is applied
|
|
// apply discounts
|
|
$promos = $criteria->getPromos();
|
|
|
|
$invoice->setTotalPrice($total['total_price'])
|
|
->setVATExclusivePrice($total['vat_ex_price'])
|
|
->setVAT($total['vat'])
|
|
->setTradeIn($total['ti_rate']);
|
|
|
|
|
|
// dump
|
|
//Debug::dump($invoice, 1);
|
|
|
|
return $invoice;
|
|
}
|
|
}
|