Add function to let the JO service call the new invoice manager. #744
This commit is contained in:
parent
77c2763f53
commit
a986d7835b
1 changed files with 148 additions and 4 deletions
|
|
@ -11,26 +11,33 @@ use App\Invoice;
|
||||||
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
use App\Ramcar\InvoiceStatus;
|
use App\Ramcar\InvoiceStatus;
|
||||||
|
use App\Ramcar\ServiceType;
|
||||||
|
use App\Ramcar\TradeInType;
|
||||||
|
|
||||||
use App\Entity\InvoiceItem;
|
use App\Entity\InvoiceItem;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
|
use App\Entity\Promo;
|
||||||
|
|
||||||
class InvoiceManager
|
class InvoiceManager
|
||||||
{
|
{
|
||||||
|
private $security;
|
||||||
protected $em;
|
protected $em;
|
||||||
|
protected $validator;
|
||||||
protected $available_rules;
|
protected $available_rules;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em)
|
public function __construct(EntityManagerInterface $em, Security $security, ValidatorInterface $validator)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
|
$this->security = $security;
|
||||||
|
$this->validator = $validator;
|
||||||
|
|
||||||
$this->available_rules = $this->getAvailableRules();
|
$this->available_rules = $this->getAvailableRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAvailableRules()
|
public function getAvailableRules()
|
||||||
{
|
{
|
||||||
// TODO: get list of invoice rules from .env
|
// TODO: get list of invoice rules from .env or a json file?
|
||||||
return [
|
return [
|
||||||
new Invoice\ServiceType(),
|
new Invoice\ServiceType(),
|
||||||
new Invoice\BatterySales(),
|
new Invoice\BatterySales(),
|
||||||
|
|
@ -50,6 +57,9 @@ class InvoiceManager
|
||||||
|
|
||||||
public function getServiceTypeFees()
|
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 [
|
return [
|
||||||
'service_fee' => 300,
|
'service_fee' => 300,
|
||||||
'coolant_fee' => 1600,
|
'coolant_fee' => 1600,
|
||||||
|
|
@ -66,9 +76,46 @@ class InvoiceManager
|
||||||
|
|
||||||
public function getTaxRate()
|
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;
|
return 0.12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array)
|
||||||
|
{
|
||||||
|
// instantiate the invoice criteria
|
||||||
|
$criteria = new InvoiceCriteria();
|
||||||
|
$criteria->setServiceType($jo->getServiceType())
|
||||||
|
->setCustomerVehicle($jo->getCustomerVehicle());
|
||||||
|
|
||||||
|
// set if taxable
|
||||||
|
$criteria->setIsTaxable();
|
||||||
|
|
||||||
|
$ierror = $this->validatePromo($criteria, $promo_id);
|
||||||
|
|
||||||
|
if (!$ierror && !empty($invoice_items))
|
||||||
|
{
|
||||||
|
// validate the invoice items (batteries and trade ins)
|
||||||
|
$ierror = $this->validateInvoiceItems($criteria, $invoice_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ierror)
|
||||||
|
{
|
||||||
|
$error_array['invoice'] = $ierror;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// generate the invoice
|
||||||
|
// check which rules to apply
|
||||||
|
$rules = $this->check($criteria);
|
||||||
|
|
||||||
|
$invoice_data = $this->compute($criteria, $rules);
|
||||||
|
|
||||||
|
$invoice = $createInvoice($invoice_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check what rules to use given the criteria
|
// check what rules to use given the criteria
|
||||||
public function check($criteria)
|
public function check($criteria)
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +128,6 @@ class InvoiceManager
|
||||||
}
|
}
|
||||||
|
|
||||||
return $active_rules;
|
return $active_rules;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function compute($criteria, $active_rules)
|
public function compute($criteria, $active_rules)
|
||||||
|
|
@ -194,11 +240,109 @@ class InvoiceManager
|
||||||
'invoice_items' => $invoice_items,
|
'invoice_items' => $invoice_items,
|
||||||
'total' => $total,
|
'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($items))
|
||||||
|
{
|
||||||
|
// check if this is a valid battery
|
||||||
|
foreach ($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)
|
||||||
|
{
|
||||||
|
$invoice = new Invoice();
|
||||||
|
|
||||||
|
// get current user
|
||||||
|
$user = $this->security->getUser();
|
||||||
|
// check if user is User or APIUser
|
||||||
|
if ($user instanceof User)
|
||||||
|
{
|
||||||
|
$invoice->setCreatedBy($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($invoice_data as $data)
|
||||||
|
{
|
||||||
|
$invoice_items = $data['invoice_items'];
|
||||||
|
$total = $data['total'];
|
||||||
|
|
||||||
|
// check if promo is set
|
||||||
|
if (isset($data['promo']))
|
||||||
|
$promo = $data['promo'];
|
||||||
|
|
||||||
|
$invoice->addItem($invoice_item);
|
||||||
|
|
||||||
|
$invoice->setTotalPrice($total['total_price'])
|
||||||
|
->setVATExclusivePrice($total['vat_ex_price'])
|
||||||
|
->setVAT($total['vat'])
|
||||||
|
->setDiscount($total['discount'])
|
||||||
|
->setTradeIn($total['ti_rate'])
|
||||||
|
->setStatus(InvoiceStatus::DRAFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invoice;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue