195 lines
5.4 KiB
PHP
195 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Service;
|
|
|
|
use Symfony\Component\Security\Core\Security;
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
|
|
use App\Invoice;
|
|
|
|
use App\Ramcar\InvoiceCriteria;
|
|
use App\Ramcar\InvoiceStatus;
|
|
|
|
use App\Entity\InvoiceItem;
|
|
use App\Entity\User;
|
|
use App\Entity\Battery;
|
|
|
|
class InvoiceManager
|
|
{
|
|
protected $em;
|
|
protected $available_rules;
|
|
|
|
public function __construct(EntityManagerInterface $em)
|
|
{
|
|
$this->em = $em;
|
|
|
|
$this->available_rules = $this->getAvailableRules();
|
|
}
|
|
|
|
public function getAvailableRules()
|
|
{
|
|
// TODO: get list of invoice rules from .env
|
|
return [
|
|
new Invoice\ServiceType(),
|
|
new Invoice\BatterySales(),
|
|
new Invoice\BatteryReplacementWarranty(),
|
|
new Invoice\Jumpstart(),
|
|
new Invoice\JumpstartWarranty(),
|
|
new Invoice\PostRecharged(),
|
|
new Invoice\PostReplacement(),
|
|
new Invoice\Overheat(),
|
|
new Invoice\Fuel(),
|
|
new Invoice\TireRepair(),
|
|
new Invoice\DiscountType(),
|
|
new Invoice\TradeIn(),
|
|
new Invoice\Tax,
|
|
];
|
|
}
|
|
|
|
public function getServiceTypeFees()
|
|
{
|
|
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' => 320,
|
|
];
|
|
}
|
|
|
|
public function getTaxRate()
|
|
{
|
|
return 0.12;
|
|
}
|
|
|
|
// check what rules to use given the 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
|
|
$total = [
|
|
'sell_price' => 0.0,
|
|
'vat' => 0.0,
|
|
'vat_ex_price' => 0.0,
|
|
'ti_rate' => 0.0,
|
|
'total_price' => 0.0,
|
|
'discount' => 0.0,
|
|
];
|
|
|
|
// get what is in criteria
|
|
$stype = $criteria->getServiceType();
|
|
$entries = $criteria->getEntries();
|
|
$promos = $criteria->getPromos();
|
|
$is_taxable = $criteria->isTaxable();
|
|
|
|
// get the service type fees
|
|
$stype_fees = $this->getServiceTypeFees();
|
|
|
|
$flag_trade_in = false;
|
|
foreach ($entries as $entry)
|
|
{
|
|
if ($entry['trade_in'] != null)
|
|
{
|
|
$flag_trade_in = true;
|
|
}
|
|
}
|
|
|
|
$invoice_items = [];
|
|
$data = [];
|
|
foreach ($active_rules as $id => $active_rule)
|
|
{
|
|
// each criteria can only have one service type
|
|
// find the rule for the service type
|
|
if ($id == $stype)
|
|
{
|
|
$items = [];
|
|
|
|
$computed_items = $active_rule->compute($criteria, $stype_fees);
|
|
foreach ($computed_items as $computed_item)
|
|
{
|
|
if (!empty($computed_item))
|
|
{
|
|
$items[] = $computed_item;
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
foreach ($items as $item)
|
|
{
|
|
$invoice_item = new InvoiceItem();
|
|
|
|
$invoice_item->setTitle($item['title'])
|
|
->setQuantity($item['qty'])
|
|
->setPrice($item['price']);
|
|
|
|
if (isset($item['battery']))
|
|
$invoice_item->setBattery($item['battery']);
|
|
|
|
$invoice_items[] = $invoice_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);
|
|
}
|
|
}
|
|
|
|
// also need to return the total
|
|
$data[] = [
|
|
'invoice_items' => $invoice_items,
|
|
'total' => $total,
|
|
];
|
|
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
}
|