Add function to let the JO service call the new invoice manager. #744

This commit is contained in:
Korina Cordero 2023-06-02 05:50:39 -04:00
parent 77c2763f53
commit a986d7835b

View file

@ -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;
}
} }