From a986d7835ba6826ad60974c0407d1d7d65213ca4 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 2 Jun 2023 05:50:39 -0400 Subject: [PATCH] Add function to let the JO service call the new invoice manager. #744 --- src/Service/InvoiceManager.php | 152 ++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 4 deletions(-) diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 1a17fe7d..0990db76 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -11,26 +11,33 @@ use App\Invoice; use App\Ramcar\InvoiceCriteria; use App\Ramcar\InvoiceStatus; +use App\Ramcar\ServiceType; +use App\Ramcar\TradeInType; use App\Entity\InvoiceItem; use App\Entity\User; use App\Entity\Battery; +use App\Entity\Promo; class InvoiceManager { + private $security; protected $em; + protected $validator; protected $available_rules; - public function __construct(EntityManagerInterface $em) + public function __construct(EntityManagerInterface $em, Security $security, ValidatorInterface $validator) { $this->em = $em; + $this->security = $security; + $this->validator = $validator; $this->available_rules = $this->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 [ new Invoice\ServiceType(), new Invoice\BatterySales(), @@ -50,6 +57,9 @@ class InvoiceManager 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, @@ -66,9 +76,46 @@ class InvoiceManager 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; } + 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 public function check($criteria) { @@ -81,7 +128,6 @@ class InvoiceManager } return $active_rules; - } public function compute($criteria, $active_rules) @@ -194,11 +240,109 @@ class InvoiceManager 'invoice_items' => $invoice_items, 'total' => $total, ]; - } } 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; + } + }