Fix invoice generation computations
This commit is contained in:
parent
141212d4e6
commit
a3d793087d
3 changed files with 159 additions and 87 deletions
|
|
@ -632,6 +632,54 @@ class JobOrderController extends BaseController
|
|||
*/
|
||||
}
|
||||
|
||||
protected function invoicePromo($em, InvoiceCriteria $criteria, $promo_id)
|
||||
{
|
||||
// return error if there's a problem, false otherwise
|
||||
|
||||
if (empty($promo_id))
|
||||
return false;
|
||||
|
||||
// check if this is a valid promo
|
||||
$promo = $em->getRepository(Promo::class)->find($promo_id);
|
||||
|
||||
if (empty($promo))
|
||||
return 'Invalid promo specified.';
|
||||
|
||||
$criteria->addPromo($promo);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function invoiceBatteries($em, InvoiceCriteria $criteria, $items)
|
||||
{
|
||||
// return error if there's a problem, false otherwise
|
||||
|
||||
foreach ($items as $item)
|
||||
{
|
||||
// check if this is a valid battery
|
||||
$battery = $em->getRepository(Battery::class)->find($item['battery']);
|
||||
|
||||
if (empty($battery))
|
||||
{
|
||||
$error = 'Invalid battery specified.';
|
||||
return $error;
|
||||
}
|
||||
|
||||
// quantity
|
||||
$qty = $item['quantity'];
|
||||
if ($qty < 1)
|
||||
continue;
|
||||
|
||||
// add to criteria
|
||||
$criteria->addBattery($battery, $qty);
|
||||
|
||||
// if this is a trade in, add trade in
|
||||
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
||||
$criteria->addTradeIn($item['trade_in'] == 'motolite', $qty);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function generateInvoice(Request $req, InvoiceCreator $ic)
|
||||
{
|
||||
$error = false;
|
||||
|
|
@ -644,38 +692,11 @@ class JobOrderController extends BaseController
|
|||
// instantiate invoice criteria
|
||||
$criteria = new InvoiceCriteria();
|
||||
|
||||
if (!empty($promo_id))
|
||||
{
|
||||
// check if this is a valid promo
|
||||
$promo = $em->getRepository(Promo::class)->find($promo_id);
|
||||
|
||||
if (empty($promo))
|
||||
$error = 'Invalid promo specified.';
|
||||
else
|
||||
$criteria->addPromo($promo);
|
||||
}
|
||||
$error = $this->invoicePromo($em, $criteria, $promo_id);
|
||||
|
||||
if (!$error)
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
// check if this is a valid battery
|
||||
$battery = $em->getRepository(Battery::class)->find($item['battery']);
|
||||
|
||||
if (empty($battery))
|
||||
{
|
||||
$error = 'Invalid battery specified.';
|
||||
break;
|
||||
}
|
||||
|
||||
// add to criteria
|
||||
$criteria->addBattery($battery);
|
||||
|
||||
// if this is a trade in, add trade in
|
||||
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
||||
$criteria->addTradeIn($item['trade_in'] == 'motolite' ? true : false);
|
||||
}
|
||||
}
|
||||
$error = $this->invoiceBatteries($em, $criteria, $items);
|
||||
|
||||
|
||||
if ($error)
|
||||
{
|
||||
|
|
@ -693,7 +714,7 @@ class JobOrderController extends BaseController
|
|||
$invoice = [
|
||||
'discount' => number_format($iobj->getDiscount(), 2),
|
||||
'trade_in' => number_format($iobj->getTradeIn(), 2), // TODO: computations not done yet for this on invoice creator
|
||||
'price' => number_format($iobj->getVATExclusivePrice(), 2), // TODO: computations not done yet for this on invoice creator
|
||||
'price' => number_format($iobj->getVATExclusivePrice(), 2),
|
||||
'vat' => number_format($iobj->getVAT(), 2),
|
||||
'total_price' => number_format($iobj->getTotalPrice(), 2),
|
||||
'items' => []
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ class InvoiceCriteria
|
|||
$this->trade_ins = [];
|
||||
}
|
||||
|
||||
public function addBattery(Battery $battery)
|
||||
public function addBattery(Battery $battery, $qty = 1)
|
||||
{
|
||||
$this->batteries[] = $battery;
|
||||
for ($i = 0; $i < $qty; $i++)
|
||||
$this->batteries[] = $battery;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -40,17 +41,20 @@ class InvoiceCriteria
|
|||
return $this->promos;
|
||||
}
|
||||
|
||||
public function addTradeIn($is_motolite)
|
||||
public function addTradeIn($is_motolite, $qty = 1)
|
||||
{
|
||||
// NOTE: this asumes that all the rates for trade-ins are standardized
|
||||
// for motolite and non-motolite trade-ins
|
||||
|
||||
if ($is_motolite)
|
||||
$trade_in = 'motolite';
|
||||
else
|
||||
$trade_in = 'other';
|
||||
for ($i = 0; $i < $qty; $i++)
|
||||
{
|
||||
if ($is_motolite)
|
||||
$trade_in = 'motolite';
|
||||
else
|
||||
$trade_in = 'other';
|
||||
|
||||
$this->trade_ins[] = $trade_in;
|
||||
$this->trade_ins[] = $trade_in;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Service;
|
||||
|
||||
use App\Ramcar\InvoiceCriteria;
|
||||
use App\Ramcar\TradeInType;
|
||||
|
||||
use App\Entity\Invoice;
|
||||
use App\Entity\InvoiceItem;
|
||||
|
|
@ -13,8 +14,8 @@ use Doctrine\Common\Util\Debug;
|
|||
class InvoiceCreator
|
||||
{
|
||||
const VAT_RATE = 0.12;
|
||||
const TIRATE_MOTOLITE = 300.00;
|
||||
const TIRATE_OTHER = 150.00;
|
||||
const TIRATE_MOTOLITE = 200.00;
|
||||
const TIRATE_OTHER = 100.00;
|
||||
|
||||
// creates invoice based on the criteria sent
|
||||
public function __construct()
|
||||
|
|
@ -40,6 +41,93 @@ class InvoiceCreator
|
|||
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();
|
||||
|
|
@ -48,63 +136,22 @@ class InvoiceCreator
|
|||
'sell_price' => 0.0,
|
||||
'vat' => 0.0,
|
||||
'vat_ex_price' => 0.0,
|
||||
|
||||
'ti_rate' => 0.0,
|
||||
|
||||
'total_price' => 0.0,
|
||||
];
|
||||
|
||||
// get batteries
|
||||
$batts = $criteria->getBatteries();
|
||||
foreach ($batts as $batt)
|
||||
{
|
||||
$sell_price = $batt->getSellingPrice();
|
||||
$vat = $this->getVATAmount($sell_price);
|
||||
$vat_ex_price = $this->getVATExclusivePrice($sell_price);
|
||||
|
||||
$total['sell_price'] += $sell_price;
|
||||
$total['vat'] += $vat;
|
||||
$total['vat_ex_price'] += $vat_ex_price;
|
||||
|
||||
$total['total_price'] += $sell_price;
|
||||
|
||||
// add item
|
||||
$item = new InvoiceItem();
|
||||
$item->setInvoice($invoice)
|
||||
->setTitle($batt->getModel()->getName() . ' ' . $batt->getSize()->getName())
|
||||
->setQuantity(1)
|
||||
->setPrice($sell_price);
|
||||
|
||||
$invoice->addItem($item);
|
||||
}
|
||||
|
||||
// get trade-ins
|
||||
$trade_ins = $criteria->getTradeIns();
|
||||
foreach ($trade_ins as $ti)
|
||||
{
|
||||
$ti_rate = $this->getTradeInRate($ti);
|
||||
|
||||
$total['ti_rate'] += $ti_rate;
|
||||
|
||||
$total['total_price'] -= $ti_rate;
|
||||
|
||||
// add item
|
||||
$item = new InvoiceItem();
|
||||
$item->setInvoice($invoice)
|
||||
->setTitle('Trade-in battery')
|
||||
->setQuantity(1)
|
||||
->setPrice($ti_rate);
|
||||
|
||||
$invoice->addItem($item);
|
||||
}
|
||||
$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'])
|
||||
->setDiscount($total['ti_rate']);
|
||||
->setTradeIn($total['ti_rate']);
|
||||
|
||||
|
||||
// dump
|
||||
|
|
|
|||
Loading…
Reference in a new issue