Modify the invoice manager to be more generic. #744

This commit is contained in:
Korina Cordero 2023-07-04 06:05:34 -04:00
parent 783c26facc
commit b4bcc06e42
20 changed files with 744 additions and 910 deletions

View file

@ -45,6 +45,7 @@ class TestInvoiceManagerCommand extends Command
$this->testBatterySalesNoTradeInNoDiscountWithTax(); $this->testBatterySalesNoTradeInNoDiscountWithTax();
$this->testBatterySalesQuantityNoTradeInNoDiscountWithTax(); $this->testBatterySalesQuantityNoTradeInNoDiscountWithTax();
/*
// battery sales without tax // battery sales without tax
$this->testBatterySalesNoTradeInNoDiscountWithoutTax(); $this->testBatterySalesNoTradeInNoDiscountWithoutTax();
$this->testBatterySalesQuantityNoTradeInNoDiscountWithoutTax(); $this->testBatterySalesQuantityNoTradeInNoDiscountWithoutTax();
@ -153,7 +154,7 @@ class TestInvoiceManagerCommand extends Command
$this->testGenerateDraftInvoiceBatterySalesNoPromo(); $this->testGenerateDraftInvoiceBatterySalesNoPromo();
// test generateInvoiceInvoice call from ajax call // test generateInvoiceInvoice call from ajax call
$this->testGenerateInvoice(); $this->testGenerateInvoice(); */
return 0; return 0;
} }
@ -172,11 +173,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addEntry($battery, null, 1); $criteria->addEntry($battery, null, 1);
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -207,11 +204,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addEntry($battery, null, 2); $criteria->addEntry($battery, null, 2);
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -242,11 +235,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addEntry($battery, null, 1); $criteria->addEntry($battery, null, 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -276,11 +265,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addEntry($battery, null, 2); $criteria->addEntry($battery, null, 2);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -316,11 +301,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addEntry($battery, 'premium', 1); $criteria->addEntry($battery, 'premium', 1);
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -354,11 +335,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -392,11 +369,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -433,11 +406,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -474,11 +443,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -515,11 +480,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -556,11 +517,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -593,11 +550,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($battery, 'premium', 1); $criteria->addEntry($battery, 'premium', 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -629,11 +582,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($battery, 'motolite', 1); $criteria->addEntry($battery, 'motolite', 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -665,11 +614,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($battery, 'other', 1); $criteria->addEntry($battery, 'other', 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -704,11 +649,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($trade_battery, 'premium', 1); $criteria->addEntry($trade_battery, 'premium', 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -743,11 +684,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($trade_battery, 'motolite', 1); $criteria->addEntry($trade_battery, 'motolite', 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -782,11 +719,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($trade_battery, 'other', 1); $criteria->addEntry($trade_battery, 'other', 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -821,11 +754,7 @@ class TestInvoiceManagerCommand extends Command
// add battery for trade in // add battery for trade in
$criteria->addEntry($trade_battery, 'other', 3); $criteria->addEntry($trade_battery, 'other', 3);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -861,11 +790,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -904,11 +829,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addPromo($promo); $criteria->addPromo($promo);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -952,11 +873,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -1003,11 +920,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1044,11 +957,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addPromo($promo); $criteria->addPromo($promo);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
// error_log(print_r(json_encode($invoice_data), true)); // error_log(print_r(json_encode($invoice_data), true));
@ -1093,11 +1002,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addPromo($promo); $criteria->addPromo($promo);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1128,11 +1033,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1161,11 +1062,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->addEntry($battery, null, 1); $criteria->addEntry($battery, null, 1);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1197,11 +1094,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1232,11 +1125,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1267,11 +1156,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1302,11 +1187,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1336,11 +1217,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1369,11 +1246,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1402,11 +1275,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1435,11 +1304,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1465,11 +1330,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1493,11 +1354,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT); $criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1523,11 +1380,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1551,11 +1404,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setServiceType(ServiceType::JUMPSTART_WARRANTY); $criteria->setServiceType(ServiceType::JUMPSTART_WARRANTY);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1587,11 +1436,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setHasCoolant(); $criteria->setHasCoolant();
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1621,11 +1466,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1656,11 +1497,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$criteria->setHasCoolant(); $criteria->setHasCoolant();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1689,11 +1526,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1719,11 +1552,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1747,11 +1576,7 @@ class TestInvoiceManagerCommand extends Command
// TEST SCENARIO: post recharged with tax // TEST SCENARIO: post recharged with tax
$criteria->setServiceType(ServiceType::POST_RECHARGED); $criteria->setServiceType(ServiceType::POST_RECHARGED);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1777,11 +1602,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1807,11 +1628,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1843,11 +1660,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1878,11 +1691,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1912,11 +1721,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {
@ -1945,11 +1750,7 @@ class TestInvoiceManagerCommand extends Command
$criteria->setCustomerVehicle($cv); $criteria->setCustomerVehicle($cv);
$rules = $this->inv_manager->check($criteria); $invoice_data = $this->inv_manager->compute($criteria);
// error_log(print_r($rules, true));
$invoice_data = $this->inv_manager->compute($criteria, $rules);
foreach ($invoice_data as $data) foreach ($invoice_data as $data)
{ {

View file

@ -1,67 +0,0 @@
<?php
namespace App\Invoice;
use App\InvoiceInterface;
class BatteryReplacementWarranty implements InvoiceInterface
{
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
return 'invoice/battery.html.twig';
}
public function getID()
{
return 'battery_warranty';
}
public function compute($criteria, $stype_fees, &$total)
{
$stype = $criteria->getServiceType();
$items = [];
if ($stype == $this->getID())
{
// get the entries
$entries = $criteria->getEntries();
$stype_fee_id = $this->getID() . '_fee';
foreach($entries as $entry)
{
$batt = $entry['battery'];
$qty = 1;
$price = $stype_fees[$stype_fee_id];
$items[] = [
'service_type' => $this->getID(),
'battery' => $batt,
'qty' => $qty,
'title' => $this->getTitle($batt),
'price' => $price,
];
$qty_price = bcmul($price, $qty, 2);
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
}
}
return $items;
}
protected function getTitle($battery)
{
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit';
return $title;
}
}

View file

@ -1,77 +0,0 @@
<?php
namespace App\Invoice;
use App\InvoiceInterface;
class BatterySales implements InvoiceInterface
{
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
return 'invoice/battery.html.twig';
}
public function getID()
{
return 'battery_new';
}
public function compute($criteria, $stype_fees, &$total)
{
$stype = $criteria->getServiceType();
$items = [];
if ($stype == $this->getID())
{
// get the entries
$entries = $criteria->getEntries();
foreach($entries as $entry)
{
$batt = $entry['battery'];
$qty = $entry['qty'];
$trade_in = null;
if (isset($entry['trade_in']))
$trade_in = $entry['trade_in'];
$size = $batt->getSize();
if ($trade_in == null)
{
// battery purchase
$price = $batt->getSellingPrice();
$items[] = [
'service_type' => $this->getID(),
'battery' => $batt,
'qty' => $qty,
'title' => $this->getTitle($batt),
'price' => $price,
];
$qty_price = bcmul($price, $qty, 2);
$total['sell_price'] = bcadd($total['sell_price'], $qty_price, 2);
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
}
}
}
return $items;
}
protected function getTitle($battery)
{
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName();
return $title;
}
}

View file

@ -1,30 +0,0 @@
<?php
namespace App\Invoice;
use App\InvoiceInterface;
class ServiceType implements InvoiceInterface
{
public function check($criteria)
{
if ($criteria->getServiceType() != null)
return true;
return false;
}
public function getTemplate()
{
return 'invoice/service_type.html.twig';
}
public function getID()
{
return 'service_type';
}
public function compute($criteria, $stype_fees)
{
}
}

View file

@ -1,91 +0,0 @@
<?php
namespace App\Invoice;
use App\InvoiceInterface;
class Tax implements InvoiceInterface
{
public function check($criteria)
{
if (!empty($criteria->isTaxable()))
return true;
return false;
}
public function getTemplate()
{
return 'invoice/tax.html.twig';
}
public function getID()
{
return 'tax';
}
public function compute($tax_rate, $items, &$total)
{
$is_battery_sales = false;
$total_price = 0;
foreach ($items as $item)
{
$price = $item['price'];
$qty = $item['qty'];
if (isset($item['service_type']))
{
// battery sales is a special case since vat is computed per battery
if ($item['service_type'] == 'battery_new')
{
$is_battery_sales = true;
// battery purchase
if (isset($item['battery']))
{
// battery purchase
$vat = $this->getTaxAmount($price, $tax_rate);
$qty_price = bcmul($price, $qty, 2);
$qty_vat = bcmul($vat, $qty, 2);
$price_minus_vat = bcsub($price, $vat, 2);
$qty_price_minus_vat = bcmul($price_minus_vat, $qty, 2);
$total['vat'] = bcadd($total['vat'], $qty_vat, 2);
$total['vat_ex_price'] = bcadd($total['vat_ex_price'], $qty_price_minus_vat, 2);
}
}
}
}
// compute VAT after adding all item costs, if service type is not battery sales
if (!$is_battery_sales)
{
$total_price = $total['total_price'];
$vat_ex_price = $this->getTaxExclusivePrice($total_price, $tax_rate);
$vat = bcsub($total_price, $vat_ex_price, 2);
$total['vat_ex_price'] = $vat_ex_price;
$total['vat'] = $vat;
}
}
protected function getTaxAmount($price, $tax_rate)
{
$vat_ex_price = $this->getTaxExclusivePrice($price, $tax_rate);
$tax_amount = bcsub($price, $vat_ex_price, 2);
return $tax_amount;
}
protected function getTaxExclusivePrice($price, $tax_rate)
{
$tax_ex_price = bcdiv($price, bcadd(1, $tax_rate, 2), 2);
return $tax_ex_price;
}
}

View file

@ -1,12 +0,0 @@
<?php
namespace App;
interface InvoiceInterface
{
// check if the invoice rule is in the criteria
public function check($criteria);
// display the html partial for the form
public function getTemplate();
}

View file

@ -0,0 +1,119 @@
<?php
namespace App\InvoiceRule;
use App\InvoiceRuleInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Ramcar\ServiceType;
use App\Ramcar\TradeInType;
use App\Entity\Battery;
class BatteryReplacementWarranty implements InvoiceRuleInterface
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function getID()
{
return 'battery_warranty';
}
public function compute($criteria, &$total)
{
$stype = $criteria->getServiceType();
$items = [];
if ($stype == $this->getID())
{
// get the entries
$entries = $criteria->getEntries();
foreach($entries as $entry)
{
$batt = $entry['battery'];
$qty = 1;
$price = $this->getServiceTypeFee();
$items[] = [
'service_type' => $this->getID(),
'battery' => $batt,
'qty' => $qty,
'title' => $this->getTitle($batt),
'price' => $price,
];
$qty_price = bcmul($price, $qty, 2);
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
}
}
return $items;
}
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 0;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
// check service type. Only battery sales and battery warranty should have invoice items
$stype = $criteria->getServiceType();
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY)
return null;
// return error if there's a problem, false otherwise
if (!empty($invoice_items))
{
// check if this is a valid battery
foreach ($invoice_items as $item)
{
$battery = $this->em->getRepository(Battery::class)->find($item['battery']);
if (empty($battery))
{
$error = 'Invalid battery specified.';
return $error;
}
// quantity
$qty = $item['quantity'];
if ($qty < 1)
continue;
// if this is a trade in, add trade in
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
$trade_in = $item['trade_in'];
else
$trade_in = null;
$criteria->addEntry($battery, $trade_in, $qty);
}
}
return null;
}
protected function getTitle($battery)
{
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit';
return $title;
}
}

View file

@ -0,0 +1,122 @@
<?php
namespace App\InvoiceRule;
use Doctrine\ORM\EntityManagerInterface;
use App\InvoiceRuleInterface;
use App\Ramcar\TradeInType;
use App\Ramcar\ServiceType;
use App\Entity\Battery;
class BatterySales implements InvoiceRuleInterface
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function getID()
{
return 'battery_new';
}
public function compute($criteria, &$total)
{
$stype = $criteria->getServiceType();
$items = [];
if ($stype == $this->getID())
{
// get the entries
$entries = $criteria->getEntries();
foreach($entries as $entry)
{
$batt = $entry['battery'];
$qty = $entry['qty'];
$trade_in = null;
if (isset($entry['trade_in']))
$trade_in = $entry['trade_in'];
$size = $batt->getSize();
if ($trade_in == null)
{
// battery purchase
$price = $batt->getSellingPrice();
$items[] = [
'service_type' => $this->getID(),
'battery' => $batt,
'qty' => $qty,
'title' => $this->getTitle($batt),
'price' => $price,
];
$qty_price = bcmul($price, $qty, 2);
$total['sell_price'] = bcadd($total['sell_price'], $qty_price, 2);
$total['total_price'] = bcadd($total['total_price'], $qty_price, 2);
}
}
}
return $items;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
// check service type. Only battery sales and battery warranty should have invoice items
$stype = $criteria->getServiceType();
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY)
return null;
// return error if there's a problem, false otherwise
if (!empty($invoice_items))
{
// check if this is a valid battery
foreach ($invoice_items as $item)
{
$battery = $this->em->getRepository(Battery::class)->find($item['battery']);
if (empty($battery))
{
$error = 'Invalid battery specified.';
return $error;
}
// quantity
$qty = $item['quantity'];
if ($qty < 1)
continue;
// if this is a trade in, add trade in
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
$trade_in = $item['trade_in'];
else
$trade_in = null;
$criteria->addEntry($battery, $trade_in, $qty);
}
}
return null;
}
protected function getTitle($battery)
{
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName();
return $title;
}
}

View file

@ -1,39 +1,40 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use Doctrine\ORM\EntityManagerInterface;
use App\InvoiceRuleInterface;
use App\Ramcar\ServiceType;
use App\Ramcar\DiscountApply; use App\Ramcar\DiscountApply;
class DiscountType implements InvoiceInterface use App\Entity\Promo;
class DiscountType implements InvoiceRuleInterface
{ {
public function check($criteria) protected $em;
public function __construct(EntityManagerInterface $em)
{ {
if (!empty($criteria->getPromos())) $this->em = $em;
return true;
return false;
}
public function getTemplate()
{
return 'invoice/discount_type.html.twig';
} }
public function getID() public function getID()
{ {
return 'discount_type'; return 'discount';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$items = []; $items = [];
$promos = $criteria->getPromos(); $promos = $criteria->getPromos();
// NOTE: only get first promo because only one is applicable anyway if (empty($promos))
return $items;
// NOTE: only get first promo because only one is applicable anyway
$promo = $promos[0]; $promo = $promos[0];
$rate = $promo->getDiscountRate(); $rate = $promo->getDiscountRate();
@ -75,6 +76,36 @@ class DiscountType implements InvoiceInterface
return $items; return $items;
} }
public function validatePromo($criteria, $promo_id)
{
// return error if there's a problem, false otherwise
// check service type
$stype = $criteria->getServiceType();
// discount/promo only applies for battery sales
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW)
return null;
if (empty($promo_id))
{
return false;
}
// check if this is a valid promo
$promo = $this->em->getRepository(Promo::class)->find($promo_id);
if (empty($promo))
return 'Invalid promo specified.';
$criteria->addPromo($promo);
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getTitle() protected function getTitle()
{ {
$title = 'Promo discount'; $title = 'Promo discount';

View file

@ -1,32 +1,20 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
use App\Ramcar\FuelType; use App\Ramcar\FuelType;
use App\Ramcar\ServiceType; use App\Ramcar\ServiceType;
class Fuel implements InvoiceInterface class Fuel implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'fuel'; return 'fuel';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
@ -39,7 +27,7 @@ class Fuel implements InvoiceInterface
if ($cv->hasMotoliteBattery()) if ($cv->hasMotoliteBattery())
$fee = 0; $fee = 0;
else else
$fee = $stype_fees['service_fee']; $fee = $this->getServiceTypeFee();
$ftype = $cv->getFuelType(); $ftype = $cv->getFuelType();
@ -55,14 +43,12 @@ class Fuel implements InvoiceInterface
$qty_fee = bcmul($qty, $fee, 2); $qty_fee = bcmul($qty, $fee, 2);
$total_price = $qty_fee; $total_price = $qty_fee;
$stype_fees_id = $this->getID() . '_fee_' . $ftype;
switch ($ftype) switch ($ftype)
{ {
case FuelType::GAS: case FuelType::GAS:
case FuelType::DIESEL: case FuelType::DIESEL:
$qty = 1; $qty = 1;
$price = $stype_fees[$stype_fees_id]; $price = $this->getFuelFee();
$items[] = [ $items[] = [
'service_type' => $this->getID(), 'service_type' => $this->getID(),
'qty' => $qty, 'qty' => $qty,
@ -96,6 +82,41 @@ class Fuel implements InvoiceInterface
return $items; return $items;
} }
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any changes are to be made, we just edit the file
// instead of the code
return 300;
}
public function getFuelFee($fuel_type)
{
// TODO: we need to to put this somewhere like in .env
// so that if any changes are to be made, we just edit the file
// instead of the code
if ($fuel_type == FuelType::GAS)
{
// gas fuel fee
return 320;
}
else
{
// diesel fuel fee
return 340;
}
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getTitle($fuel_type) protected function getTitle($fuel_type)
{ {
$title = '4L - ' . ucfirst($fuel_type); $title = '4L - ' . ucfirst($fuel_type);

View file

@ -1,29 +1,17 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
class Jumpstart implements InvoiceInterface class Jumpstart implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'jumpstart_troubleshoot'; return 'jumpstart_troubleshoot';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
@ -31,9 +19,7 @@ class Jumpstart implements InvoiceInterface
if ($stype == $this->getID()) if ($stype == $this->getID())
{ {
$stype_fees_id = $this->getID() . '_fee'; $fee = $this->getServiceTypeFee();
$fee = $stype_fees[$stype_fees_id];
// add the service fee to items // add the service fee to items
$qty = 1; $qty = 1;
@ -51,6 +37,24 @@ class Jumpstart implements InvoiceInterface
return $items; return $items;
} }
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 150;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getServiceTitle() protected function getServiceTitle()
{ {
$title = 'Service - Troubleshooting fee'; $title = 'Service - Troubleshooting fee';

View file

@ -1,29 +1,17 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
class JumpstartWarranty implements InvoiceInterface class JumpstartWarranty implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'jumpstart_warranty'; return 'jumpstart_warranty';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
@ -31,9 +19,7 @@ class JumpstartWarranty implements InvoiceInterface
if ($stype == $this->getID()) if ($stype == $this->getID())
{ {
$stype_fees_id = $this->getID() . '_fee'; $fee = $this->getServiceTypeFee();
$fee = $stype_fees[$stype_fees_id];
// add the service fee to items // add the service fee to items
$qty = 1; $qty = 1;
@ -51,6 +37,24 @@ class JumpstartWarranty implements InvoiceInterface
return $items; return $items;
} }
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 0;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getServiceTitle() protected function getServiceTitle()
{ {
$title = 'Service - Troubleshooting fee'; $title = 'Service - Troubleshooting fee';

View file

@ -1,31 +1,19 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
USE App\Ramcar\ServiceType; use App\Ramcar\ServiceType;
class Overheat implements InvoiceInterface class Overheat implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'overheat'; return 'overheat';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
$has_coolant = $criteria->hasCoolant(); $has_coolant = $criteria->hasCoolant();
@ -39,7 +27,7 @@ class Overheat implements InvoiceInterface
if ($cv->hasMotoliteBattery()) if ($cv->hasMotoliteBattery())
$fee = 0; $fee = 0;
else else
$fee = $stype_fees['service_fee']; $fee = $this->getServiceTypeFee();
// add the service fee to items // add the service fee to items
$qty = 1; $qty = 1;
@ -55,7 +43,7 @@ class Overheat implements InvoiceInterface
if ($has_coolant) if ($has_coolant)
{ {
$coolant_fee = $stype_fees['coolant_fee']; $coolant_fee = $this->getCoolantFee();
$items[] = [ $items[] = [
'service_type' => $this->getID(), 'service_type' => $this->getID(),
'qty' => $qty, 'qty' => $qty,
@ -73,6 +61,32 @@ class Overheat implements InvoiceInterface
return $items; return $items;
} }
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 300;
}
public function getCoolantFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 1600;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getServiceTitle() protected function getServiceTitle()
{ {
$title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE); $title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE);

View file

@ -1,29 +1,17 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
class PostRecharged implements InvoiceInterface class PostRecharged implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'post_recharged'; return 'post_recharged';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
@ -31,7 +19,7 @@ class PostRecharged implements InvoiceInterface
if ($stype == $this->getID()) if ($stype == $this->getID())
{ {
$fee = $stype_fees[$this->getID() . '_fee']; $fee = $this->getServiceTypeFee();
$qty = 1; $qty = 1;
$items[] = [ $items[] = [
@ -49,6 +37,24 @@ class PostRecharged implements InvoiceInterface
return $items; return $items;
} }
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 300;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getServiceTitle() protected function getServiceTitle()
{ {
$title = 'Recharge fee'; $title = 'Recharge fee';

View file

@ -1,29 +1,17 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
class PostReplacement implements InvoiceInterface class PostReplacement implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'post_replacement'; return 'post_replacement';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
@ -31,7 +19,7 @@ class PostReplacement implements InvoiceInterface
if ($stype == $this->getID()) if ($stype == $this->getID())
{ {
$fee = $stype_fees['battery_replacement_fee']; $fee = $this->getServiceTypeFee();
$qty = 1; $qty = 1;
$items[] = [ $items[] = [
@ -48,6 +36,24 @@ class PostReplacement implements InvoiceInterface
return $items; return $items;
} }
public function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 0;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getServiceTitle() protected function getServiceTitle()
{ {
$title = 'Battery replacement'; $title = 'Battery replacement';

110
src/InvoiceRule/Tax.php Normal file
View file

@ -0,0 +1,110 @@
<?php
namespace App\InvoiceRule;
use App\InvoiceRuleInterface;
use App\Ramcar\ServiceType;
class Tax implements InvoiceRuleInterface
{
public function getID()
{
return 'tax';
}
public function compute($criteria, &$total)
{
// check if taxable
if (!$criteria->isTaxable())
{
// nothing to compute
return [];
}
$tax_rate = $this->getTaxRate();
$is_battery_sales = false;
$total_price = 0;
// compute tax per item if service type is battery sales
$stype = $criteria->getServiceType();
if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW)
{
// get the entries
$entries = $criteria->getEntries();
foreach($entries as $entry)
{
// check if entry is trade-in
if (isset($entry['trade_in']))
{
// continue to next entry
continue;
}
$battery = $entry['battery'];
$qty = $entry['qty'];
$price = $battery->getSellingPrice();
$vat = $this->getTaxAmount($price, $tax_rate);
$qty_price = bcmul($price, $qty, 2);
$qty_vat = bcmul($vat, $qty, 2);
$price_minus_vat = bcsub($price, $vat, 2);
$qty_price_minus_vat = bcmul($price_minus_vat, $qty, 2);
$total['vat'] = bcadd($total['vat'], $qty_vat, 2);
$total['vat_ex_price'] = bcadd($total['vat_ex_price'], $qty_price_minus_vat, 2);
}
}
else
{
// compute VAT after adding all item costs, if service type is not battery sales
$total_price = $total['total_price'];
$vat_ex_price = $this->getTaxExclusivePrice($total_price, $tax_rate);
$vat = bcsub($total_price, $vat_ex_price, 2);
$total['vat_ex_price'] = $vat_ex_price;
$total['vat'] = $vat;
}
return [];
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getTaxAmount($price, $tax_rate)
{
$vat_ex_price = $this->getTaxExclusivePrice($price, $tax_rate);
$tax_amount = bcsub($price, $vat_ex_price, 2);
return $tax_amount;
}
protected function getTaxExclusivePrice($price, $tax_rate)
{
$tax_ex_price = bcdiv($price, bcadd(1, $tax_rate, 2), 2);
return $tax_ex_price;
}
protected function getTaxRate()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 0.12;
}
}

View file

@ -1,29 +1,17 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
class TireRepair implements InvoiceInterface class TireRepair implements InvoiceRuleInterface
{ {
public function check($criteria)
{
if ($this->getID() == $criteria->getServiceType())
return true;
return false;
}
public function getTemplate()
{
}
public function getID() public function getID()
{ {
return 'tire'; return 'tire';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
@ -36,7 +24,7 @@ class TireRepair implements InvoiceInterface
if ($cv->hasMotoliteBattery()) if ($cv->hasMotoliteBattery())
$fee = 0; $fee = 0;
else else
$fee = $stype_fees['service_fee']; $fee = $this->getServiceTypeFee();
// add the service fee to items // add the service fee to items
$qty = 1; $qty = 1;
@ -54,6 +42,24 @@ class TireRepair implements InvoiceInterface
return $items; return $items;
} }
protected function getServiceTypeFee()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 300;
}
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getServiceTitle() protected function getServiceTitle()
{ {
$title = 'Service - Flat Tire'; $title = 'Service - Flat Tire';

View file

@ -1,41 +1,19 @@
<?php <?php
namespace App\Invoice; namespace App\InvoiceRule;
use App\InvoiceInterface; use App\InvoiceRuleInterface;
use App\Ramcar\TradeInType; use App\Ramcar\TradeInType;
class TradeIn implements InvoiceInterface class TradeIn implements InvoiceRuleInterface
{ {
public function check($criteria)
{
// compare specified type ids with trade in entry of criteria
$entries = $criteria->getEntries();
foreach($entries as $entry)
{
if ($entry['trade_in'])
{
// just need to find one trade-in entry
return true;
}
}
return false;
}
public function getTemplate()
{
return 'invoice/trade_in.html.twig';
}
public function getID() public function getID()
{ {
return 'trade_in'; return 'trade-in';
} }
public function compute($criteria, $stype_fees, &$total) public function compute($criteria, &$total)
{ {
$items = []; $items = [];
@ -72,6 +50,16 @@ class TradeIn implements InvoiceInterface
return $items; return $items;
} }
public function validatePromo($criteria, $promo_id)
{
return false;
}
public function validateInvoiceItems($criteria, $invoice_items)
{
return null;
}
protected function getTradeInRate($battery, $trade_in_type) protected function getTradeInRate($battery, $trade_in_type)
{ {
$size = $battery->getSize(); $size = $battery->getSize();

View file

@ -0,0 +1,15 @@
<?php
namespace App;
interface InvoiceRuleInterface
{
// validate promo
public function validatePromo($criteria, $promo_id);
// validate invoice items
public function validateInvoiceItems($criteria, $invoice_items);
// compute
public function compute($criteria, &$total);
}

View file

@ -7,7 +7,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use App\Invoice; use App\InvoiceRule;
use App\Service\InvoiceGeneratorInterface; use App\Service\InvoiceGeneratorInterface;
@ -16,7 +16,7 @@ use App\Ramcar\InvoiceStatus;
use App\Ramcar\ServiceType; use App\Ramcar\ServiceType;
use App\Ramcar\TradeInType; use App\Ramcar\TradeInType;
use App\Entity\Invoice as Inv; use App\Entity\Invoice;
use App\Entity\InvoiceItem; use App\Entity\InvoiceItem;
use App\Entity\User; use App\Entity\User;
use App\Entity\Battery; use App\Entity\Battery;
@ -42,49 +42,21 @@ class InvoiceManager implements InvoiceGeneratorInterface
{ {
// TODO: get list of invoice rules from .env or a json file? // TODO: get list of invoice rules from .env or a json file?
return [ return [
new Invoice\ServiceType(), new InvoiceRule\BatterySales($this->em),
new Invoice\BatterySales(), new InvoiceRule\BatteryReplacementWarranty($this->em),
new Invoice\BatteryReplacementWarranty(), new InvoiceRule\Jumpstart(),
new Invoice\Jumpstart(), new InvoiceRule\JumpstartWarranty(),
new Invoice\JumpstartWarranty(), new InvoiceRule\PostRecharged(),
new Invoice\PostRecharged(), new InvoiceRule\PostReplacement(),
new Invoice\PostReplacement(), new InvoiceRule\Overheat(),
new Invoice\Overheat(), new InvoiceRule\Fuel(),
new Invoice\Fuel(), new InvoiceRule\TireRepair(),
new Invoice\TireRepair(), new InvoiceRule\DiscountType($this->em),
new Invoice\DiscountType(), new InvoiceRule\TradeIn(),
new Invoice\TradeIn(), new InvoiceRule\Tax(),
new Invoice\Tax(),
]; ];
} }
public function getServiceTypeFees()
{
// TODO: we need to put this somewhere like a json file, so
// if any changes are to be made to fees, we just edit the file
// instead of the code
return [
'service_fee' => 300,
'coolant_fee' => 1600,
'post_recharged_fee' => 300,
'jumpstart_troubleshoot_fee' => 150,
'jumpstart_warranty_fee' => 0,
'battery_replacement_fee' => 0,
'battery_warranty_fee' => 0,
'other_services_fee' => 200,
'fuel_fee_gas' => 320,
'fuel_fee_diesel' => 340,
];
}
public function getTaxRate()
{
// TODO: we need to to put this somewhere like in .env
// so that if any chanages are to be made, we just edit the file
// instead of the code
return 0.12;
}
// this is called when JO is submitted // this is called when JO is submitted
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array) public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array)
{ {
@ -98,12 +70,26 @@ class InvoiceManager implements InvoiceGeneratorInterface
// would mean adding it as a parameter to the call, impacting all calls // would mean adding it as a parameter to the call, impacting all calls
$criteria->setIsTaxable(); $criteria->setIsTaxable();
$ierror = $this->validatePromo($criteria, $promo_id); foreach ($this->available_rules as $avail_rule)
{
$ierror = $avail_rule->validatePromo($criteria, $promo_id);
// break out of loop when error found
if ($ierror)
break;
}
if (!$ierror && !empty($invoice_items)) if (!$ierror && !empty($invoice_items))
{ {
// validate the invoice items (batteries and trade ins) // validate the invoice items (batteries and trade ins)
$ierror = $this->validateInvoiceItems($criteria, $invoice_items); foreach ($this->available_rules as $avail_rule)
{
$ierror = $avail_rule->validateInvoiceItems($criteria, $invoice_items);
// break out of loop when error found
if ($ierror)
break;
}
} }
if ($ierror) if ($ierror)
@ -142,12 +128,26 @@ class InvoiceManager implements InvoiceGeneratorInterface
// this is called by JobOrderController when JS script generateInvoice is called // this is called by JobOrderController when JS script generateInvoice is called
public function generateDraftInvoice($criteria, $promo_id, $service_charges, $items) public function generateDraftInvoice($criteria, $promo_id, $service_charges, $items)
{ {
$ierror = $this->validatePromo($criteria, $promo_id); foreach ($this->available_rules as $avail_rule)
{
$ierror = $avail_rule->validatePromo($criteria, $promo_id);
// break out of loop when error found
if ($ierror)
break;
}
if (!$ierror && !empty($items)) if (!$ierror && !empty($items))
{ {
// validate the invoice items (batteries and trade ins) // validate the invoice items (batteries and trade ins)
$ierror = $this->validateInvoiceItems($criteria, $items); foreach ($this->available_rules as $avail_rule)
{
$ierror = $avail_rule->validateInvoiceItems($criteria, $items);
// break out of loop when error found
if ($ierror)
break;
}
} }
return $ierror; return $ierror;
@ -163,31 +163,14 @@ class InvoiceManager implements InvoiceGeneratorInterface
{ {
// no need to validate since generateDraftInvoice was called before this was called // no need to validate since generateDraftInvoice was called before this was called
// generate the invoice and from APIController, the fields were validated // generate the invoice and from APIController, the fields were validated
// check which rules to apply $invoice_data = $this->compute($criteria);
$rules = $this->check($criteria);
$invoice_data = $this->compute($criteria, $rules);
$invoice = $this->createInvoice($invoice_data); $invoice = $this->createInvoice($invoice_data);
return $invoice; return $invoice;
} }
// check what rules to use given the criteria public function compute($criteria)
public function check($criteria)
{
$active_rules = [];
foreach ($this->available_rules as $rule)
{
$is_active = $rule->check($criteria);
if ($is_active)
$active_rules[$rule->getID()] = $rule;
}
return $active_rules;
}
public function compute($criteria, $active_rules)
{ {
// initialize // initialize
$total = [ $total = [
@ -205,9 +188,6 @@ class InvoiceManager implements InvoiceGeneratorInterface
$promos = $criteria->getPromos(); $promos = $criteria->getPromos();
$is_taxable = $criteria->isTaxable(); $is_taxable = $criteria->isTaxable();
// get the service type fees
$stype_fees = $this->getServiceTypeFees();
$flag_trade_in = false; $flag_trade_in = false;
foreach ($entries as $entry) foreach ($entries as $entry)
{ {
@ -219,164 +199,48 @@ class InvoiceManager implements InvoiceGeneratorInterface
$invoice_items = []; $invoice_items = [];
$data = []; $data = [];
foreach ($active_rules as $id => $active_rule) foreach ($this->available_rules as $rule)
{ {
// each criteria can only have one service type $items = $rule->compute($criteria, $total);
// find the rule for the service type
if ($id == $stype) $promo = null;
foreach ($items as $item)
{ {
$items = []; $title = $item['title'];
$quantity = $item['qty'];
$price = $item['price'];
$computed_items = $active_rule->compute($criteria, $stype_fees, $total); $battery = null;
foreach ($computed_items as $computed_item) if (isset($item['battery']))
{ $battery = $item['battery'];
if (!empty($computed_item))
{
$items[] = $computed_item;
}
}
// check if tax is needed
if ($is_taxable)
{
$tax_rate = $this->getTaxRate();
if (isset($active_rules['tax']))
{
$active_rules['tax']->compute($tax_rate, $items, $total);
}
}
// process trade-ins by calling the trade-in rule if there are trade-ins among the entries
if ($flag_trade_in)
{
if (isset($active_rules['trade_in']))
{
$tradein_items = $active_rules['trade_in']->compute($criteria, $stype_fees, $total);
foreach ($tradein_items as $tradein_item)
{
$items[] = $tradein_item;
}
}
}
// process promos, if any
if (count($promos) > 0)
{
if (isset($active_rules['discount_type']))
{
$discount_items = $active_rules['discount_type']->compute($criteria, $stype_fees, $total);
foreach ($discount_items as $discount_item)
{
$items[] = $discount_item;
}
}
}
$promo = null; $promo = null;
foreach ($items as $item) if (isset($item['promo']))
{ $promo = $item['promo'];
$title = $item['title'];
$quantity = $item['qty'];
$price = $item['price'];
$battery = null; $invoice_items[] = [
if (isset($item['battery'])) 'title' => $title,
$battery = $item['battery']; 'quantity' => $quantity,
'price' => $price,
$promo = null; 'battery' => $battery,
if (isset($item['promo']))
$promo = $item['promo'];
$invoice_items[] = [
'title' => $title,
'quantity' => $quantity,
'price' => $price,
'battery' => $battery,
'promo' => $promo,
];
}
// also need to return the total and the promo
$data[] = [
'promo' => $promo, 'promo' => $promo,
'invoice_items' => $invoice_items,
'total' => $total,
]; ];
} }
// also need to return the total and the promo
$data[] = [
'promo' => $promo,
'invoice_items' => $invoice_items,
'total' => $total,
];
} }
return $data; return $data;
} }
protected function validatePromo($criteria, $promo_id)
{
// return error if there's a problem, false otherwise
// check service type
$stype = $criteria->getServiceType();
// discount/promo only applies for battery sales
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW)
return null;
if (empty($promo_id))
{
return false;
}
// check if this is a valid promo
$promo = $this->em->getRepository(Promo::class)->find($promo_id);
if (empty($promo))
return 'Invalid promo specified.';
$criteria->addPromo($promo);
return false;
}
protected function validateInvoiceItems($criteria, $invoice_items)
{
// check service type. Only battery sales and battery warranty should have invoice items
$stype = $criteria->getServiceType();
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY)
return null;
// return error if there's a problem, false otherwise
if (!empty($invoice_items))
{
// check if this is a valid battery
foreach ($invoice_items as $item)
{
$battery = $this->em->getRepository(Battery::class)->find($item['battery']);
if (empty($battery))
{
$error = 'Invalid battery specified.';
return $error;
}
// quantity
$qty = $item['quantity'];
if ($qty < 1)
continue;
// if this is a trade in, add trade in
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
$trade_in = $item['trade_in'];
else
$trade_in = null;
$criteria->addEntry($battery, $trade_in, $qty);
}
}
return null;
}
protected function createInvoice($invoice_data) protected function createInvoice($invoice_data)
{ {
$invoice = new Inv(); $invoice = new Invoice();
// get current user // get current user
$user = $this->security->getUser(); $user = $this->security->getUser();