From 1c02138f52766b417a03ee1c22bd3226258b8115 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 22 May 2023 06:06:12 -0400 Subject: [PATCH 01/25] Add services for the new invoice generator. #744 --- src/Ramcar/InvoiceCriteria.php | 13 +++ src/Service/InvoiceBatteryManager.php | 40 +++++++ src/Service/InvoiceManager.php | 159 ++++++++++++++++++++++++++ src/Service/InvoiceTaxManager.php | 29 +++++ src/Service/InvoiceTradeInManager.php | 53 +++++++++ 5 files changed, 294 insertions(+) create mode 100644 src/Service/InvoiceBatteryManager.php create mode 100644 src/Service/InvoiceManager.php create mode 100644 src/Service/InvoiceTaxManager.php create mode 100644 src/Service/InvoiceTradeInManager.php diff --git a/src/Ramcar/InvoiceCriteria.php b/src/Ramcar/InvoiceCriteria.php index 6665226d..886d6024 100644 --- a/src/Ramcar/InvoiceCriteria.php +++ b/src/Ramcar/InvoiceCriteria.php @@ -15,6 +15,7 @@ class InvoiceCriteria protected $flag_coolant; protected $discount; protected $service_charges; + protected $flag_taxable; // entries are battery and trade-in combos protected $entries; @@ -28,6 +29,7 @@ class InvoiceCriteria $this->flag_coolant = false; $this->discount = 0; $this->service_charges = []; + $this->flag_taxable = false; } public function setServiceType($stype) @@ -153,4 +155,15 @@ class InvoiceCriteria return $this->service_charges; } + public function setIsTaxable($flag = true) + { + $this->flag_taxable = $flag; + return $this; + } + + public function isTaxable() + { + return $this->flag_taxable; + } + } diff --git a/src/Service/InvoiceBatteryManager.php b/src/Service/InvoiceBatteryManager.php new file mode 100644 index 00000000..c9af27e5 --- /dev/null +++ b/src/Service/InvoiceBatteryManager.php @@ -0,0 +1,40 @@ +getSellingPrice(); + + $computed_price = bcmul($sell_price, $qty, 2); + $invoice_batteries = [ + 'title' => $battery->getModel()->getName() . ' ' . $battery->getSize()->getName(), + 'battery' => $battery, + 'qty' => $qty, + 'sell_price' => $computed_price, + 'vat' => 0.0, + 'vat_ex_price' => 0.0, + ]; + + $total['sell_price'] = bcadd($total['sell_price'], $computed_price, 2); + $total['vat'] += 0.00; + $total['vat_ex_price'] += 0.00; + + $total['total_price'] = bcadd($total['total_price'], $computed_price, 2); + } + + return $invoice_batteries; + } +} diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php new file mode 100644 index 00000000..ddb108e2 --- /dev/null +++ b/src/Service/InvoiceManager.php @@ -0,0 +1,159 @@ +security = $security; + $this->em = $em; + $this->validator = $validator; + $this->inv_batt = $inv_batt; + $this->inv_trade = $inv_trade; + $this->inv_tax = $inv_tax; + } + + public function generateInvoice(InvoiceCriteria $criteria) + { + // initialize + $invoice = new Invoice(); + $total = [ + 'sell_price' => 0.0, + 'vat' => 0.0, + 'vat_ex_price' => 0.0, + 'ti_rate' => 0.0, + 'total_price' => 0.0, + 'discount' => 0.0, + ]; + + $stype = $criteria->getServiceType(); + $cv = $criteria->getCustomerVehicle(); + $has_coolant = $criteria->hasCoolant(); + + switch($stype) + { + case ServiceType::JUMPSTART_TROUBLESHOOT: + $this->processJumpstart($total, $invoice); + break; + case ServiceType::JUMPSTART_WARRANTY: + $this->processJumpstartWarranty($total, $invoice); + break; + case ServiceType::BATTERY_REPLACEMENT_NEW: + $this->processEntries($total, $criteria, $invoice); + $this->processDiscount($total, $criteria, $invoice, $cust_tag_info); + break; + case ServiceType::BATTERY_REPLACEMENT_WARRANTY: + $this->processWarranty($total, $criteria, $invoice); + break; + case ServiceType::POST_RECHARGED: + $this->processRecharge($total, $invoice); + break; + case ServiceType::POST_REPLACEMENT: + $this->processReplacement($total, $invoice); + break; + case ServiceType::TIRE_REPAIR: + $this->processTireRepair($total, $invoice, $cv); + break; + case ServiceType::OVERHEAT_ASSISTANCE: + $this->processOverheat($total, $invoice, $cv, $has_coolant); + break; + case ServiceType::EMERGENCY_REFUEL: + $ftype = $criteria->getCustomerVehicle()->getFuelType(); + $this->processRefuel($total, $invoice, $cv); + break; + } + + // process promos here? + + // get current user + $user = $this->security->getUser(); + // check if user is User or APIUser + if ($user instanceof User) + { + $invoice->setCreatedBy($user); + } + + $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; + } + + // process battery sales and trade-ins + protected function processEntries(&$total, InvoiceCriteria $criteria, Invoice $invoice) + { + $entries = $criteria->getEntries(); + + $con_batts = []; + $con_tis = []; + foreach($entries as $entry) + { + // batteries purchased should have trade_in set to null + $batt = $entry['battery']; + $qty = $entry['qty']; + $trade_in = $entry['trade_in']; + $size = $batt->getSize(); + + // consolidate batteries + $batt_id = $batt->getID(); + if (!isset($con_batts[$batt_id])) + $con_batts[$batt->getID()] = [ + 'batt' => $batt, + 'qty' => 0 + ]; + $con_batts[$batt_id]['qty']++; + + // no trade-in + if ($trade_in == null) + continue; + + // consolidate trade-ins + // need to set battery for trade in so we know what battery is for trade in + // possible that battery purchased is not the same battery for trade in + $ti_key = $size->getID() . '|' . $trade_in; + if (!isset($con_tis[$ti_key])) + $con_tis[$ti_key] = [ + 'batt' => $batt, + 'size' => $size, + 'trade_in' => $trade_in, + 'qty' => 0 + ]; + $con_tis[$ti_key]['qty']++; + } + + $inv_batt_entries = $this->inv_batt->processBatteries($con_batts, $total); + $inv_trade_in_entries = $this->inv_trade->processTradeIns($con_tis, $total); + + // check if we need to compute tax + if ($criteria->isTaxable()) + { + $this->inv_tax->computeTax($inv_batt_entries, $total); + } + } +} diff --git a/src/Service/InvoiceTaxManager.php b/src/Service/InvoiceTaxManager.php new file mode 100644 index 00000000..1535c68e --- /dev/null +++ b/src/Service/InvoiceTaxManager.php @@ -0,0 +1,29 @@ +getTaxAmount($sell_price); + $vat_ex_price = $this->getTaxExclusivePrice($sell_price); + + // TODO: add to the total array the computed vat prices + } + } + + // TODO: use bc functions for these + protected function getTaxAmount($price) + { + $vat_ex_price = $this->getTaxExclusivePrice($price); + return $price - $vat_ex_price; + } + + protected function getTaxExclusivePrice($price) + { + return round($price / (1 + self::TAX_RATE), 2); + } +} diff --git a/src/Service/InvoiceTradeInManager.php b/src/Service/InvoiceTradeInManager.php new file mode 100644 index 00000000..e0e04308 --- /dev/null +++ b/src/Service/InvoiceTradeInManager.php @@ -0,0 +1,53 @@ +getTradeInRate($ti); + + $ti_price = bcmul($ti_rate, -1, 2); + $invoice_trade_ins = [ + 'title' => 'Trade-in ' . TradeInType::getName($ti['trade_in']) . ' ' . $ti['size']->getName() . ' battery'), + 'qty' => $qty, + 'price' => $ti_price, + ]; + + $tti_price = bcmul($ti_rate, $qty, 2); + + $total['ti_rate'] = bcadd($total['ti_rate'], $tti_price, 2); + $total['total_price'] = bcsub($total['total_price'], $tti_price, 2); + } + + return $invoice_trade_ins; + } + + protected function getTradeInRate($ti) + { + $size = $ti['size']; + $trade_in = $ti['trade_in']; + + if ($trade_in == null) + return 0; + + switch ($trade_in) + { + case TradeInType::MOTOLITE: + return $size->getTIPriceMotolite(); + case TradeInType::PREMIUM: + return $size->getTIPricePremium(); + case TradeInType::OTHER: + return $size->getTIPriceOther(); + } + + return 0; + } +} From 0bb32f47b5f0a7c0109e4ef2fdaf17c7022a488f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 23 May 2023 07:52:14 -0400 Subject: [PATCH 02/25] Modify invoice engine. #744 --- src/Invoice/ServiceType.php | 26 ++++ src/InvoiceCriteria.php | 169 ++++++++++++++++++++++++++ src/InvoiceInterface.php | 12 ++ src/Service/InvoiceBatteryManager.php | 40 ------ src/Service/InvoiceManager.php | 141 +-------------------- src/Service/InvoiceTaxManager.php | 29 ----- src/Service/InvoiceTradeInManager.php | 53 -------- 7 files changed, 209 insertions(+), 261 deletions(-) create mode 100644 src/Invoice/ServiceType.php create mode 100644 src/InvoiceCriteria.php create mode 100644 src/InvoiceInterface.php delete mode 100644 src/Service/InvoiceBatteryManager.php delete mode 100644 src/Service/InvoiceTaxManager.php delete mode 100644 src/Service/InvoiceTradeInManager.php diff --git a/src/Invoice/ServiceType.php b/src/Invoice/ServiceType.php new file mode 100644 index 00000000..e27f2bc6 --- /dev/null +++ b/src/Invoice/ServiceType.php @@ -0,0 +1,26 @@ +getServiceType()) + return true; + } + + return false; + } + + public function getTemplate() + { + return 'invoice/service_type.html.twig'; + } +} diff --git a/src/InvoiceCriteria.php b/src/InvoiceCriteria.php new file mode 100644 index 00000000..886d6024 --- /dev/null +++ b/src/InvoiceCriteria.php @@ -0,0 +1,169 @@ +stype = 0; + $this->promos = []; + $this->entries = []; + $this->cv = null; + $this->flag_coolant = false; + $this->discount = 0; + $this->service_charges = []; + $this->flag_taxable = false; + } + + public function setServiceType($stype) + { + // TODO: validate service type + $this->stype = $stype; + return $this; + } + + public function getServiceType() + { + return $this->stype; + } + + /* + public function addBattery(Battery $battery, $qty = 1) + { + for ($i = 0; $i < $qty; $i++) + $this->batteries[] = $battery; + return $this; + } + + public function getBatteries() + { + return $this->batteries; + } + */ + + public function addPromo(Promo $promo) + { + $this->promos[] = $promo; + return $this; + } + + public function getPromos() + { + return $this->promos; + } + + /* + public function addTradeIn($is_motolite, $qty = 1) + { + // NOTE: this asumes that all the rates for trade-ins are standardized + // for motolite and non-motolite trade-ins + + for ($i = 0; $i < $qty; $i++) + { + if ($is_motolite) + $trade_in = 'motolite'; + else + $trade_in = 'other'; + + $this->trade_ins[] = $trade_in; + } + return $this; + } + + public function getTradeIns() + { + return $this->trade_ins; + } + */ + + public function addEntry($battery, $trade_in, $qty) + { + // trade_in is null if no trade_in specified + + $entry = [ + 'battery' => $battery, + 'trade_in' => $trade_in, + 'qty' => $qty + ]; + + $this->entries[] = $entry; + } + + public function getEntries() + { + return $this->entries; + } + + public function setCustomerVehicle(CustomerVehicle $cv = null) + { + $this->cv = $cv; + return $this; + } + + public function getCustomerVehicle() + { + return $this->cv; + } + + public function setHasCoolant($flag = true) + { + $this->flag_coolant = $flag; + return $this; + } + + public function hasCoolant() + { + return $this->flag_coolant; + } + + public function setDiscount($discount) + { + $this->discount = $discount; + return $this; + } + + public function getDiscount() + { + return $this->discount; + } + + public function addServiceCharge(ServiceCharge $service_charge) + { + $this->service_charges[] = $service_charge; + return $this; + } + + public function getServiceCharges() + { + return $this->service_charges; + } + + public function setIsTaxable($flag = true) + { + $this->flag_taxable = $flag; + return $this; + } + + public function isTaxable() + { + return $this->flag_taxable; + } + +} diff --git a/src/InvoiceInterface.php b/src/InvoiceInterface.php new file mode 100644 index 00000000..704e4e46 --- /dev/null +++ b/src/InvoiceInterface.php @@ -0,0 +1,12 @@ +getSellingPrice(); - - $computed_price = bcmul($sell_price, $qty, 2); - $invoice_batteries = [ - 'title' => $battery->getModel()->getName() . ' ' . $battery->getSize()->getName(), - 'battery' => $battery, - 'qty' => $qty, - 'sell_price' => $computed_price, - 'vat' => 0.0, - 'vat_ex_price' => 0.0, - ]; - - $total['sell_price'] = bcadd($total['sell_price'], $computed_price, 2); - $total['vat'] += 0.00; - $total['vat_ex_price'] += 0.00; - - $total['total_price'] = bcadd($total['total_price'], $computed_price, 2); - } - - return $invoice_batteries; - } -} diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index ddb108e2..8d608e89 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -17,143 +17,6 @@ use App\Entity\Battery; class InvoiceManager { - protected $security; - protected $em; - protected $validator; - protected $inv_batt; - protected $inv_trade; - protected $inv_tax; - - public function __construct(Security $service, EntityManagerInterface $em, ValidatorInterface $validator, - InvoiceBatteryManager $inv_batt, InvoiceTradeInManager $inv_trade, InvoiceTaxManager $inv_tax) - { - $this->security = $security; - $this->em = $em; - $this->validator = $validator; - $this->inv_batt = $inv_batt; - $this->inv_trade = $inv_trade; - $this->inv_tax = $inv_tax; - } - - public function generateInvoice(InvoiceCriteria $criteria) - { - // initialize - $invoice = new Invoice(); - $total = [ - 'sell_price' => 0.0, - 'vat' => 0.0, - 'vat_ex_price' => 0.0, - 'ti_rate' => 0.0, - 'total_price' => 0.0, - 'discount' => 0.0, - ]; - - $stype = $criteria->getServiceType(); - $cv = $criteria->getCustomerVehicle(); - $has_coolant = $criteria->hasCoolant(); - - switch($stype) - { - case ServiceType::JUMPSTART_TROUBLESHOOT: - $this->processJumpstart($total, $invoice); - break; - case ServiceType::JUMPSTART_WARRANTY: - $this->processJumpstartWarranty($total, $invoice); - break; - case ServiceType::BATTERY_REPLACEMENT_NEW: - $this->processEntries($total, $criteria, $invoice); - $this->processDiscount($total, $criteria, $invoice, $cust_tag_info); - break; - case ServiceType::BATTERY_REPLACEMENT_WARRANTY: - $this->processWarranty($total, $criteria, $invoice); - break; - case ServiceType::POST_RECHARGED: - $this->processRecharge($total, $invoice); - break; - case ServiceType::POST_REPLACEMENT: - $this->processReplacement($total, $invoice); - break; - case ServiceType::TIRE_REPAIR: - $this->processTireRepair($total, $invoice, $cv); - break; - case ServiceType::OVERHEAT_ASSISTANCE: - $this->processOverheat($total, $invoice, $cv, $has_coolant); - break; - case ServiceType::EMERGENCY_REFUEL: - $ftype = $criteria->getCustomerVehicle()->getFuelType(); - $this->processRefuel($total, $invoice, $cv); - break; - } - - // process promos here? - - // get current user - $user = $this->security->getUser(); - // check if user is User or APIUser - if ($user instanceof User) - { - $invoice->setCreatedBy($user); - } - - $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; - } - - // process battery sales and trade-ins - protected function processEntries(&$total, InvoiceCriteria $criteria, Invoice $invoice) - { - $entries = $criteria->getEntries(); - - $con_batts = []; - $con_tis = []; - foreach($entries as $entry) - { - // batteries purchased should have trade_in set to null - $batt = $entry['battery']; - $qty = $entry['qty']; - $trade_in = $entry['trade_in']; - $size = $batt->getSize(); - - // consolidate batteries - $batt_id = $batt->getID(); - if (!isset($con_batts[$batt_id])) - $con_batts[$batt->getID()] = [ - 'batt' => $batt, - 'qty' => 0 - ]; - $con_batts[$batt_id]['qty']++; - - // no trade-in - if ($trade_in == null) - continue; - - // consolidate trade-ins - // need to set battery for trade in so we know what battery is for trade in - // possible that battery purchased is not the same battery for trade in - $ti_key = $size->getID() . '|' . $trade_in; - if (!isset($con_tis[$ti_key])) - $con_tis[$ti_key] = [ - 'batt' => $batt, - 'size' => $size, - 'trade_in' => $trade_in, - 'qty' => 0 - ]; - $con_tis[$ti_key]['qty']++; - } - - $inv_batt_entries = $this->inv_batt->processBatteries($con_batts, $total); - $inv_trade_in_entries = $this->inv_trade->processTradeIns($con_tis, $total); - - // check if we need to compute tax - if ($criteria->isTaxable()) - { - $this->inv_tax->computeTax($inv_batt_entries, $total); - } - } + // TODO: get list of invoice rules from .env + // TODO: get the service type fees } diff --git a/src/Service/InvoiceTaxManager.php b/src/Service/InvoiceTaxManager.php deleted file mode 100644 index 1535c68e..00000000 --- a/src/Service/InvoiceTaxManager.php +++ /dev/null @@ -1,29 +0,0 @@ -getTaxAmount($sell_price); - $vat_ex_price = $this->getTaxExclusivePrice($sell_price); - - // TODO: add to the total array the computed vat prices - } - } - - // TODO: use bc functions for these - protected function getTaxAmount($price) - { - $vat_ex_price = $this->getTaxExclusivePrice($price); - return $price - $vat_ex_price; - } - - protected function getTaxExclusivePrice($price) - { - return round($price / (1 + self::TAX_RATE), 2); - } -} diff --git a/src/Service/InvoiceTradeInManager.php b/src/Service/InvoiceTradeInManager.php deleted file mode 100644 index e0e04308..00000000 --- a/src/Service/InvoiceTradeInManager.php +++ /dev/null @@ -1,53 +0,0 @@ -getTradeInRate($ti); - - $ti_price = bcmul($ti_rate, -1, 2); - $invoice_trade_ins = [ - 'title' => 'Trade-in ' . TradeInType::getName($ti['trade_in']) . ' ' . $ti['size']->getName() . ' battery'), - 'qty' => $qty, - 'price' => $ti_price, - ]; - - $tti_price = bcmul($ti_rate, $qty, 2); - - $total['ti_rate'] = bcadd($total['ti_rate'], $tti_price, 2); - $total['total_price'] = bcsub($total['total_price'], $tti_price, 2); - } - - return $invoice_trade_ins; - } - - protected function getTradeInRate($ti) - { - $size = $ti['size']; - $trade_in = $ti['trade_in']; - - if ($trade_in == null) - return 0; - - switch ($trade_in) - { - case TradeInType::MOTOLITE: - return $size->getTIPriceMotolite(); - case TradeInType::PREMIUM: - return $size->getTIPricePremium(); - case TradeInType::OTHER: - return $size->getTIPriceOther(); - } - - return 0; - } -} From 0063f10f93a19b6ec5917b70d2a86a818803a301 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 24 May 2023 06:16:44 -0400 Subject: [PATCH 03/25] Add function to check what rules to use. #744 --- src/Invoice/1 | 37 +++++++++ src/Invoice/BatteryReplacementWarranty.php | 39 ++++++++++ src/Invoice/BatterySales.php | 38 +++++++++ src/Invoice/Discount.php | 34 +++++++++ src/Invoice/Fuel.php | 37 +++++++++ src/Invoice/Jumpstart.php | 37 +++++++++ src/Invoice/JumpstartWarranty.php | 37 +++++++++ src/Invoice/Overheat.php | 37 +++++++++ src/Invoice/PostRecharged.php | 37 +++++++++ src/Invoice/PostReplacement.php | 37 +++++++++ src/Invoice/ServiceType.php | 19 +++-- src/Invoice/TireRepair.php | 37 +++++++++ src/Invoice/TradeIn.php | 58 ++++++++++++++ src/InvoiceCriteria.php | 2 +- src/Service/InvoiceManager.php | 89 +++++++++++++++++++++- 15 files changed, 565 insertions(+), 10 deletions(-) create mode 100644 src/Invoice/1 create mode 100644 src/Invoice/BatteryReplacementWarranty.php create mode 100644 src/Invoice/BatterySales.php create mode 100644 src/Invoice/Discount.php create mode 100644 src/Invoice/Fuel.php create mode 100644 src/Invoice/Jumpstart.php create mode 100644 src/Invoice/JumpstartWarranty.php create mode 100644 src/Invoice/Overheat.php create mode 100644 src/Invoice/PostRecharged.php create mode 100644 src/Invoice/PostReplacement.php create mode 100644 src/Invoice/TireRepair.php create mode 100644 src/Invoice/TradeIn.php diff --git a/src/Invoice/1 b/src/Invoice/1 new file mode 100644 index 00000000..4ce94378 --- /dev/null +++ b/src/Invoice/1 @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'overheat'; + } + + public function getAmount($battery = null, $service_type_fees) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$this->getID()])) + return $service_type_fees[$this->getID()]; + + return 0; + } +} diff --git a/src/Invoice/BatteryReplacementWarranty.php b/src/Invoice/BatteryReplacementWarranty.php new file mode 100644 index 00000000..a6c8b201 --- /dev/null +++ b/src/Invoice/BatteryReplacementWarranty.php @@ -0,0 +1,39 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + return 'invoice/battery.html.twig'; + } + + public function getID() + { + return 'battery_warranty'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id)) + return $service_type_fees[$id]; + + return 0; + } +} + diff --git a/src/Invoice/BatterySales.php b/src/Invoice/BatterySales.php new file mode 100644 index 00000000..2e05ab2b --- /dev/null +++ b/src/Invoice/BatterySales.php @@ -0,0 +1,38 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + return 'invoice/battery.html.twig'; + } + + public function getID() + { + return 'battery_new'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id])) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/Discount.php b/src/Invoice/Discount.php new file mode 100644 index 00000000..62a37eb6 --- /dev/null +++ b/src/Invoice/Discount.php @@ -0,0 +1,34 @@ +getDiscount()) + return true; + + return false; + + } + + public function getTemplate() + { + return 'invoice/discount.html.twig'; + } + + public function getID() + { + return 'discount'; + } + + public function getAmount($battery = null, $discount_list, $id) + { + return 0; + } +} + diff --git a/src/Invoice/Fuel.php b/src/Invoice/Fuel.php new file mode 100644 index 00000000..4a700f3b --- /dev/null +++ b/src/Invoice/Fuel.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'fuel'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id])) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/Jumpstart.php b/src/Invoice/Jumpstart.php new file mode 100644 index 00000000..36c25fa7 --- /dev/null +++ b/src/Invoice/Jumpstart.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'jumpstart_troubleshoot'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id])) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/JumpstartWarranty.php b/src/Invoice/JumpstartWarranty.php new file mode 100644 index 00000000..5ca77781 --- /dev/null +++ b/src/Invoice/JumpstartWarranty.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'jumpstart_warranty'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id)) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/Overheat.php b/src/Invoice/Overheat.php new file mode 100644 index 00000000..dfe33cbc --- /dev/null +++ b/src/Invoice/Overheat.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'overheat'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id])) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/PostRecharged.php b/src/Invoice/PostRecharged.php new file mode 100644 index 00000000..31678bc1 --- /dev/null +++ b/src/Invoice/PostRecharged.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'post_recharged'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id)) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/PostReplacement.php b/src/Invoice/PostReplacement.php new file mode 100644 index 00000000..bab0cb44 --- /dev/null +++ b/src/Invoice/PostReplacement.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'post_replacement'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id])) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/ServiceType.php b/src/Invoice/ServiceType.php index e27f2bc6..fc33c64b 100644 --- a/src/Invoice/ServiceType.php +++ b/src/Invoice/ServiceType.php @@ -8,13 +8,8 @@ class ServiceType implements InvoiceInterface { public function check($settings, $criteria) { - // compare specified type ids with service type of criteria - $stypes = $settings['type_id']; - foreach ($stypes as $type_id) - { - if ($type_id == $criteria->getServiceType()) - return true; - } + if (isset($settings['service_type'])) + return true; return false; } @@ -23,4 +18,14 @@ class ServiceType implements InvoiceInterface { return 'invoice/service_type.html.twig'; } + + public function getID() + { + return 'service_type'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + return 0; + } } diff --git a/src/Invoice/TireRepair.php b/src/Invoice/TireRepair.php new file mode 100644 index 00000000..dcd20ed3 --- /dev/null +++ b/src/Invoice/TireRepair.php @@ -0,0 +1,37 @@ +getServiceType()) + return true; + + return false; + } + + public function getTemplate() + { + } + + public function getID() + { + return 'tire'; + } + + public function getAmount($battery = null, $service_type_fees, $id) + { + if ($battery != null) + return $battery->getSellingPrice(); + + if (isset($service_type_fees[$id)) + return $service_type_fees[$id]; + + return 0; + } +} diff --git a/src/Invoice/TradeIn.php b/src/Invoice/TradeIn.php new file mode 100644 index 00000000..e4fb974b --- /dev/null +++ b/src/Invoice/TradeIn.php @@ -0,0 +1,58 @@ +getEntries(); + + foreach ($trade_ins as $type_id) + { + foreach($entries as $entry) + { + if ($type_id == $entry['trade_in']) + return true; + } + } + + return false; + } + + public function getTemplate() + { + return 'invoice/trade_in.html.twig'; + } + + public function getID() + { + return 'trade_in'; + } + + public function getAmount($battery = null, $trade_in_types, $id) + { + if (isset($trade_in_types[$id])) + { + if ($battery != null) + { + switch ($trade_in) + { + case TradeInType::MOTOLITE: + return $battery->getSize()->getTIPriceMotolite(); + case TradeInType::PREMIUM: + return $battery0>getSize()->getTIPricePremium(); + case TradeInType::OTHER: + return $battery->getSize()->getTIPriceOther(); + } + } + } + + return 0; + } +} + diff --git a/src/InvoiceCriteria.php b/src/InvoiceCriteria.php index 886d6024..12ee71e0 100644 --- a/src/InvoiceCriteria.php +++ b/src/InvoiceCriteria.php @@ -1,6 +1,6 @@ em = $em; + + $this->available_rules = $this->getAllRules(); + } + + 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\JumstartWarranty(), + new Invoice\PostRecharged(), + new Invoice\PostReplacement(), + new Invoice\Overheat(), + new Invoice\Fuel(), + new Invoice\TireRepair(), + new Invoice\Discount(), + new Invoice\TradeIn(), + ]; + } + + // check what rules to use given the criteria + public function check($criteria) + { + // get what is in criteria + $stype = $criteria->getServiceType(); + $discount = $criteria->getDiscount(); + $entries = $criteria->getEntries(); + + $batteries = []; + $trade_ins = []; + foreach ($entries as $entry) + { + if ($entry['trade_in'] != null) + { + // battery purchase + $batteries[] = [ + 'battery' => $entry['battery'], + 'qty' => $entry['qty'], + ]; + } + else + { + // trade in + $trade_ins[] = [ + 'battery' => $entry['battery'], + 'qty' => $entry['qty'], + ]; + } + } + + $settings = [ + 'service_type' => $criteria->getServiceType(), + 'discount' => $criteria->getDiscount(), + 'batteries' => $batteries, + 'trade_ins' => $trade_ins, + ]; + + $active_rules = []; + foreach ($this->available_rules as $rule) + { + $is_active = $rule->check($settings, $criteria); + if ($is_active) + $active_rules[$rule->getID()] = $rule; + } + + return $active_rules; + + } + + public function compute($invoice, $criteria, $active_rules) + { + // get what is in criteria + $stype = $criteria->getServiceType(); + $discount = $criteria->getDiscount(); + $entries = $criteria->getEntries(); + + // TODO: need to find out how to call the correct rule + } } From 15830924e2e6c961e6b4e06701a9dcb5bf0475c7 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 25 May 2023 06:06:15 -0400 Subject: [PATCH 04/25] Add function to process the criteria entries. #744 --- src/Invoice/1 | 37 ----------- src/Invoice/BatteryReplacementWarranty.php | 36 +++++++++-- src/Invoice/BatterySales.php | 47 ++++++++++++-- src/Invoice/JumpstartWarranty.php | 2 +- src/Invoice/PostRecharged.php | 2 +- src/Invoice/TireRepair.php | 2 +- src/Service/InvoiceManager.php | 71 +++++++++++++++++++++- 7 files changed, 143 insertions(+), 54 deletions(-) delete mode 100644 src/Invoice/1 diff --git a/src/Invoice/1 b/src/Invoice/1 deleted file mode 100644 index 4ce94378..00000000 --- a/src/Invoice/1 +++ /dev/null @@ -1,37 +0,0 @@ -getServiceType()) - return true; - - return false; - } - - public function getTemplate() - { - } - - public function getID() - { - return 'overheat'; - } - - public function getAmount($battery = null, $service_type_fees) - { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$this->getID()])) - return $service_type_fees[$this->getID()]; - - return 0; - } -} diff --git a/src/Invoice/BatteryReplacementWarranty.php b/src/Invoice/BatteryReplacementWarranty.php index a6c8b201..4d571a9f 100644 --- a/src/Invoice/BatteryReplacementWarranty.php +++ b/src/Invoice/BatteryReplacementWarranty.php @@ -25,15 +25,39 @@ class BatteryReplacementWarranty implements InvoiceInterface return 'battery_warranty'; } - public function getAmount($battery = null, $service_type_fees, $id) + // TODO: need to add service type fees as a parameter + public function compute($criteria) { - if ($battery != null) - return $battery->getSellingPrice(); + $stype = $criteria->getServiceType(); - if (isset($service_type_fees[$id)) - return $service_type_fees[$id]; + $items = []; + if ($stype == $this->getID()) + { + // get the entries + $entries = $criteria->getEntries(); + foreach($entries as $entry) + { + $batt = $entry['battery']; + $qty = 1; + $price = 0; // need to put this in a config or something - return 0; + $items[] = [ + 'battery' => $batt, + 'qty' => $qty, + 'title' => $this->getTitle($batt), + 'price' => $price, + ]; + } + } + + return $items; + } + + protected function getTitle($battery) + { + $title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit'); + + return $title; } } diff --git a/src/Invoice/BatterySales.php b/src/Invoice/BatterySales.php index 2e05ab2b..f0b316d7 100644 --- a/src/Invoice/BatterySales.php +++ b/src/Invoice/BatterySales.php @@ -25,14 +25,49 @@ class BatterySales implements InvoiceInterface return 'battery_new'; } - public function getAmount($battery = null, $service_type_fees, $id) + // TODO: need to add service type fees as a parameter + public function compute($criteria) { - if ($battery != null) - return $battery->getSellingPrice(); + $stype = $criteria->getServiceType(); - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; + $items = []; + if ($stype == $this->getID()) + { + // get the entries + $entries = $criteria->getEntries(); + foreach($entries as $entry) + { + $batt = $entry['battery']; + $qty = $entry['qty']; + $trade_in = null; - return 0; + if (isset($entry['trade_in'])) + $trade_in = $entry['trade_in']; + + $size = $batt->getSize(); + + if ($trade_in == null) + { + // battery purchase + $price = $batt->getSellingPrice(); + + $items[] = [ + 'battery' => $batt, + 'qty' => $qty, + 'title' => $this->getTitle($batt), + 'price' => $price, + ]; + } + } + } + + return $items; + } + + protected function getTitle($battery) + { + $title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName(); + + return $title; } } diff --git a/src/Invoice/JumpstartWarranty.php b/src/Invoice/JumpstartWarranty.php index 5ca77781..b7f89c3c 100644 --- a/src/Invoice/JumpstartWarranty.php +++ b/src/Invoice/JumpstartWarranty.php @@ -29,7 +29,7 @@ class JumpstartWarranty implements InvoiceInterface if ($battery != null) return $battery->getSellingPrice(); - if (isset($service_type_fees[$id)) + if (isset($service_type_fees[$id])) return $service_type_fees[$id]; return 0; diff --git a/src/Invoice/PostRecharged.php b/src/Invoice/PostRecharged.php index 31678bc1..26122764 100644 --- a/src/Invoice/PostRecharged.php +++ b/src/Invoice/PostRecharged.php @@ -29,7 +29,7 @@ class PostRecharged implements InvoiceInterface if ($battery != null) return $battery->getSellingPrice(); - if (isset($service_type_fees[$id)) + if (isset($service_type_fees[$id])) return $service_type_fees[$id]; return 0; diff --git a/src/Invoice/TireRepair.php b/src/Invoice/TireRepair.php index dcd20ed3..c659aa31 100644 --- a/src/Invoice/TireRepair.php +++ b/src/Invoice/TireRepair.php @@ -29,7 +29,7 @@ class TireRepair implements InvoiceInterface if ($battery != null) return $battery->getSellingPrice(); - if (isset($service_type_fees[$id)) + if (isset($service_type_fees[$id])) return $service_type_fees[$id]; return 0; diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 84479f62..95831d65 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -46,6 +46,22 @@ class InvoiceManager ]; } + public function getServiceTypeFees() + { + return [ + 'service_fee' => 300, + 'coolant_fee' => 1600, + 'recharge_fee' => 300, + 'jumpstart_fee' => 150, + 'jumpstart_warranty_fee' => 0, + 'battery_replacement_fee' => 0, + 'warranty_fee' => 0, + 'other_services_fee' => 200, + 'refuel_fee_gas' => 320, + 'refuel_fee_diesel' => 320, + ]; + } + // check what rules to use given the criteria public function check($criteria) { @@ -58,7 +74,7 @@ class InvoiceManager $trade_ins = []; foreach ($entries as $entry) { - if ($entry['trade_in'] != null) + if ($entry['trade_in'] == null) { // battery purchase $batteries[] = [ @@ -102,6 +118,57 @@ class InvoiceManager $discount = $criteria->getDiscount(); $entries = $criteria->getEntries(); - // TODO: need to find out how to call the correct rule + $flag_trade_in = false; + foreach ($entries as $entry) + { + if ($entry['trade_in'] != null) + { + $flag_trade_in = true; + } + } + + foreach ($active_rules as $id => $active_rule) + { + if ($id == $stype) + { + // process trade-ins by calling the trade-in rule if there are trade-ins + // since it's lumped with only the battery_new service type + $trade_in_items = []; + if ($flag_trade_in) + { + $trade_in_items = $active_rules['trade_in']->compute($criteria); + } + + // TODO: need to pass service type fees to compute + $items = $active_rule->compute($criteria); + + foreach ($items as $item) + { + $invoice_item = new InvoiceItem(); + + $invoice_item->setInvoice($invoice) + ->setTitle($item['title']) + ->setQuantity($item['qty']) + ->setPrice($item['price']); + + if (isset($item['battery'])) + $invoice_item->setBattery($item['battery']); + + $invoice->addItem($invoice_item); + } + + foreach ($trade_in_items as $trade_in) + { + $invoice_item = new InvoiceItem(); + + $invoice_item->setInvoice($invoice) + ->setTitle($trade_in_item['title']) + ->setQuantity($trade_in_item['qty']) + ->setPrice($trade_initem['price']); + + $invoice->addItem($invoice_item); + } + } + } } } From e3ec6148df5f8aa39347b50023475cd828cbc538 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 26 May 2023 05:54:22 -0400 Subject: [PATCH 05/25] Add command to test invoice manager. #744 --- src/Command/TestInvoiceManagerCommand.php | 75 ++++++++++++++ src/Invoice/BatteryReplacementWarranty.php | 14 +-- src/Invoice/BatterySales.php | 8 +- src/Invoice/Discount.php | 34 ------- src/Invoice/DiscountType.php | 33 +++++++ src/Invoice/Fuel.php | 71 ++++++++++++-- src/Invoice/Jumpstart.php | 15 +-- src/Invoice/JumpstartWarranty.php | 22 ++--- src/Invoice/Overheat.php | 19 ++-- src/Invoice/PostRecharged.php | 17 +--- src/Invoice/PostReplacement.php | 21 ++-- src/Invoice/ServiceType.php | 7 +- src/Invoice/TireRepair.php | 22 ++--- src/Invoice/TradeIn.php | 31 ++---- src/InvoiceInterface.php | 4 +- src/Service/InvoiceManager.php | 109 ++++++++------------- 16 files changed, 269 insertions(+), 233 deletions(-) create mode 100644 src/Command/TestInvoiceManagerCommand.php delete mode 100644 src/Invoice/Discount.php create mode 100644 src/Invoice/DiscountType.php diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php new file mode 100644 index 00000000..14c8ff90 --- /dev/null +++ b/src/Command/TestInvoiceManagerCommand.php @@ -0,0 +1,75 @@ +setName('test:generateinvoice') + ->setDescription('Test invoice manager service.') + ->setHelp('Test invoice manager service.'); + } + + public function __construct(InvoiceManager $inv_manager, EntityManagerInterface $em) + { + $this->em = $em; + $this->inv_manager = $inv_manager; + + parent::__construct(); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->testBatterySalesNoTradeInNoDiscount(); + + // TEST SCENARIO: new battery with trade in + // TEST SCENARIO: new battery with discount + // TEST SCENARIO: new battery with discount and trade-in + // TEST SCENARIO: fuel, gas + // TEST SCENARIO: fuel, diesel + // TEST SCENARIO: fuel, gas, with discount + return 0; + } + + protected function testBatterySalesNoTradeInNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, no trade-in, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $criteria->addEntry($battery, null, 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } +} diff --git a/src/Invoice/BatteryReplacementWarranty.php b/src/Invoice/BatteryReplacementWarranty.php index 4d571a9f..e1a1536b 100644 --- a/src/Invoice/BatteryReplacementWarranty.php +++ b/src/Invoice/BatteryReplacementWarranty.php @@ -6,10 +6,9 @@ use App\InvoiceInterface; class BatteryReplacementWarranty implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; return false; @@ -25,8 +24,7 @@ class BatteryReplacementWarranty implements InvoiceInterface return 'battery_warranty'; } - // TODO: need to add service type fees as a parameter - public function compute($criteria) + public function compute($criteria, $stype_fees) { $stype = $criteria->getServiceType(); @@ -35,11 +33,13 @@ class BatteryReplacementWarranty implements InvoiceInterface { // get the entries $entries = $criteria->getEntries(); + + $stype_fee_id = $this->getID() . '_fee'; foreach($entries as $entry) { $batt = $entry['battery']; $qty = 1; - $price = 0; // need to put this in a config or something + $price = $stype_fees[$stype_fee_id]; $items[] = [ 'battery' => $batt, @@ -55,7 +55,7 @@ class BatteryReplacementWarranty implements InvoiceInterface protected function getTitle($battery) { - $title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit'); + $title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' - Service Unit'; return $title; } diff --git a/src/Invoice/BatterySales.php b/src/Invoice/BatterySales.php index f0b316d7..d102f950 100644 --- a/src/Invoice/BatterySales.php +++ b/src/Invoice/BatterySales.php @@ -6,10 +6,9 @@ use App\InvoiceInterface; class BatterySales implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; return false; @@ -25,8 +24,7 @@ class BatterySales implements InvoiceInterface return 'battery_new'; } - // TODO: need to add service type fees as a parameter - public function compute($criteria) + public function compute($criteria, $stype_fees) { $stype = $criteria->getServiceType(); diff --git a/src/Invoice/Discount.php b/src/Invoice/Discount.php deleted file mode 100644 index 62a37eb6..00000000 --- a/src/Invoice/Discount.php +++ /dev/null @@ -1,34 +0,0 @@ -getDiscount()) - return true; - - return false; - - } - - public function getTemplate() - { - return 'invoice/discount.html.twig'; - } - - public function getID() - { - return 'discount'; - } - - public function getAmount($battery = null, $discount_list, $id) - { - return 0; - } -} - diff --git a/src/Invoice/DiscountType.php b/src/Invoice/DiscountType.php new file mode 100644 index 00000000..6ce07355 --- /dev/null +++ b/src/Invoice/DiscountType.php @@ -0,0 +1,33 @@ +getPromos())) + return true; + + return false; + + } + + public function getTemplate() + { + return 'invoice/discount_type.html.twig'; + } + + public function getID() + { + return 'discount_type'; + } + + public function compute($criteria, $stype_fees) + { + return []; + } +} + diff --git a/src/Invoice/Fuel.php b/src/Invoice/Fuel.php index 4a700f3b..ad0680a1 100644 --- a/src/Invoice/Fuel.php +++ b/src/Invoice/Fuel.php @@ -4,12 +4,13 @@ namespace App\Invoice; use App\InvoiceInterface; +use App\Ramcar\FuelType; + class Fuel implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; return false; @@ -24,14 +25,66 @@ class Fuel implements InvoiceInterface return 'fuel'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); + $stype = $criteria->getServiceType(); - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; + $items = []; - return 0; + + if ($stype == $this->getID()) + { + // check if customer vehicle has a motolite battery + $cv = $criteria->getCustomerVehicle(); + if ($cv->hasMotoliteBattery()) + $fee = 0; + else + $fee = $stype_fees['service_fee']; + + // add the service fee to items + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getTitle($ftype), + 'price' => $fee, + ]; + + $ftype = $cv->getFuelType(); + + $stype_fees_id = $this->getID() . '_' . $ftype; + + switch ($ftype) + { + case FuelType::GAS: + case FuelType::DIESEL: + $qty = 1; + $price = $stype_fees[$stype_fees_id]; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getTitle($ftype), + 'price' => $price, + ]; + + break; + default: + $qty = 1; + $price = 0; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getTitle('Unknown'), + 'price' => $price, + ]; + break; + } + } + + return $items; + } + + protected function getTitle($fuel_type) + { + $title = '4L - ' . $fuel_type; + + return $title; } } diff --git a/src/Invoice/Jumpstart.php b/src/Invoice/Jumpstart.php index 36c25fa7..84ac7ff6 100644 --- a/src/Invoice/Jumpstart.php +++ b/src/Invoice/Jumpstart.php @@ -6,10 +6,9 @@ use App\InvoiceInterface; class Jumpstart implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; return false; @@ -24,14 +23,8 @@ class Jumpstart implements InvoiceInterface return 'jumpstart_troubleshoot'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; - - return 0; + return []; } } diff --git a/src/Invoice/JumpstartWarranty.php b/src/Invoice/JumpstartWarranty.php index b7f89c3c..dc322036 100644 --- a/src/Invoice/JumpstartWarranty.php +++ b/src/Invoice/JumpstartWarranty.php @@ -5,15 +5,14 @@ namespace App\Invoice; use App\InvoiceInterface; class JumpstartWarranty implements InvoiceInterface -{ - public function check($settings, $criteria) +{ + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; - + return false; - } + } public function getTemplate() { @@ -24,14 +23,9 @@ class JumpstartWarranty implements InvoiceInterface return 'jumpstart_warranty'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; - - return 0; + return []; } + } diff --git a/src/Invoice/Overheat.php b/src/Invoice/Overheat.php index dfe33cbc..5e8e0aae 100644 --- a/src/Invoice/Overheat.php +++ b/src/Invoice/Overheat.php @@ -6,15 +6,14 @@ use App\InvoiceInterface; class Overheat implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; - + return false; } - + public function getTemplate() { } @@ -24,14 +23,8 @@ class Overheat implements InvoiceInterface return 'overheat'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; - - return 0; + return []; } } diff --git a/src/Invoice/PostRecharged.php b/src/Invoice/PostRecharged.php index 26122764..546736fd 100644 --- a/src/Invoice/PostRecharged.php +++ b/src/Invoice/PostRecharged.php @@ -6,12 +6,11 @@ use App\InvoiceInterface; class PostRecharged implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; - + return false; } @@ -24,14 +23,8 @@ class PostRecharged implements InvoiceInterface return 'post_recharged'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; - - return 0; + return []; } } diff --git a/src/Invoice/PostReplacement.php b/src/Invoice/PostReplacement.php index bab0cb44..3d891ffb 100644 --- a/src/Invoice/PostReplacement.php +++ b/src/Invoice/PostReplacement.php @@ -5,15 +5,14 @@ namespace App\Invoice; use App\InvoiceInterface; class PostReplacement implements InvoiceInterface -{ - public function check($settings, $criteria) +{ + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; - + return false; - } + } public function getTemplate() { @@ -24,14 +23,8 @@ class PostReplacement implements InvoiceInterface return 'post_replacement'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; - - return 0; + return []; } } diff --git a/src/Invoice/ServiceType.php b/src/Invoice/ServiceType.php index fc33c64b..120ac0a7 100644 --- a/src/Invoice/ServiceType.php +++ b/src/Invoice/ServiceType.php @@ -6,9 +6,9 @@ use App\InvoiceInterface; class ServiceType implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { - if (isset($settings['service_type'])) + if ($criteria->getServiceType() != null) return true; return false; @@ -24,8 +24,7 @@ class ServiceType implements InvoiceInterface return 'service_type'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - return 0; } } diff --git a/src/Invoice/TireRepair.php b/src/Invoice/TireRepair.php index c659aa31..3a903bab 100644 --- a/src/Invoice/TireRepair.php +++ b/src/Invoice/TireRepair.php @@ -5,15 +5,14 @@ namespace App\Invoice; use App\InvoiceInterface; class TireRepair implements InvoiceInterface -{ - public function check($settings, $criteria) +{ + public function check($criteria) { - $type_id = $settings['service_type']; - if ($type_id == $criteria->getServiceType()) + if ($this->getID() == $criteria->getServiceType()) return true; - + return false; - } + } public function getTemplate() { @@ -24,14 +23,9 @@ class TireRepair implements InvoiceInterface return 'tire'; } - public function getAmount($battery = null, $service_type_fees, $id) + public function compute($criteria, $stype_fees) { - if ($battery != null) - return $battery->getSellingPrice(); - - if (isset($service_type_fees[$id])) - return $service_type_fees[$id]; - - return 0; + return []; } + } diff --git a/src/Invoice/TradeIn.php b/src/Invoice/TradeIn.php index e4fb974b..ffb1ffc9 100644 --- a/src/Invoice/TradeIn.php +++ b/src/Invoice/TradeIn.php @@ -6,18 +6,17 @@ use App\InvoiceInterface; class TradeIn implements InvoiceInterface { - public function check($settings, $criteria) + public function check($criteria) { // compare specified type ids with trade in entry of criteria - $trade_ins = $settings['trade_ins']; $entries = $criteria->getEntries(); - foreach ($trade_ins as $type_id) + foreach($entries as $entry) { - foreach($entries as $entry) + if ($this->getID() == $entry['trade_in']) { - if ($type_id == $entry['trade_in']) - return true; + // just need to find one trade-in entry + return true; } } @@ -34,25 +33,9 @@ class TradeIn implements InvoiceInterface return 'trade_in'; } - public function getAmount($battery = null, $trade_in_types, $id) + public function compute($criteria, $stype_fees) { - if (isset($trade_in_types[$id])) - { - if ($battery != null) - { - switch ($trade_in) - { - case TradeInType::MOTOLITE: - return $battery->getSize()->getTIPriceMotolite(); - case TradeInType::PREMIUM: - return $battery0>getSize()->getTIPricePremium(); - case TradeInType::OTHER: - return $battery->getSize()->getTIPriceOther(); - } - } - } - - return 0; + return []; } } diff --git a/src/InvoiceInterface.php b/src/InvoiceInterface.php index 704e4e46..1812fd83 100644 --- a/src/InvoiceInterface.php +++ b/src/InvoiceInterface.php @@ -4,8 +4,8 @@ namespace App; interface InvoiceInterface { - // check if the invoice rule aka settings is in the criteria - public function check($settings, $criteria); + // check if the invoice rule is in the criteria + public function check($criteria); // display the html partial for the form public function getTemplate(); diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 95831d65..bfbaa7eb 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -7,10 +7,11 @@ use Symfony\Component\Validator\Validator\ValidatorInterface; use Doctrine\ORM\EntityManagerInterface; +use App\Invoice; + use App\Ramcar\InvoiceCriteria; use App\Ramcar\InvoiceStatus; -use App\Entity\Invoice; use App\Entity\InvoiceItem; use App\Entity\User; use App\Entity\Battery; @@ -24,7 +25,7 @@ class InvoiceManager { $this->em = $em; - $this->available_rules = $this->getAllRules(); + $this->available_rules = $this->getAvailableRules(); } public function getAvailableRules() @@ -35,15 +36,15 @@ class InvoiceManager new Invoice\BatterySales(), new Invoice\BatteryReplacementWarranty(), new Invoice\Jumpstart(), - new Invoice\JumstartWarranty(), + new Invoice\JumpstartWarranty(), new Invoice\PostRecharged(), new Invoice\PostReplacement(), new Invoice\Overheat(), new Invoice\Fuel(), new Invoice\TireRepair(), - new Invoice\Discount(), + new Invoice\DiscountType(), new Invoice\TradeIn(), - ]; + ]; } public function getServiceTypeFees() @@ -55,54 +56,20 @@ class InvoiceManager 'jumpstart_fee' => 150, 'jumpstart_warranty_fee' => 0, 'battery_replacement_fee' => 0, - 'warranty_fee' => 0, + 'battery_warranty_fee' => 0, 'other_services_fee' => 200, - 'refuel_fee_gas' => 320, - 'refuel_fee_diesel' => 320, + 'fuel_fee_gas' => 320, + 'fuel_fee_diesel' => 320, ]; } // check what rules to use given the criteria public function check($criteria) { - // get what is in criteria - $stype = $criteria->getServiceType(); - $discount = $criteria->getDiscount(); - $entries = $criteria->getEntries(); - - $batteries = []; - $trade_ins = []; - foreach ($entries as $entry) - { - if ($entry['trade_in'] == null) - { - // battery purchase - $batteries[] = [ - 'battery' => $entry['battery'], - 'qty' => $entry['qty'], - ]; - } - else - { - // trade in - $trade_ins[] = [ - 'battery' => $entry['battery'], - 'qty' => $entry['qty'], - ]; - } - } - - $settings = [ - 'service_type' => $criteria->getServiceType(), - 'discount' => $criteria->getDiscount(), - 'batteries' => $batteries, - 'trade_ins' => $trade_ins, - ]; - $active_rules = []; foreach ($this->available_rules as $rule) { - $is_active = $rule->check($settings, $criteria); + $is_active = $rule->check($criteria); if ($is_active) $active_rules[$rule->getID()] = $rule; } @@ -111,13 +78,15 @@ class InvoiceManager } - public function compute($invoice, $criteria, $active_rules) + public function compute($criteria, $active_rules) { // get what is in criteria $stype = $criteria->getServiceType(); - $discount = $criteria->getDiscount(); $entries = $criteria->getEntries(); + // get the service type fees + $stype_fees = $this->getServiceTypeFees(); + $flag_trade_in = false; foreach ($entries as $entry) { @@ -127,48 +96,48 @@ class InvoiceManager } } + $invoice_items = []; foreach ($active_rules as $id => $active_rule) { if ($id == $stype) { + $items = []; // process trade-ins by calling the trade-in rule if there are trade-ins // since it's lumped with only the battery_new service type - $trade_in_items = []; if ($flag_trade_in) { - $trade_in_items = $active_rules['trade_in']->compute($criteria); + $tradein_items = $active_rules['trade_in']->compute($criteria); + foreach ($tradein_items as $tradein_item) + { + $items[] = $tradein_item; + } } - // TODO: need to pass service type fees to compute - $items = $active_rule->compute($criteria); + $computed_items = $active_rule->compute($criteria, $stype_fees); + foreach ($computed_items as $computed_item) + { + $items[] = $computed_item; + } foreach ($items as $item) { - $invoice_item = new InvoiceItem(); + if (isset($item['title'])) + { + $invoice_item = new InvoiceItem(); - $invoice_item->setInvoice($invoice) - ->setTitle($item['title']) - ->setQuantity($item['qty']) - ->setPrice($item['price']); + $invoice_item->setTitle($item['title']) + ->setQuantity($item['qty']) + ->setPrice($item['price']); - if (isset($item['battery'])) - $invoice_item->setBattery($item['battery']); + if (isset($item['battery'])) + $invoice_item->setBattery($item['battery']); - $invoice->addItem($invoice_item); - } - - foreach ($trade_in_items as $trade_in) - { - $invoice_item = new InvoiceItem(); - - $invoice_item->setInvoice($invoice) - ->setTitle($trade_in_item['title']) - ->setQuantity($trade_in_item['qty']) - ->setPrice($trade_initem['price']); - - $invoice->addItem($invoice_item); - } + $invoice_items[] = $invoice_item; + } + } } } + + return $invoice_items; } } From 9bac6df2dfefe0726b63568b28c73fbab18e183c Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 29 May 2023 06:05:59 -0400 Subject: [PATCH 06/25] Add rules for trade in and other service types. Add test scenarios. #744 --- src/Command/TestInvoiceManagerCommand.php | 556 +++++++++++++++++++++- src/Invoice/Fuel.php | 18 +- src/Invoice/Jumpstart.php | 28 +- src/Invoice/JumpstartWarranty.php | 27 +- src/Invoice/Overheat.php | 51 +- src/Invoice/PostRecharged.php | 26 +- src/Invoice/PostReplacement.php | 26 +- src/Invoice/TireRepair.php | 30 +- src/Invoice/TradeIn.php | 59 ++- src/Service/InvoiceManager.php | 24 +- 10 files changed, 813 insertions(+), 32 deletions(-) diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 14c8ff90..68051147 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -15,6 +15,7 @@ use App\InvoiceCriteria; use App\Ramcar\ServiceType; use App\Entity\Battery; +use App\Entity\CustomerVehicle; class TestInvoiceManagerCommand extends Command { @@ -38,14 +39,52 @@ class TestInvoiceManagerCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { + // battery sales $this->testBatterySalesNoTradeInNoDiscount(); + $this->testBatterySalesQuantityNoTradeInNoDiscount(); + + // battery sales with trade in + $this->testBatterySalesTradeInSameBatteryPremiumNoDiscount(); + $this->testBatterySalesTradeInSameBatteryMotoliteNoDiscount(); + $this->testBatterySalesTradeInSameBatteryOtherNoDiscount(); + $this->testBatterySalesTradeInDifferentBatteryPremiumNoDiscount(); + $this->testBatterySalesTradeInDifferentBatteryMotoliteNoDiscount(); + $this->testBatterySalesTradeInDifferentBatteryOtherNoDiscount(); + $this->testBatterySalesTradeInQuantityNoDiscount(); + + // battery sales with discount + + // battery replacement warranty + $this->testBatteryReplacementWarranty(); + + // fuel + $this->testFuelGasWithServiceFee(); + $this->testFuelDieselWithServiceFee(); + $this->testFuelGasWithNoServiceFee(); + $this->testFuelDieselWithNoServiceFee(); + + // jumpstart + $this->testJumpstart(); + + // jumpstart warranty + $this->testJumpstartWarranty(); + + // overheat + $this->testOverheatAssistanceWithCoolant(); + $this->testOverheatAssistanceWithoutCoolant(); + + // post-recharged + $this->testPostRecharged(); + + // post replacement + $this->testPostReplacement(); + + // tire repair + $this->testTireRepairWithServiceFee(); + $this->testTireRepairWithNoServiceFee(); - // TEST SCENARIO: new battery with trade in // TEST SCENARIO: new battery with discount // TEST SCENARIO: new battery with discount and trade-in - // TEST SCENARIO: fuel, gas - // TEST SCENARIO: fuel, diesel - // TEST SCENARIO: fuel, gas, with discount return 0; } @@ -69,7 +108,514 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } + + protected function testBatterySalesQuantityNoTradeInNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, more than 1, no trade-in, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $criteria->addEntry($battery, null, 2); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInSameBatteryPremiumNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in same battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'premium', 1); + + $rules = $this->inv_manager->check($criteria); + + error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInSameBatteryMotoliteNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in same battery, motolite, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'motolite', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInSameBatteryOtherNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in same battery, other, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'other', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInDifferentBatteryPremiumNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'premium', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInDifferentBatteryMotoliteNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'motolite', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInDifferentBatteryOtherNoDiscount() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'other', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testBatterySalesTradeInQuantityNoDiscount() + { + } + + protected function testBatteryReplacementWarranty() + { + // TEST SCENARIO: battery replacement warranty + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_WARRANTY); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $criteria->addEntry($battery, null, 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_WARRANTY . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testFuelGasWithServiceFee() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, gas, service fee + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306614; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testFuelDieselWithServiceFee() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, diesel, service fee + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306612; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testFuelGasWithNoServiceFee() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, gas, no service fee + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testFuelDieselWithNoServiceFee() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, diesel, no service fee + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306599; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testJumpstart() + { + // TEST SCENARIO: jumpstart + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::JUMPSTART_TROUBLESHOOT . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testJumpstartWarranty() + { + // TEST SCENARIO: jumpstart warranty + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::JUMPSTART_WARRANTY); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::JUMPSTART_WARRANTY . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testOverheatAssistanceWithCoolant() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: overheat assistance with coolant + $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); + + // set customer vehicle + $cv_id = 1306614; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + $criteria->setHasCoolant(); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::OVERHEAT_ASSISTANCE . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testOverheatAssistanceWithoutCoolant() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: overheat assistance with coolant + $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); + + // set customer vehicle + $cv_id = 1306614; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::OVERHEAT_ASSISTANCE . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testPostRecharged() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: post recharged + $criteria->setServiceType(ServiceType::POST_RECHARGED); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::POST_RECHARGED . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testPostReplacement() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: post replacement + $criteria->setServiceType(ServiceType::POST_REPLACEMENT); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::POST_REPLACEMENT . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testTireRepairWithServiceFee() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: tire repair with service fee + $criteria->setServiceType(ServiceType::TIRE_REPAIR); + + // set customer vehicle + $cv_id = 1306612; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::TIRE_REPAIR . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + + protected function testTireRepairWithNoServiceFee() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: tire repair no service fee + $criteria->setServiceType(ServiceType::TIRE_REPAIR); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . ServiceType::TIRE_REPAIR . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + } diff --git a/src/Invoice/Fuel.php b/src/Invoice/Fuel.php index ad0680a1..6c892615 100644 --- a/src/Invoice/Fuel.php +++ b/src/Invoice/Fuel.php @@ -5,6 +5,7 @@ namespace App\Invoice; use App\InvoiceInterface; use App\Ramcar\FuelType; +use App\Ramcar\ServiceType; class Fuel implements InvoiceInterface { @@ -41,17 +42,17 @@ class Fuel implements InvoiceInterface else $fee = $stype_fees['service_fee']; + $ftype = $cv->getFuelType(); + // add the service fee to items $qty = 1; $items[] = [ 'qty' => $qty, - 'title' => $this->getTitle($ftype), + 'title' => $this->getServiceTitle($ftype), 'price' => $fee, ]; - $ftype = $cv->getFuelType(); - - $stype_fees_id = $this->getID() . '_' . $ftype; + $stype_fees_id = $this->getID() . '_fee_' . $ftype; switch ($ftype) { @@ -83,7 +84,14 @@ class Fuel implements InvoiceInterface protected function getTitle($fuel_type) { - $title = '4L - ' . $fuel_type; + $title = '4L - ' . ucfirst($fuel_type); + + return $title; + } + + protected function getServiceTitle($fuel_type) + { + $title = 'Service - ' . ServiceType::getName(ServiceType::EMERGENCY_REFUEL); return $title; } diff --git a/src/Invoice/Jumpstart.php b/src/Invoice/Jumpstart.php index 84ac7ff6..622e5e3f 100644 --- a/src/Invoice/Jumpstart.php +++ b/src/Invoice/Jumpstart.php @@ -25,6 +25,32 @@ class Jumpstart implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $stype = $criteria->getServiceType(); + + $items = []; + + if ($stype == $this->getID()) + { + $stype_fees_id = $this->getID() . '_fee'; + + $fee = $stype_fees[$stype_fees_id]; + + // add the service fee to items + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceTitle(), + 'price' => $fee, + ]; + } + + return $items; + } + + protected function getServiceTitle() + { + $title = 'Service - Troubleshooting fee'; + + return $title; } } diff --git a/src/Invoice/JumpstartWarranty.php b/src/Invoice/JumpstartWarranty.php index dc322036..ae15170c 100644 --- a/src/Invoice/JumpstartWarranty.php +++ b/src/Invoice/JumpstartWarranty.php @@ -25,7 +25,32 @@ class JumpstartWarranty implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $stype = $criteria->getServiceType(); + + $items = []; + + if ($stype == $this->getID()) + { + $stype_fees_id = $this->getID() . '_fee'; + + $fee = $stype_fees[$stype_fees_id]; + + // add the service fee to items + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceTitle(), + 'price' => $fee, + ]; + } + + return $items; } + protected function getServiceTitle() + { + $title = 'Service - Troubleshooting fee'; + + return $title; + } } diff --git a/src/Invoice/Overheat.php b/src/Invoice/Overheat.php index 5e8e0aae..70b48bc7 100644 --- a/src/Invoice/Overheat.php +++ b/src/Invoice/Overheat.php @@ -4,6 +4,8 @@ namespace App\Invoice; use App\InvoiceInterface; +USE App\Ramcar\ServiceType; + class Overheat implements InvoiceInterface { public function check($criteria) @@ -25,6 +27,53 @@ class Overheat implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $stype = $criteria->getServiceType(); + $has_coolant = $criteria->hasCoolant(); + + $items = []; + + if ($stype == $this->getID()) + { + // check if customer vehicle has a motolite battery + $cv = $criteria->getCustomerVehicle(); + if ($cv->hasMotoliteBattery()) + $fee = 0; + else + $fee = $stype_fees['service_fee']; + + // add the service fee to items + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceTitle(), + 'price' => $fee, + ]; + + if ($has_coolant) + { + $coolant_fee = $stype_fees['coolant_fee']; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceCoolantTitle(), + 'price' => $coolant_fee, + ]; + } + } + + return $items; + } + + protected function getServiceTitle() + { + $title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE) . ' Assistance' ; + + return $title; + } + + protected function getServiceCoolantTitle() + { + $title = '4L Coolant'; + + return $title; } } diff --git a/src/Invoice/PostRecharged.php b/src/Invoice/PostRecharged.php index 546736fd..d974798a 100644 --- a/src/Invoice/PostRecharged.php +++ b/src/Invoice/PostRecharged.php @@ -25,6 +25,30 @@ class PostRecharged implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $stype = $criteria->getServiceType(); + + $items = []; + + if ($stype == $this->getID()) + { + $fee = $stype_fees[$this->getID() . '_fee']; + + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceTitle(), + 'price' => $fee, + ]; + + } + + return $items; + } + + protected function getServiceTitle() + { + $title = 'Recharge fee'; + + return $title; } } diff --git a/src/Invoice/PostReplacement.php b/src/Invoice/PostReplacement.php index 3d891ffb..76316d49 100644 --- a/src/Invoice/PostReplacement.php +++ b/src/Invoice/PostReplacement.php @@ -25,6 +25,30 @@ class PostReplacement implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $stype = $criteria->getServiceType(); + + $items = []; + + if ($stype == $this->getID()) + { + $fee = $stype_fees['battery_replacement_fee']; + + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceTitle(), + 'price' => $fee, + ]; + + } + + return $items; + } + + protected function getServiceTitle() + { + $title = 'Battery replacement'; + + return $title; } } diff --git a/src/Invoice/TireRepair.php b/src/Invoice/TireRepair.php index 3a903bab..1d019ebf 100644 --- a/src/Invoice/TireRepair.php +++ b/src/Invoice/TireRepair.php @@ -25,7 +25,35 @@ class TireRepair implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $stype = $criteria->getServiceType(); + + $items = []; + + if ($stype == $this->getID()) + { + // check if customer vehicle has a motolite battery + $cv = $criteria->getCustomerVehicle(); + if ($cv->hasMotoliteBattery()) + $fee = 0; + else + $fee = $stype_fees['service_fee']; + + // add the service fee to items + $qty = 1; + $items[] = [ + 'qty' => $qty, + 'title' => $this->getServiceTitle(), + 'price' => $fee, + ]; + } + + return $items; } + protected function getServiceTitle() + { + $title = 'Service - Flat Tire'; + + return $title; + } } diff --git a/src/Invoice/TradeIn.php b/src/Invoice/TradeIn.php index ffb1ffc9..7e3fd2c1 100644 --- a/src/Invoice/TradeIn.php +++ b/src/Invoice/TradeIn.php @@ -4,6 +4,8 @@ namespace App\Invoice; use App\InvoiceInterface; +use App\Ramcar\TradeInType; + class TradeIn implements InvoiceInterface { public function check($criteria) @@ -13,7 +15,7 @@ class TradeIn implements InvoiceInterface foreach($entries as $entry) { - if ($this->getID() == $entry['trade_in']) + if ($entry['trade_in']) { // just need to find one trade-in entry return true; @@ -33,9 +35,60 @@ class TradeIn implements InvoiceInterface return 'trade_in'; } - public function compute($criteria, $stype_fees) + public function compute($criteria) { - return []; + $items = []; + + // get the entries + $entries = $criteria->getEntries(); + foreach($entries as $entry) + { + $batt = $entry['battery']; + $qty = $entry['qty']; + $trade_in_type = null; + + if (isset($entry['trade_in'])) + $trade_in_type = $entry['trade_in']; + + if ($trade_in_type != null) + { + $ti_rate = $this->getTradeInRate($batt, $trade_in_type); + + $price = bcmul($ti_rate, -1, 2); + + $items[] = [ + 'qty' => $qty, + 'title' => $this->getTitle($batt, $trade_in_type), + 'price' => $price, + ]; + } + } + + return $items; + } + + protected function getTradeInRate($battery, $trade_in_type) + { + $size = $battery->getSize(); + + switch ($trade_in_type) + { + case TradeInType::MOTOLITE: + return $size->getTIPriceMotolite(); + case TradeInType::PREMIUM: + return $size->getTIPricePremium(); + case TradeInType::OTHER: + return $size->getTIPriceOther(); + } + + return 0; + } + + protected function getTitle($battery, $trade_in_type) + { + $title = 'Trade-in ' . TradeInType::getName($trade_in_type) . ' ' . $battery->getSize()->getName() . ' battery'; + + return $title; } } diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index bfbaa7eb..f1db5a73 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -52,8 +52,8 @@ class InvoiceManager return [ 'service_fee' => 300, 'coolant_fee' => 1600, - 'recharge_fee' => 300, - 'jumpstart_fee' => 150, + 'post_recharged_fee' => 300, + 'jumpstart_troubleshoot_fee' => 150, 'jumpstart_warranty_fee' => 0, 'battery_replacement_fee' => 0, 'battery_warranty_fee' => 0, @@ -116,24 +116,22 @@ class InvoiceManager $computed_items = $active_rule->compute($criteria, $stype_fees); foreach ($computed_items as $computed_item) { - $items[] = $computed_item; + if (!empty($computed_item)) + $items[] = $computed_item; } foreach ($items as $item) { - if (isset($item['title'])) - { - $invoice_item = new InvoiceItem(); + $invoice_item = new InvoiceItem(); - $invoice_item->setTitle($item['title']) - ->setQuantity($item['qty']) - ->setPrice($item['price']); + $invoice_item->setTitle($item['title']) + ->setQuantity($item['qty']) + ->setPrice($item['price']); - if (isset($item['battery'])) - $invoice_item->setBattery($item['battery']); + if (isset($item['battery'])) + $invoice_item->setBattery($item['battery']); - $invoice_items[] = $invoice_item; - } + $invoice_items[] = $invoice_item; } } } From f598e4f4261e6bf614339f1289a14979f7f762a8 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 30 May 2023 05:54:16 -0400 Subject: [PATCH 07/25] Add tax rule. #744 --- src/Command/TestInvoiceManagerCommand.php | 71 ++++++++++++++------ src/Invoice/BatterySales.php | 1 + src/Invoice/DiscountType.php | 23 ++++++- src/Invoice/Tax.php | 82 +++++++++++++++++++++++ src/Invoice/TradeIn.php | 2 +- src/Service/InvoiceManager.php | 60 ++++++++++++++--- 6 files changed, 204 insertions(+), 35 deletions(-) create mode 100644 src/Invoice/Tax.php diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 68051147..485bbacd 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -108,7 +108,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -132,7 +132,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -154,13 +154,13 @@ class TestInvoiceManagerCommand extends Command $rules = $this->inv_manager->check($criteria); - error_log(print_r($rules, true)); + // error_log(print_r($rules, true)); $invoice_items = $this->inv_manager->compute($criteria, $rules); foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -188,7 +188,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -216,7 +216,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -247,7 +247,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -278,7 +278,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -309,12 +309,39 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_NEW . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } protected function testBatterySalesTradeInQuantityNoDiscount() { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'other', 3); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_items = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } } protected function testBatteryReplacementWarranty() @@ -337,7 +364,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::BATTERY_REPLACEMENT_WARRANTY . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -362,7 +389,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -387,7 +414,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -412,7 +439,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -437,7 +464,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::EMERGENCY_REFUEL . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -456,7 +483,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::JUMPSTART_TROUBLESHOOT . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -475,7 +502,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::JUMPSTART_WARRANTY . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -501,7 +528,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::OVERHEAT_ASSISTANCE . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -526,7 +553,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::OVERHEAT_ASSISTANCE . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -545,7 +572,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::POST_RECHARGED . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -564,7 +591,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::POST_REPLACEMENT . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -589,7 +616,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::TIRE_REPAIR . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } @@ -614,7 +641,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . ServiceType::TIRE_REPAIR . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } diff --git a/src/Invoice/BatterySales.php b/src/Invoice/BatterySales.php index d102f950..40d77b9e 100644 --- a/src/Invoice/BatterySales.php +++ b/src/Invoice/BatterySales.php @@ -50,6 +50,7 @@ class BatterySales implements InvoiceInterface $price = $batt->getSellingPrice(); $items[] = [ + 'service_type' => $this->getID(), 'battery' => $batt, 'qty' => $qty, 'title' => $this->getTitle($batt), diff --git a/src/Invoice/DiscountType.php b/src/Invoice/DiscountType.php index 6ce07355..31a6e835 100644 --- a/src/Invoice/DiscountType.php +++ b/src/Invoice/DiscountType.php @@ -27,7 +27,28 @@ class DiscountType implements InvoiceInterface public function compute($criteria, $stype_fees) { - return []; + $items = []; + + $promos = $criteria->getPromos(); + + // NOTE: only get first promo because only one is applicable anyway + $promo = $promos[0]; + + $rate = $promo->getDiscountRate(); + $apply_to = $promo->getDiscountApply(); + + switch ($apply_to) + { + case DiscountApply::SRP: + $discount = round($total['sell_price'] * $rate, 2); + break; + case DiscountApply::OPL: + // $discount = round($total['sell_price'] * 0.6 / 0.7 * $rate, 2); + $discount = round($total['sell_price'] * (1 - 1.5 / 0.7 * $rate), 2); + break; + } + + return $items; } } diff --git a/src/Invoice/Tax.php b/src/Invoice/Tax.php new file mode 100644 index 00000000..2044840a --- /dev/null +++ b/src/Invoice/Tax.php @@ -0,0 +1,82 @@ +isTaxable())) + return true; + + return false; + + } + + public function getTemplate() + { + return 'invoice/tax.html.twig'; + } + + public function getID() + { + return 'tax'; + } + + public function compute($items, &$total) + { + foreach ($items as $item) + { + $price = $item['price']; + $qty = $item['qty']; + + if (isset($items['service_type'])) + { + if ($items['service_type'] == 'battery_new') + { + // battery purchase + if (isset($item['battery'])) + { + // battery purchase + $vat = $this->getTaxAmount($price); + + $qty_price = bcmul($price, $qty, 2); + $price_minus_vat = bcsub($price, $vat, 2); + $qty_price_minus_vat = bcmul($price_minus_vat, $qty, 2); + + $total['sell_price'] = bcadd($total['sell_price'], $qty_price, 2); + $total['vat'] = bcadd($total['vat'], $qty_price, 2); + $total['vat_ex_price'] = bcadd($total['vat_ex_price'], $qty_price_minus_vat, 2); + + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); + } + } + + } + else + { + // everything else + } + } + } + + protected function getTaxAmount($price) + { + $vat_ex_price = $this->getTaxExclusivePrice($price); + $tax_amount = bcsub($price, $vat_ex_price, 2); + + return $tax_amount; + } + + protected function getTaxExclusivePrice($price) + { + $tax_ex_price = bcdiv($price, bcadd(1, self::TAX_RATE, 2), 2); + return $tax_ex_price; + } + +} + diff --git a/src/Invoice/TradeIn.php b/src/Invoice/TradeIn.php index 7e3fd2c1..95d545c8 100644 --- a/src/Invoice/TradeIn.php +++ b/src/Invoice/TradeIn.php @@ -35,7 +35,7 @@ class TradeIn implements InvoiceInterface return 'trade_in'; } - public function compute($criteria) + public function compute($criteria, $stype_fees) { $items = []; diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index f1db5a73..240e850f 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -44,6 +44,7 @@ class InvoiceManager new Invoice\TireRepair(), new Invoice\DiscountType(), new Invoice\TradeIn(), + new Invoice\Tax, ]; } @@ -80,9 +81,21 @@ class InvoiceManager 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(); @@ -102,22 +115,36 @@ class InvoiceManager if ($id == $stype) { $items = []; - // process trade-ins by calling the trade-in rule if there are trade-ins - // since it's lumped with only the battery_new service type - if ($flag_trade_in) - { - $tradein_items = $active_rules['trade_in']->compute($criteria); - foreach ($tradein_items as $tradein_item) - { - $items[] = $tradein_item; - } - } $computed_items = $active_rule->compute($criteria, $stype_fees); foreach ($computed_items as $computed_item) { if (!empty($computed_item)) + { $items[] = $computed_item; + } + } + + // check if tax is needed + if ($is_taxable) + { + if (isset($active_rules['tax'])) + { + $active_rule['tax']->compute($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); + foreach ($tradein_items as $tradein_item) + { + $items[] = $tradein_item; + } + } } foreach ($items as $item) @@ -132,10 +159,21 @@ class InvoiceManager $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); + } + } + } } return $invoice_items; } + } From 49317188c947feac527b8d5ba4c4d942bbc5c266 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 31 May 2023 03:57:30 -0400 Subject: [PATCH 08/25] Fix issues found during testing of tax computation. #744 --- src/Command/TestInvoiceManagerCommand.php | 371 ++++++++++++++++----- src/Invoice/BatteryReplacementWarranty.php | 1 + src/Invoice/Fuel.php | 3 + src/Invoice/Jumpstart.php | 1 + src/Invoice/JumpstartWarranty.php | 1 + src/Invoice/Overheat.php | 4 +- src/Invoice/PostRecharged.php | 1 + src/Invoice/PostReplacement.php | 1 + src/Invoice/Tax.php | 51 ++- src/Invoice/TireRepair.php | 1 + src/Invoice/TradeIn.php | 7 +- src/Service/InvoiceManager.php | 38 ++- 12 files changed, 374 insertions(+), 106 deletions(-) diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 485bbacd..f82b8c25 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -81,7 +81,7 @@ class TestInvoiceManagerCommand extends Command // tire repair $this->testTireRepairWithServiceFee(); - $this->testTireRepairWithNoServiceFee(); + $this->testTireRepairWithoutServiceFee(); // TEST SCENARIO: new battery with discount // TEST SCENARIO: new battery with discount and trade-in @@ -99,16 +99,27 @@ class TestInvoiceManagerCommand extends Command $battery = $this->em->getRepository(Battery::class)->find($battery_id); $criteria->addEntry($battery, null, 1); + $criteria->setIsTaxable(); $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -123,16 +134,27 @@ class TestInvoiceManagerCommand extends Command $battery = $this->em->getRepository(Battery::class)->find($battery_id); $criteria->addEntry($battery, null, 2); + $criteria->setIsTaxable(); $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -142,7 +164,7 @@ class TestInvoiceManagerCommand extends Command // TEST SCENARIO: new battery, trade-in same battery, premium, no discount $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); - + $battery_id = 1038; $battery = $this->em->getRepository(Battery::class)->find($battery_id); @@ -151,16 +173,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($battery, 'premium', 1); + $criteria->setIsTaxable(); $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -180,15 +211,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($battery, 'motolite', 1); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -208,15 +249,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($battery, 'other', 1); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -239,15 +290,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($trade_battery, 'premium', 1); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -255,7 +316,7 @@ class TestInvoiceManagerCommand extends Command { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + // TEST SCENARIO: new battery, trade-in different battery, motolite, no discount $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); $battery_id = 1038; @@ -270,15 +331,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($trade_battery, 'motolite', 1); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -286,7 +357,7 @@ class TestInvoiceManagerCommand extends Command { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + // TEST SCENARIO: new battery, trade-in different battery, other, no discount $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); $battery_id = 1038; @@ -301,15 +372,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($trade_battery, 'other', 1); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -332,15 +413,25 @@ class TestInvoiceManagerCommand extends Command // add battery for trade in $criteria->addEntry($trade_battery, 'other', 3); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -356,15 +447,25 @@ class TestInvoiceManagerCommand extends Command $criteria->addEntry($battery, null, 1); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -381,15 +482,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setCustomerVehicle($cv); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -406,15 +517,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setCustomerVehicle($cv); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -431,15 +552,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setCustomerVehicle($cv); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -451,20 +582,30 @@ class TestInvoiceManagerCommand extends Command $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); // set customer vehicle - $cv_id = 1306599; + $cv_id = 1306581; $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); - $criteria->setCustomerVehicle($cv); + $criteria->setCustomerVehicle($cv); + + $criteria->setIsTaxable(); $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -475,15 +616,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); - - foreach ($invoice_items as $invoice_item) - { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -494,15 +645,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setServiceType(ServiceType::JUMPSTART_WARRANTY); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -519,16 +680,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setCustomerVehicle($cv); $criteria->setHasCoolant(); + $criteria->setIsTaxable(); $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -536,7 +706,7 @@ class TestInvoiceManagerCommand extends Command { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: overheat assistance with coolant + // TEST SCENARIO: overheat assistance without coolant $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); // set customer vehicle @@ -544,16 +714,25 @@ class TestInvoiceManagerCommand extends Command $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); $criteria->setCustomerVehicle($cv); + $criteria->setIsTaxable(); $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -564,15 +743,25 @@ class TestInvoiceManagerCommand extends Command // TEST SCENARIO: post recharged $criteria->setServiceType(ServiceType::POST_RECHARGED); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -583,15 +772,25 @@ class TestInvoiceManagerCommand extends Command // TEST SCENARIO: post replacement $criteria->setServiceType(ServiceType::POST_REPLACEMENT); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } @@ -608,19 +807,29 @@ class TestInvoiceManagerCommand extends Command $criteria->setCustomerVehicle($cv); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testTireRepairWithNoServiceFee() + protected function testTireRepairWithoutServiceFee() { $criteria = new InvoiceCriteria(); @@ -633,15 +842,25 @@ class TestInvoiceManagerCommand extends Command $criteria->setCustomerVehicle($cv); + $criteria->setIsTaxable(); + $rules = $this->inv_manager->check($criteria); // error_log(print_r($rules, true)); - $invoice_items = $this->inv_manager->compute($criteria, $rules); + $invoice_data = $this->inv_manager->compute($criteria, $rules); - foreach ($invoice_items as $invoice_item) + foreach ($invoice_data as $data) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); } } diff --git a/src/Invoice/BatteryReplacementWarranty.php b/src/Invoice/BatteryReplacementWarranty.php index e1a1536b..525793f1 100644 --- a/src/Invoice/BatteryReplacementWarranty.php +++ b/src/Invoice/BatteryReplacementWarranty.php @@ -42,6 +42,7 @@ class BatteryReplacementWarranty implements InvoiceInterface $price = $stype_fees[$stype_fee_id]; $items[] = [ + 'service_type' => $this->getID(), 'battery' => $batt, 'qty' => $qty, 'title' => $this->getTitle($batt), diff --git a/src/Invoice/Fuel.php b/src/Invoice/Fuel.php index 6c892615..6cc5e338 100644 --- a/src/Invoice/Fuel.php +++ b/src/Invoice/Fuel.php @@ -47,6 +47,7 @@ class Fuel implements InvoiceInterface // add the service fee to items $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle($ftype), 'price' => $fee, @@ -61,6 +62,7 @@ class Fuel implements InvoiceInterface $qty = 1; $price = $stype_fees[$stype_fees_id]; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getTitle($ftype), 'price' => $price, @@ -71,6 +73,7 @@ class Fuel implements InvoiceInterface $qty = 1; $price = 0; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getTitle('Unknown'), 'price' => $price, diff --git a/src/Invoice/Jumpstart.php b/src/Invoice/Jumpstart.php index 622e5e3f..088bb020 100644 --- a/src/Invoice/Jumpstart.php +++ b/src/Invoice/Jumpstart.php @@ -38,6 +38,7 @@ class Jumpstart implements InvoiceInterface // add the service fee to items $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle(), 'price' => $fee, diff --git a/src/Invoice/JumpstartWarranty.php b/src/Invoice/JumpstartWarranty.php index ae15170c..c4b3192e 100644 --- a/src/Invoice/JumpstartWarranty.php +++ b/src/Invoice/JumpstartWarranty.php @@ -38,6 +38,7 @@ class JumpstartWarranty implements InvoiceInterface // add the service fee to items $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle(), 'price' => $fee, diff --git a/src/Invoice/Overheat.php b/src/Invoice/Overheat.php index 70b48bc7..e05eb657 100644 --- a/src/Invoice/Overheat.php +++ b/src/Invoice/Overheat.php @@ -44,6 +44,7 @@ class Overheat implements InvoiceInterface // add the service fee to items $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle(), 'price' => $fee, @@ -53,6 +54,7 @@ class Overheat implements InvoiceInterface { $coolant_fee = $stype_fees['coolant_fee']; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceCoolantTitle(), 'price' => $coolant_fee, @@ -65,7 +67,7 @@ class Overheat implements InvoiceInterface protected function getServiceTitle() { - $title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE) . ' Assistance' ; + $title = 'Service - ' . ServiceType::getName(ServiceType::OVERHEAT_ASSISTANCE); return $title; } diff --git a/src/Invoice/PostRecharged.php b/src/Invoice/PostRecharged.php index d974798a..84f2f03a 100644 --- a/src/Invoice/PostRecharged.php +++ b/src/Invoice/PostRecharged.php @@ -35,6 +35,7 @@ class PostRecharged implements InvoiceInterface $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle(), 'price' => $fee, diff --git a/src/Invoice/PostReplacement.php b/src/Invoice/PostReplacement.php index 76316d49..014f021f 100644 --- a/src/Invoice/PostReplacement.php +++ b/src/Invoice/PostReplacement.php @@ -35,6 +35,7 @@ class PostReplacement implements InvoiceInterface $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle(), 'price' => $fee, diff --git a/src/Invoice/Tax.php b/src/Invoice/Tax.php index 2044840a..377dc2b6 100644 --- a/src/Invoice/Tax.php +++ b/src/Invoice/Tax.php @@ -6,8 +6,6 @@ use App\InvoiceInterface; class Tax implements InvoiceInterface { - const TAX_RATE = 0.12; - public function check($criteria) { if (!empty($criteria->isTaxable())) @@ -27,54 +25,73 @@ class Tax implements InvoiceInterface return 'tax'; } - public function compute($items, &$total) + 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($items['service_type'])) + if (isset($item['service_type'])) { - if ($items['service_type'] == 'battery_new') + // 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); - + $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['sell_price'] = bcadd($total['sell_price'], $qty_price, 2); - $total['vat'] = bcadd($total['vat'], $qty_price, 2); + $total['vat'] = bcadd($total['vat'], $qty_vat, 2); $total['vat_ex_price'] = bcadd($total['vat_ex_price'], $qty_price_minus_vat, 2); $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } } - - } - else - { - // everything else + else + { + // for all other service types + // add the item price to total_price. we compute VAT from the total price + $total_price = bcadd($total_price, $price, 2); + } } } + + // compute VAT after adding all item costs, if service type is not battery sales + if (!$is_battery_sales) + { + $vat_ex_price = $this->getTaxExclusivePrice($total_price, $tax_rate); + $vat = bcsub($total_price, $vat_ex_price, 2); + + $total['total_price'] = $total_price; + $total['vat_ex_price'] = $vat_ex_price; + $total['vat'] = $vat; + } } - protected function getTaxAmount($price) + protected function getTaxAmount($price, $tax_rate) { - $vat_ex_price = $this->getTaxExclusivePrice($price); + $vat_ex_price = $this->getTaxExclusivePrice($price, $tax_rate); $tax_amount = bcsub($price, $vat_ex_price, 2); return $tax_amount; } - protected function getTaxExclusivePrice($price) + protected function getTaxExclusivePrice($price, $tax_rate) { - $tax_ex_price = bcdiv($price, bcadd(1, self::TAX_RATE, 2), 2); + $tax_ex_price = bcdiv($price, bcadd(1, $tax_rate, 2), 2); return $tax_ex_price; } diff --git a/src/Invoice/TireRepair.php b/src/Invoice/TireRepair.php index 1d019ebf..d4fdcecd 100644 --- a/src/Invoice/TireRepair.php +++ b/src/Invoice/TireRepair.php @@ -41,6 +41,7 @@ class TireRepair implements InvoiceInterface // add the service fee to items $qty = 1; $items[] = [ + 'service_type' => $this->getID(), 'qty' => $qty, 'title' => $this->getServiceTitle(), 'price' => $fee, diff --git a/src/Invoice/TradeIn.php b/src/Invoice/TradeIn.php index 95d545c8..0842fd92 100644 --- a/src/Invoice/TradeIn.php +++ b/src/Invoice/TradeIn.php @@ -35,7 +35,7 @@ class TradeIn implements InvoiceInterface return 'trade_in'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $items = []; @@ -54,6 +54,11 @@ class TradeIn implements InvoiceInterface { $ti_rate = $this->getTradeInRate($batt, $trade_in_type); + $qty_ti = bcmul($ti_rate, $qty, 2); + + $total['ti_rate'] = bcadd($total['ti_rate'], $qty_ti, 2); + $total['total_price'] = bcsub($total['total_price'], $qty_ti, 2); + $price = bcmul($ti_rate, -1, 2); $items[] = [ diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 240e850f..a6503d7b 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -64,6 +64,11 @@ class InvoiceManager ]; } + public function getTaxRate() + { + return 0.12; + } + // check what rules to use given the criteria public function check($criteria) { @@ -110,8 +115,11 @@ class InvoiceManager } $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 = []; @@ -125,21 +133,12 @@ class InvoiceManager } } - // check if tax is needed - if ($is_taxable) - { - if (isset($active_rules['tax'])) - { - $active_rule['tax']->compute($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); + $tradein_items = $active_rules['trade_in']->compute($criteria, $stype_fees, $total); foreach ($tradein_items as $tradein_item) { $items[] = $tradein_item; @@ -147,6 +146,17 @@ class InvoiceManager } } + // 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(); @@ -169,11 +179,17 @@ class InvoiceManager $discount_items = $active_rules['discount_type']->compute($criteria, $stype_fees); } } + + // also need to return the total + $data[] = [ + 'invoice_items' => $invoice_items, + 'total' => $total, + ]; } } - return $invoice_items; + return $data; } } From 725704e9515b7590b4e294eb5aee4b25a47a840c Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 31 May 2023 06:09:54 -0400 Subject: [PATCH 09/25] Add test cases for no tax. Fix issues found when computing the total if no tax. #744 --- src/Command/TestInvoiceManagerCommand.php | 986 +++++++++++++++++++-- src/Invoice/BatteryReplacementWarranty.php | 5 +- src/Invoice/BatterySales.php | 7 +- src/Invoice/DiscountType.php | 4 +- src/Invoice/Fuel.php | 15 +- src/Invoice/Jumpstart.php | 5 +- src/Invoice/JumpstartWarranty.php | 5 +- src/Invoice/Overheat.php | 10 +- src/Invoice/PostRecharged.php | 5 +- src/Invoice/PostReplacement.php | 4 +- src/Invoice/Tax.php | 12 +- src/Invoice/TireRepair.php | 5 +- src/Service/InvoiceManager.php | 34 +- 13 files changed, 967 insertions(+), 130 deletions(-) diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index f82b8c25..7feafcb9 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -39,60 +39,104 @@ class TestInvoiceManagerCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { - // battery sales - $this->testBatterySalesNoTradeInNoDiscount(); - $this->testBatterySalesQuantityNoTradeInNoDiscount(); + // battery sales with tax + $this->testBatterySalesNoTradeInNoDiscountWithTax(); + $this->testBatterySalesQuantityNoTradeInNoDiscountWithTax(); - // battery sales with trade in - $this->testBatterySalesTradeInSameBatteryPremiumNoDiscount(); - $this->testBatterySalesTradeInSameBatteryMotoliteNoDiscount(); - $this->testBatterySalesTradeInSameBatteryOtherNoDiscount(); - $this->testBatterySalesTradeInDifferentBatteryPremiumNoDiscount(); - $this->testBatterySalesTradeInDifferentBatteryMotoliteNoDiscount(); - $this->testBatterySalesTradeInDifferentBatteryOtherNoDiscount(); - $this->testBatterySalesTradeInQuantityNoDiscount(); + // battery sales without tax + $this->testBatterySalesNoTradeInNoDiscountWithoutTax(); + $this->testBatterySalesQuantityNoTradeInNoDiscountWithoutTax(); - // battery sales with discount + // battery sales with trade in with tax + $this->testBatterySalesTradeInSameBatteryPremiumNoDiscountWithTax(); + $this->testBatterySalesTradeInSameBatteryMotoliteNoDiscountWithTax(); + $this->testBatterySalesTradeInSameBatteryOtherNoDiscountWithTax(); + $this->testBatterySalesTradeInDifferentBatteryPremiumNoDiscountWithTax(); + $this->testBatterySalesTradeInDifferentBatteryMotoliteNoDiscountWithTax(); + $this->testBatterySalesTradeInDifferentBatteryOtherNoDiscountWithTax(); + $this->testBatterySalesTradeInQuantityNoDiscountWithTax(); - // battery replacement warranty - $this->testBatteryReplacementWarranty(); + // battery sales with trade in without tax + $this->testBatterySalesTradeInSameBatteryPremiumNoDiscountWithoutTax(); + $this->testBatterySalesTradeInSameBatteryMotoliteNoDiscountWithoutTax(); + $this->testBatterySalesTradeInSameBatteryOtherNoDiscountWithoutTax(); + $this->testBatterySalesTradeInDifferentBatteryPremiumNoDiscountWithoutTax(); + $this->testBatterySalesTradeInDifferentBatteryMotoliteNoDiscountWithoutTax(); + $this->testBatterySalesTradeInDifferentBatteryOtherNoDiscountWithoutTax(); + $this->testBatterySalesTradeInQuantityNoDiscountWithoutTax(); - // fuel - $this->testFuelGasWithServiceFee(); - $this->testFuelDieselWithServiceFee(); - $this->testFuelGasWithNoServiceFee(); - $this->testFuelDieselWithNoServiceFee(); + // battery sales with discount with tax + // battery sales with discount without tax - // jumpstart - $this->testJumpstart(); + // battery replacement warranty with tax + $this->testBatteryReplacementWarrantyWithTax(); - // jumpstart warranty - $this->testJumpstartWarranty(); + // battery replacement warranty without tax + $this->testBatteryReplacementWarrantyWithoutTax(); - // overheat - $this->testOverheatAssistanceWithCoolant(); - $this->testOverheatAssistanceWithoutCoolant(); + // fuel with tax + $this->testFuelGasWithServiceFeeWithTax(); + $this->testFuelDieselWithServiceFeeWithTax(); + $this->testFuelGasWithNoServiceFeeWithTax(); + $this->testFuelDieselWithNoServiceFeeWithTax(); - // post-recharged - $this->testPostRecharged(); + // fuel without tax + $this->testFuelGasWithServiceFeeWithoutTax(); + $this->testFuelDieselWithServiceFeeWithoutTax(); + $this->testFuelGasWithNoServiceFeeWithoutTax(); + $this->testFuelDieselWithNoServiceFeeWithoutTax(); - // post replacement - $this->testPostReplacement(); + // jumpstart with tax + $this->testJumpstartWithTax(); - // tire repair - $this->testTireRepairWithServiceFee(); - $this->testTireRepairWithoutServiceFee(); + // jumpstart without tax + $this->testJumpstartWithoutTax(); + + // jumpstart warranty with tax + $this->testJumpstartWarrantyWithTax(); + + // jumpstart warranty without tax + $this->testJumpstartWarrantyWithoutTax(); + + // overheat with tax + $this->testOverheatAssistanceWithCoolantWithTax(); + $this->testOverheatAssistanceWithoutCoolantWithTax(); + + // overheat without tax + $this->testOverheatAssistanceWithCoolantWithoutTax(); + $this->testOverheatAssistanceWithoutCoolantWithoutTax(); + + // post-recharged with tax + $this->testPostRechargedWithTax(); + + // post-recharged without tax + $this->testPostRechargedWithoutTax(); + + // post replacement with tax + $this->testPostReplacementWithTax(); + + // post replacement without tax + $this->testPostReplacementWithoutTax(); + + // tire repair with tax + $this->testTireRepairWithServiceFeeWithTax(); + $this->testTireRepairWithoutServiceFeeWithTax(); + + // tire repair without tax + $this->testTireRepairWithServiceFeeWithoutTax(); + $this->testTireRepairWithoutServiceFeeWithoutTax(); // TEST SCENARIO: new battery with discount // TEST SCENARIO: new battery with discount and trade-in return 0; } - protected function testBatterySalesNoTradeInNoDiscount() + // 1battery sales with tax + protected function testBatterySalesNoTradeInNoDiscountWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: new battery, no trade-in, no discount + // TEST SCENARIO: new battery, no trade-in, no discount, with tax $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); $battery_id = 1038; @@ -116,18 +160,18 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesQuantityNoTradeInNoDiscount() + protected function testBatterySalesQuantityNoTradeInNoDiscountWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: new battery, more than 1, no trade-in, no discount + // TEST SCENARIO: new battery, more than 1, no trade-in, no discount, with tax $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); $battery_id = 1038; @@ -151,14 +195,84 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInSameBatteryPremiumNoDiscount() + // battery sales without tax + protected function testBatterySalesNoTradeInNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, no trade-in, no discount, no tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $criteria->addEntry($battery, null, 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesQuantityNoTradeInNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, more than 1, no trade-in, no discount, without tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $criteria->addEntry($battery, null, 2); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // battery sales with trade in with tax + protected function testBatterySalesTradeInSameBatteryPremiumNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -188,14 +302,14 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInSameBatteryMotoliteNoDiscount() + protected function testBatterySalesTradeInSameBatteryMotoliteNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -226,14 +340,14 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInSameBatteryOtherNoDiscount() + protected function testBatterySalesTradeInSameBatteryOtherNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -264,14 +378,14 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInDifferentBatteryPremiumNoDiscount() + protected function testBatterySalesTradeInDifferentBatteryPremiumNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -305,14 +419,14 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInDifferentBatteryMotoliteNoDiscount() + protected function testBatterySalesTradeInDifferentBatteryMotoliteNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -346,14 +460,14 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInDifferentBatteryOtherNoDiscount() + protected function testBatterySalesTradeInDifferentBatteryOtherNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -387,14 +501,14 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatterySalesTradeInQuantityNoDiscount() + protected function testBatterySalesTradeInQuantityNoDiscountWithTax() { $criteria = new InvoiceCriteria(); @@ -428,16 +542,282 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testBatteryReplacementWarranty() + // start: battery sales with trade in without tax + protected function testBatterySalesTradeInSameBatteryPremiumNoDiscountWithoutTax() { - // TEST SCENARIO: battery replacement warranty + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in same battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'premium', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInSameBatteryMotoliteNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in same battery, motolite, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'motolite', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInSameBatteryOtherNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in same battery, other, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'other', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInDifferentBatteryPremiumNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'premium', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInDifferentBatteryMotoliteNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, motolite, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'motolite', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInDifferentBatteryOtherNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, other, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'other', 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInQuantityNoDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, no discount + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'other', 3); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // battery replacement warranty with tax + protected function testBatteryReplacementWarrantyWithTax() + { + // TEST SCENARIO: battery replacement warranty with tax $criteria = new InvoiceCriteria(); $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_WARRANTY); @@ -462,18 +842,52 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testFuelGasWithServiceFee() + // battery replacement warranty without tax + protected function testBatteryReplacementWarrantyWithoutTax() + { + // TEST SCENARIO: battery replacement warranty without tax + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_WARRANTY); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $criteria->addEntry($battery, null, 1); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // fuel with tax + protected function testFuelGasWithServiceFeeWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: fuel, gas, service fee + // TEST SCENARIO: fuel, gas, service fee, with tax $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); // set customer vehicle @@ -497,18 +911,18 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testFuelDieselWithServiceFee() + protected function testFuelDieselWithServiceFeeWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: fuel, diesel, service fee + // TEST SCENARIO: fuel, diesel, service fee, with tax $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); // set customer vehicle @@ -532,18 +946,18 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testFuelGasWithNoServiceFee() + protected function testFuelGasWithNoServiceFeeWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: fuel, gas, no service fee + // TEST SCENARIO: fuel, gas, no service fee, with tax $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); // set customer vehicle @@ -567,18 +981,18 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testFuelDieselWithNoServiceFee() + protected function testFuelDieselWithNoServiceFeeWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: fuel, diesel, no service fee + // TEST SCENARIO: fuel, diesel, no service fee, with tax $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); // set customer vehicle @@ -602,16 +1016,150 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testJumpstart() + // fuel without tax + protected function testFuelGasWithServiceFeeWithoutTax() { - // TEST SCENARIO: jumpstart + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, gas, service fee, without tax + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306614; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testFuelDieselWithServiceFeeWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, diesel, service fee, without tax + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306612; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testFuelGasWithNoServiceFeeWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, gas, no service fee, without tax + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testFuelDieselWithNoServiceFeeWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: fuel, diesel, no service fee, without tax + $criteria->setServiceType(ServiceType::EMERGENCY_REFUEL); + + // set customer vehicle + $cv_id = 1306581; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // jumpstart with tax + protected function testJumpstartWithTax() + { + // TEST SCENARIO: jumpstart with tax $criteria = new InvoiceCriteria(); $criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT); @@ -631,16 +1179,45 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testJumpstartWarranty() + // jumpstart without tax + protected function testJumpstartWithoutTax() { - // TEST SCENARIO: jumpstart warranty + // TEST SCENARIO: jumpstart without tax + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // jumpstart warranty with tax + protected function testJumpstartWarrantyWithTax() + { + // TEST SCENARIO: jumpstart warranty with tax $criteria = new InvoiceCriteria(); $criteria->setServiceType(ServiceType::JUMPSTART_WARRANTY); @@ -660,18 +1237,47 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testOverheatAssistanceWithCoolant() + // jumpstart warranty without tax + protected function testJumpstartWarrantyWithoutTax() + { + // TEST SCENARIO: jumpstart warranty without tax + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::JUMPSTART_WARRANTY); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // overheat assistance with tax + protected function testOverheatAssistanceWithCoolantWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: overheat assistance with coolant + // TEST SCENARIO: overheat assistance with coolant with tax $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); // set customer vehicle @@ -695,18 +1301,18 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testOverheatAssistanceWithoutCoolant() + protected function testOverheatAssistanceWithoutCoolantWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: overheat assistance without coolant + // TEST SCENARIO: overheat assistance without coolant with tax $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); // set customer vehicle @@ -729,18 +1335,87 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testPostRecharged() + // overheat assistance without tax + protected function testOverheatAssistanceWithCoolantWithoutTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: post recharged + // TEST SCENARIO: overheat assistance with coolant without tax + $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); + + // set customer vehicle + $cv_id = 1306614; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + $criteria->setHasCoolant(); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testOverheatAssistanceWithoutCoolantWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: overheat assistance without coolant without tax + $criteria->setServiceType(ServiceType::OVERHEAT_ASSISTANCE); + + // set customer vehicle + $cv_id = 1306614; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // post recharged with tax + protected function testPostRechargedWithTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: post recharged with tax $criteria->setServiceType(ServiceType::POST_RECHARGED); $criteria->setIsTaxable(); @@ -758,18 +1433,47 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testPostReplacement() + // post recharged without tax + protected function testPostRechargedWithoutTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: post replacement + // TEST SCENARIO: post recharged with tax + $criteria->setServiceType(ServiceType::POST_RECHARGED); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // post replacement with tax + protected function testPostReplacementWithTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: post replacement with tax $criteria->setServiceType(ServiceType::POST_REPLACEMENT); $criteria->setIsTaxable(); @@ -787,18 +1491,49 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testTireRepairWithServiceFee() + // post replacement without tax + protected function testPostReplacementWithoutTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: tire repair with service fee + // TEST SCENARIO: post replacement without tax + $criteria->setServiceType(ServiceType::POST_REPLACEMENT); + + $criteria->setIsTaxable(); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // tire repair with tax + protected function testTireRepairWithServiceFeeWithTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: tire repair with service fee with tax $criteria->setServiceType(ServiceType::TIRE_REPAIR); // set customer vehicle @@ -822,18 +1557,18 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } - protected function testTireRepairWithoutServiceFee() + protected function testTireRepairWithoutServiceFeeWithTax() { $criteria = new InvoiceCriteria(); - // TEST SCENARIO: tire repair no service fee + // TEST SCENARIO: tire repair no service fee with tax $criteria->setServiceType(ServiceType::TIRE_REPAIR); // set customer vehicle @@ -857,11 +1592,78 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } error_log('TOTAL ' . print_r(json_encode($total), true)); } } + // tire repair without tax + protected function testTireRepairWithServiceFeeWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: tire repair with service fee without tax + $criteria->setServiceType(ServiceType::TIRE_REPAIR); + + // set customer vehicle + $cv_id = 1306612; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testTireRepairWithoutServiceFeeWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: tire repair no service fee without tax + $criteria->setServiceType(ServiceType::TIRE_REPAIR); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $criteria->setCustomerVehicle($cv); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + } diff --git a/src/Invoice/BatteryReplacementWarranty.php b/src/Invoice/BatteryReplacementWarranty.php index 525793f1..108016ac 100644 --- a/src/Invoice/BatteryReplacementWarranty.php +++ b/src/Invoice/BatteryReplacementWarranty.php @@ -24,7 +24,7 @@ class BatteryReplacementWarranty implements InvoiceInterface return 'battery_warranty'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -48,6 +48,9 @@ class BatteryReplacementWarranty implements InvoiceInterface 'title' => $this->getTitle($batt), 'price' => $price, ]; + + $qty_price = bcmul($price, $qty, 2); + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } } diff --git a/src/Invoice/BatterySales.php b/src/Invoice/BatterySales.php index 40d77b9e..e1b94282 100644 --- a/src/Invoice/BatterySales.php +++ b/src/Invoice/BatterySales.php @@ -24,7 +24,7 @@ class BatterySales implements InvoiceInterface return 'battery_new'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -56,6 +56,11 @@ class BatterySales implements InvoiceInterface '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); } } } diff --git a/src/Invoice/DiscountType.php b/src/Invoice/DiscountType.php index 31a6e835..a1bea802 100644 --- a/src/Invoice/DiscountType.php +++ b/src/Invoice/DiscountType.php @@ -4,6 +4,8 @@ namespace App\Invoice; use App\InvoiceInterface; +use App\Ramcar\DiscountApply; + class DiscountType implements InvoiceInterface { public function check($criteria) @@ -25,7 +27,7 @@ class DiscountType implements InvoiceInterface return 'discount_type'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $items = []; diff --git a/src/Invoice/Fuel.php b/src/Invoice/Fuel.php index 6cc5e338..2cc8bbeb 100644 --- a/src/Invoice/Fuel.php +++ b/src/Invoice/Fuel.php @@ -26,12 +26,11 @@ class Fuel implements InvoiceInterface return 'fuel'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); $items = []; - if ($stype == $this->getID()) { @@ -52,6 +51,9 @@ class Fuel implements InvoiceInterface 'title' => $this->getServiceTitle($ftype), 'price' => $fee, ]; + + $qty_fee = bcmul($qty, $fee, 2); + $total_price = $qty_fee; $stype_fees_id = $this->getID() . '_fee_' . $ftype; @@ -68,6 +70,9 @@ class Fuel implements InvoiceInterface 'price' => $price, ]; + $qty_price = bcmul($price, $qty, 2); + $total_price = bcadd($total_price, $qty_price, 2); + break; default: $qty = 1; @@ -78,8 +83,14 @@ class Fuel implements InvoiceInterface 'title' => $this->getTitle('Unknown'), 'price' => $price, ]; + + $qty_price = bcmul($price, $qty, 2); + $total_price = bcadd($total_price, $qty_price, 2); + break; } + + $total['total_price'] = bcadd($total['total_price'], $total_price, 2); } return $items; diff --git a/src/Invoice/Jumpstart.php b/src/Invoice/Jumpstart.php index 088bb020..747c1217 100644 --- a/src/Invoice/Jumpstart.php +++ b/src/Invoice/Jumpstart.php @@ -23,7 +23,7 @@ class Jumpstart implements InvoiceInterface return 'jumpstart_troubleshoot'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -43,6 +43,9 @@ class Jumpstart implements InvoiceInterface 'title' => $this->getServiceTitle(), 'price' => $fee, ]; + + $qty_price = bcmul($fee, $qty, 2); + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } return $items; diff --git a/src/Invoice/JumpstartWarranty.php b/src/Invoice/JumpstartWarranty.php index c4b3192e..634e79b8 100644 --- a/src/Invoice/JumpstartWarranty.php +++ b/src/Invoice/JumpstartWarranty.php @@ -23,7 +23,7 @@ class JumpstartWarranty implements InvoiceInterface return 'jumpstart_warranty'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -43,6 +43,9 @@ class JumpstartWarranty implements InvoiceInterface 'title' => $this->getServiceTitle(), 'price' => $fee, ]; + + $qty_price = bcmul($fee, $qty, 2); + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } return $items; diff --git a/src/Invoice/Overheat.php b/src/Invoice/Overheat.php index e05eb657..4700b9b2 100644 --- a/src/Invoice/Overheat.php +++ b/src/Invoice/Overheat.php @@ -25,7 +25,7 @@ class Overheat implements InvoiceInterface return 'overheat'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); $has_coolant = $criteria->hasCoolant(); @@ -50,6 +50,9 @@ class Overheat implements InvoiceInterface 'price' => $fee, ]; + $qty_fee = bcmul($qty, $fee, 2); + $total_price = $qty_fee; + if ($has_coolant) { $coolant_fee = $stype_fees['coolant_fee']; @@ -59,7 +62,12 @@ class Overheat implements InvoiceInterface 'title' => $this->getServiceCoolantTitle(), 'price' => $coolant_fee, ]; + + $qty_price = bcmul($coolant_fee, $qty, 2); + $total_price = bcadd($total_price, $qty_price, 2); } + + $total['total_price'] = bcadd($total['total_price'], $total_price, 2); } return $items; diff --git a/src/Invoice/PostRecharged.php b/src/Invoice/PostRecharged.php index 84f2f03a..9984e6a2 100644 --- a/src/Invoice/PostRecharged.php +++ b/src/Invoice/PostRecharged.php @@ -23,7 +23,7 @@ class PostRecharged implements InvoiceInterface return 'post_recharged'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -41,6 +41,9 @@ class PostRecharged implements InvoiceInterface 'price' => $fee, ]; + $qty_price = bcmul($fee, $qty, 2); + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); + } return $items; diff --git a/src/Invoice/PostReplacement.php b/src/Invoice/PostReplacement.php index 014f021f..5d5ec7ba 100644 --- a/src/Invoice/PostReplacement.php +++ b/src/Invoice/PostReplacement.php @@ -23,7 +23,7 @@ class PostReplacement implements InvoiceInterface return 'post_replacement'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -41,6 +41,8 @@ class PostReplacement implements InvoiceInterface 'price' => $fee, ]; + $qty_price = bcmul($fee, $qty, 2); + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } return $items; diff --git a/src/Invoice/Tax.php b/src/Invoice/Tax.php index 377dc2b6..45172286 100644 --- a/src/Invoice/Tax.php +++ b/src/Invoice/Tax.php @@ -53,29 +53,21 @@ class Tax implements InvoiceInterface $price_minus_vat = bcsub($price, $vat, 2); $qty_price_minus_vat = bcmul($price_minus_vat, $qty, 2); - $total['sell_price'] = bcadd($total['sell_price'], $qty_price, 2); $total['vat'] = bcadd($total['vat'], $qty_vat, 2); $total['vat_ex_price'] = bcadd($total['vat_ex_price'], $qty_price_minus_vat, 2); - - $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } } - else - { - // for all other service types - // add the item price to total_price. we compute VAT from the total price - $total_price = bcadd($total_price, $price, 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['total_price'] = $total_price; $total['vat_ex_price'] = $vat_ex_price; $total['vat'] = $vat; } diff --git a/src/Invoice/TireRepair.php b/src/Invoice/TireRepair.php index d4fdcecd..4ec85945 100644 --- a/src/Invoice/TireRepair.php +++ b/src/Invoice/TireRepair.php @@ -23,7 +23,7 @@ class TireRepair implements InvoiceInterface return 'tire'; } - public function compute($criteria, $stype_fees) + public function compute($criteria, $stype_fees, &$total) { $stype = $criteria->getServiceType(); @@ -46,6 +46,9 @@ class TireRepair implements InvoiceInterface 'title' => $this->getServiceTitle(), 'price' => $fee, ]; + + $qty_price = bcmul($fee, $qty, 2); + $total['total_price'] = bcadd($total['total_price'], $qty_price, 2); } return $items; diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index a6503d7b..b1baf521 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -60,7 +60,7 @@ class InvoiceManager 'battery_warranty_fee' => 0, 'other_services_fee' => 200, 'fuel_fee_gas' => 320, - 'fuel_fee_diesel' => 320, + 'fuel_fee_diesel' => 340, ]; } @@ -124,7 +124,7 @@ class InvoiceManager { $items = []; - $computed_items = $active_rule->compute($criteria, $stype_fees); + $computed_items = $active_rule->compute($criteria, $stype_fees, $total); foreach ($computed_items as $computed_item) { if (!empty($computed_item)) @@ -133,6 +133,17 @@ class InvoiceManager } } + // 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) { @@ -146,14 +157,12 @@ class InvoiceManager } } - // check if tax is needed - if ($is_taxable) + // process promos, if any + if (count($promos) > 0) { - $tax_rate = $this->getTaxRate(); - - if (isset($active_rules['tax'])) + if (isset($active_rules['discount_type'])) { - $active_rules['tax']->compute($tax_rate, $items, $total); + $discount_items = $active_rules['discount_type']->compute($criteria, $stype_fees); } } @@ -171,15 +180,6 @@ class InvoiceManager $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, From f760b2c02ae26a78f1f5ac5dd02e997532555d86 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 1 Jun 2023 03:22:24 -0400 Subject: [PATCH 10/25] Add discount type rule and test cases. #744 --- src/Command/TestInvoiceManagerCommand.php | 286 +++++++++++++++++++++- src/Invoice/DiscountType.php | 33 ++- src/Service/InvoiceManager.php | 13 +- 3 files changed, 326 insertions(+), 6 deletions(-) diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 7feafcb9..6c971156 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -16,6 +16,7 @@ use App\Ramcar\ServiceType; use App\Entity\Battery; use App\Entity\CustomerVehicle; +use App\Entity\Promo; class TestInvoiceManagerCommand extends Command { @@ -66,7 +67,18 @@ class TestInvoiceManagerCommand extends Command $this->testBatterySalesTradeInQuantityNoDiscountWithoutTax(); // battery sales with discount with tax + $this->testBatterySalesNoTradeInWithDiscountWithTax(); + // battery sales with discount without tax + $this->testBatterySalesNoTradeInWithDiscountWithoutTax(); + + // battery sales with discount and trade in with tax + $this->testBatterySalesTradeInSameBatteryWithDiscountWithTax(); + $this->testBatterySalesTradeInDifferentBatteryWithDiscountWithTax(); + + // battery sales with discount and trade in without tax + $this->testBatterySalesTradeInSameBatteryWithDiscountWithoutTax(); + $this->testBatterySalesTradeInDifferentBatteryWithDiscountWithoutTax(); // battery replacement warranty with tax $this->testBatteryReplacementWarrantyWithTax(); @@ -126,8 +138,6 @@ class TestInvoiceManagerCommand extends Command $this->testTireRepairWithServiceFeeWithoutTax(); $this->testTireRepairWithoutServiceFeeWithoutTax(); - // TEST SCENARIO: new battery with discount - // TEST SCENARIO: new battery with discount and trade-in return 0; } @@ -814,6 +824,278 @@ class TestInvoiceManagerCommand extends Command } } + // battery sales with discount with tax + protected function testBatterySalesNoTradeInWithDiscountWithTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, no trade-in, with discount, with tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 1; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + $criteria->addEntry($battery, null, 1); + + $criteria->addPromo($promo); + + $criteria->setIsTaxable(); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + $promo = $data['promo']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN WITH DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('PROMO ' . $promo->getName()); + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // battery sales with discount without tax + protected function testBatterySalesNoTradeInWithDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, no trade-in, with discount, without tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 10; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + $criteria->addEntry($battery, null, 1); + + $criteria->addPromo($promo); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + $promo = $data['promo']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN WITH DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('PROMO ' . $promo->getName()); + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // battery sales with discount and trade in with tax + protected function testBatterySalesTradeInSameBatteryWithDiscountWithTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, no trade-in, with discount, with tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 1; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'premium', 1); + + $criteria->addPromo($promo); + + $criteria->setIsTaxable(); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + $promo = $data['promo']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN SAME BATTERY WITH DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('PROMO ' . $promo->getName()); + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInDifferentBatteryWithDiscountWithTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, with discount, with tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 1; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'premium', 1); + + $criteria->addPromo($promo); + + $criteria->setIsTaxable(); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN DIFFERENT BATTERY WITH DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + // battery sales with discount and trade in without tax + protected function testBatterySalesTradeInSameBatteryWithDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, no trade-in, with discount, with tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 1; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + $criteria->addEntry($battery, null, 1); + + // add battery for trade in + $criteria->addEntry($battery, 'premium', 1); + + $criteria->addPromo($promo); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + // error_log(print_r(json_encode($invoice_data), true)); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + $promo = $data['promo']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN SAME BATTERY WITH DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('PROMO ' . $promo->getName()); + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + + protected function testBatterySalesTradeInDifferentBatteryWithDiscountWithoutTax() + { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, with discount, without tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 1; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'premium', 1); + + $criteria->addPromo($promo); + + $rules = $this->inv_manager->check($criteria); + + // error_log(print_r($rules, true)); + + $invoice_data = $this->inv_manager->compute($criteria, $rules); + + foreach ($invoice_data as $data) + { + $invoice_items = $data['invoice_items']; + $total = $data['total']; + + foreach ($invoice_items as $invoice_item) + { + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN DIFFERENT BATTERY WITH DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + + error_log('TOTAL ' . print_r(json_encode($total), true)); + } + } + // battery replacement warranty with tax protected function testBatteryReplacementWarrantyWithTax() { diff --git a/src/Invoice/DiscountType.php b/src/Invoice/DiscountType.php index a1bea802..091ff9c6 100644 --- a/src/Invoice/DiscountType.php +++ b/src/Invoice/DiscountType.php @@ -42,15 +42,44 @@ class DiscountType implements InvoiceInterface switch ($apply_to) { case DiscountApply::SRP: - $discount = round($total['sell_price'] * $rate, 2); + $discount = bcmul($total['sell_price'], $rate, 2); break; case DiscountApply::OPL: // $discount = round($total['sell_price'] * 0.6 / 0.7 * $rate, 2); - $discount = round($total['sell_price'] * (1 - 1.5 / 0.7 * $rate), 2); + // $discount = round($total['sell_price'] * (1 - 1.5 / 0.7 * $rate), 2); + $num1 = bcdiv(1.5, 0.7, 9); + $num1_rate = bcmul($num1, $rate, 9); + $multiplier = bcsub(1, $num1_rate, 9); + + $discount = bcmul($total['sell_price'], $multiplier, 2); break; } + // if discount is higher than 0, add to items + if ($discount > 0) + { + $qty = 1; + $price = bcmul(-1, $discount, 2); + + $items[] = [ + 'promo' => $promo, + 'title' => $this->getTitle(), + 'qty' => $qty, + 'price' => $price, + ]; + } + + $total['discount'] = $discount; + $total['total_price'] = bcsub($total['total_price'], $discount, 2); + return $items; } + + protected function getTitle() + { + $title = 'Promo discount'; + + return $title; + } } diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index b1baf521..8743a099 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -162,10 +162,15 @@ class InvoiceManager { if (isset($active_rules['discount_type'])) { - $discount_items = $active_rules['discount_type']->compute($criteria, $stype_fees); + $discount_items = $active_rules['discount_type']->compute($criteria, $stype_fees, $total); + foreach ($discount_items as $discount_item) + { + $items[] = $discount_item; + } } } + $promo = null; foreach ($items as $item) { $invoice_item = new InvoiceItem(); @@ -177,11 +182,15 @@ class InvoiceManager if (isset($item['battery'])) $invoice_item->setBattery($item['battery']); + if (isset($item['promo'])) + $promo = $item['promo']; + $invoice_items[] = $invoice_item; } - // also need to return the total + // also need to return the total and the promo $data[] = [ + 'promo' => $promo, 'invoice_items' => $invoice_items, 'total' => $total, ]; From 77c2763f53df1fba1fcdb1662454a658eefd8fe1 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 1 Jun 2023 04:39:38 -0400 Subject: [PATCH 11/25] Fix typo. #744 --- src/Service/InvoiceManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 8743a099..1a17fe7d 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -44,7 +44,7 @@ class InvoiceManager new Invoice\TireRepair(), new Invoice\DiscountType(), new Invoice\TradeIn(), - new Invoice\Tax, + new Invoice\Tax(), ]; } From a986d7835ba6826ad60974c0407d1d7d65213ca4 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 2 Jun 2023 05:50:39 -0400 Subject: [PATCH 12/25] 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; + } + } From fe5121cf71f605bc8e8b5887e847f4053e361d5c Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jun 2023 01:55:04 -0400 Subject: [PATCH 13/25] Add methods to process generateInvoice ajax call. Add test cases. #744 --- src/Command/TestInvoiceManagerCommand.php | 181 ++++++++++++++++++++++ src/Controller/JobOrderController.php | 2 + src/Service/InvoiceManager.php | 56 ++++++- 3 files changed, 234 insertions(+), 5 deletions(-) diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 6c971156..85745c1d 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -17,6 +17,7 @@ use App\Ramcar\ServiceType; use App\Entity\Battery; use App\Entity\CustomerVehicle; use App\Entity\Promo; +use App\Entity\JobOrder; class TestInvoiceManagerCommand extends Command { @@ -138,6 +139,22 @@ class TestInvoiceManagerCommand extends Command $this->testTireRepairWithServiceFeeWithoutTax(); $this->testTireRepairWithoutServiceFeeWithoutTax(); + // test creation of invoice criteria when JO is submitted + $this->testGenerateInvoiceCriteria(); + $this->testGenerateInvoiceCriteriaInvalidPromo(); + $this->testGenerateInvoiceCriteriaInvalidBattery(); + + // test generateDraftInvoice call from ajax call + $this->testGenerateDraftInvoiceNoErrorWithTradeIn(); + $this->testGenerateDraftInvoiceNoErrorNoTradeIn(); + $this->testGenerateDraftInvoiceInvalidBattery(); + $this->testGenerateDraftInvoiceInvalidPromo(); + $this->testGenerateDraftInvoiceNonBatterySales(); + $this->testGenerateDraftInvoiceBatterySalesNoPromo(); + + // test generateInvoiceInvoice call from ajax call + $this->testGenerateInvoice(); + return 0; } @@ -1948,4 +1965,168 @@ class TestInvoiceManagerCommand extends Command } } + // test creation of invoice criteria when JO is submitted + protected function testGenerateInvoiceCriteria() + { + // create JO, set service type and customer vehicle + $jo = new JobOrder(); + + $jo->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $jo->setCustomerVehicle($cv); + + // create error_array + $error_array = []; + + // create array of invoice items + $invoice_items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ], [ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => 'premium' + ]]; + + // error_log(print_r(json_encode($invoice_items), true)); + // promo id + $promo_id = 10; + + $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + + if ($invoice != null) + { + error_log('TEST GENERATEINVOICECRITERIA:'); + error_log('INVOICE'); + error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); + error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); + error_log('VAT: ' . $invoice->getVAT()); + error_log('DISCOUNT: ' . $invoice->getDiscount()); + error_log('TRADE-IN: ' . $invoice->getTradeIn()); + error_log('STATUS: ' . $invoice->getStatus()); + + $invoice_items = $invoice->getItems(); + + foreach ($invoice_items as $invoice_item) + { + error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + } + + protected function testGenerateInvoiceCriteriaInvalidPromo() + { + } + + protected function testGenerateInvoiceCriteriaInvalidBattery() + { + } + + // test generateDraftInvoice call from ajax call + protected function testGenerateDraftInvoiceNoErrorWithTradeIn() + { + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + $criteria->setIsTaxable(); + + $promo_id = 1; + $service_charges = []; + + // create array of invoice items + $items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ], [ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => 'premium' + ]]; + + $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); + + if ($error) + error_log('TEST GENERATE DRAFT INVOICE NO ERROR WITH TRADE IN: Errors found when generating draft invoice' . print_r($error, true)); + else + error_log('TEST GENERATE DRAFT INVOICE NO ERROR WITH TRADE IN: No errors here'); + } + + protected function testGenerateDraftInvoiceNoErrorNoTradeIn() + { + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + $criteria->setIsTaxable(); + + $promo_id = 1; + $service_charges = []; + + // create array of invoice items + $items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ]]; + + $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); + + if ($error) + error_log('TEST GENERATE DRAFT INVOICE NO ERROR NO TRADE IN: Errors found when generating draft invoice' . print_r($error, true)); + else + error_log('TEST GENERATE DRAFT INVOICE NO ERROR NO TRADE IN: No errors here'); + } + + protected function testGenerateDraftInvoiceInvalidBattery() + { + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + $criteria->setIsTaxable(); + + $promo_id = 1; + $service_charges = []; + + // create array of invoice items + $items = [[ + 'battery' => 1, + 'quantity' => 1, + 'trade_in' => '', + ], [ + 'battery' => 2, + 'quantity' => 1, + 'trade_in' => 'premium' + ]]; + + $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); + + if ($error) + error_log('TEST GENERATE DRAFT INVOICE BATTERY ERROR: Errors found when generating draft invoice: ' . print_r($error, true)); + else + error_log('TEST GENERATE DRAFT INVOICE BATTERY ERROR: No errors here'); + } + + protected function testGenerateDraftInvoiceInvalidPromo() + { + } + + protected function testGenerateDraftInvoiceNonBatterySales() + { + } + + protected function testGenerateDraftInvoiceBatterySalesNoPromo() + { + } + + + // test generateInvoiceInvoice call from ajax call + protected function testGenerateInvoice() + { + } + } diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index 485709e4..c51a34c9 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -724,6 +724,8 @@ class JobOrderController extends Controller $cvid = $req->request->get('cvid'); $service_charges = $req->request->get('service_charges', []); + // TODO: set if taxable here + $em = $this->getDoctrine()->getManager(); // get customer vehicle diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 0990db76..41d8dde9 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -14,6 +14,7 @@ use App\Ramcar\InvoiceStatus; use App\Ramcar\ServiceType; use App\Ramcar\TradeInType; +use App\Entity\Invoice as Inv; use App\Entity\InvoiceItem; use App\Entity\User; use App\Entity\Battery; @@ -82,6 +83,7 @@ class InvoiceManager return 0.12; } + // this is called when JO is submitted public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array) { // instantiate the invoice criteria @@ -112,8 +114,45 @@ class InvoiceManager $invoice_data = $this->compute($criteria, $rules); - $invoice = $createInvoice($invoice_data); + $invoice = $this->createInvoice($invoice_data); + + return $invoice; } + + return null; + } + + // this is called by JobOrderController when JS script generateInvoice is called + public function generateDraftInvoice($criteria, $promo_id, $service_charges, $items) + { + error_log('generateDraftInvoice'); + $ierror = $this->validatePromo($criteria, $promo_id); + + error_log(print_r($ierror, true)); + + if (!$ierror && !empty($items)) + { + error_log('calling validateInvoiceItems'); + // validate the invoice items (batteries and trade ins) + $ierror = $this->validateInvoiceItems($criteria, $items); + } + + return $ierror; + } + + // this is called by JobOrderController when JS script generateInvoice is called + public function generateInvoice($criteria) + { + // no need to validate since generateDraftInvoice was called before this was called + // generate the invoice + // check which rules to apply + $rules = $this->check($criteria); + + $invoice_data = $this->compute($criteria, $rules); + + $invoice = $this->createInvoice($invoice_data); + + return $invoice; } // check what rules to use given the criteria @@ -264,6 +303,8 @@ class InvoiceManager // check if this is a valid promo $promo = $this->em->getRepository(Promo::class)->find($promo_id); + error_log('promo checkpoint'); + if (empty($promo)) return 'Invalid promo specified.'; @@ -274,17 +315,19 @@ class InvoiceManager protected function validateInvoiceItems($criteria, $invoice_items) { + error_log('validate 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)) + if (!empty($invoice_items)) { // check if this is a valid battery - foreach ($items as $item) + foreach ($invoice_items as $item) { + error_log($item['battery']); $battery = $this->em->getRepository(Battery::class)->find($item['battery']); if (empty($battery)) @@ -313,7 +356,7 @@ class InvoiceManager protected function createInvoice($invoice_data) { - $invoice = new Invoice(); + $invoice = new Inv(); // get current user $user = $this->security->getUser(); @@ -332,7 +375,10 @@ class InvoiceManager if (isset($data['promo'])) $promo = $data['promo']; - $invoice->addItem($invoice_item); + foreach ($invoice_items as $invoice_item) + { + $invoice->addItem($invoice_item); + } $invoice->setTotalPrice($total['total_price']) ->setVATExclusivePrice($total['vat_ex_price']) From 4ebbd8cfd3205c06f94a82eb6609e789648b033f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jun 2023 20:13:37 -0400 Subject: [PATCH 14/25] Finish adding the test cases. #744 --- src/Command/TestInvoiceManagerCommand.php | 229 +++++++++++++++++++++- src/Service/InvoiceManager.php | 8 - 2 files changed, 225 insertions(+), 12 deletions(-) diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 85745c1d..62fbf0f8 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -1999,7 +1999,7 @@ class TestInvoiceManagerCommand extends Command $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); - if ($invoice != null) + if (empty($error_array)) { error_log('TEST GENERATEINVOICECRITERIA:'); error_log('INVOICE'); @@ -2017,14 +2017,124 @@ class TestInvoiceManagerCommand extends Command error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); } } + else + { + error_log('TEST GENERATE INVOICE CRITERIA: Errors found when generating invoice ' . print_r(json_encode($error_array), true)); + } } protected function testGenerateInvoiceCriteriaInvalidPromo() { + // create JO, set service type and customer vehicle + $jo = new JobOrder(); + + $jo->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $jo->setCustomerVehicle($cv); + + // create error_array + $error_array = []; + + // create array of invoice items + $invoice_items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ], [ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => 'premium' + ]]; + + // error_log(print_r(json_encode($invoice_items), true)); + // promo id + $promo_id = 99; + + $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + + if (empty($error_array)) + { + error_log('TEST GENERATEINVOICECRITERIA:'); + error_log('INVOICE'); + error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); + error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); + error_log('VAT: ' . $invoice->getVAT()); + error_log('DISCOUNT: ' . $invoice->getDiscount()); + error_log('TRADE-IN: ' . $invoice->getTradeIn()); + error_log('STATUS: ' . $invoice->getStatus()); + + $invoice_items = $invoice->getItems(); + + foreach ($invoice_items as $invoice_item) + { + error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + else + { + error_log('TEST GENERATE INVOICE CRITERIA INVALID PROMO: Errors found when generating invoice ' . print_r(json_encode($error_array), true)); + } } protected function testGenerateInvoiceCriteriaInvalidBattery() { + // create JO, set service type and customer vehicle + $jo = new JobOrder(); + + $jo->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + // set customer vehicle + $cv_id = 1306604; + $cv = $this->em->getRepository(CustomerVehicle::class)->find($cv_id); + + $jo->setCustomerVehicle($cv); + + // create error_array + $error_array = []; + + // create array of invoice items + $invoice_items = [[ + 'battery' => 1, + 'quantity' => 1, + 'trade_in' => '', + ], [ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => 'premium' + ]]; + + // error_log(print_r(json_encode($invoice_items), true)); + // promo id + $promo_id = 1; + + $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + + if (empty($error_array)) + { + error_log('TEST GENERATEINVOICECRITERIA:'); + error_log('INVOICE'); + error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); + error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); + error_log('VAT: ' . $invoice->getVAT()); + error_log('DISCOUNT: ' . $invoice->getDiscount()); + error_log('TRADE-IN: ' . $invoice->getTradeIn()); + error_log('STATUS: ' . $invoice->getStatus()); + + $invoice_items = $invoice->getItems(); + + foreach ($invoice_items as $invoice_item) + { + error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + else + { + error_log('TEST GENERATE INVOICE CRITERIA INVALID BATTERY: Errors found when generating invoice ' . print_r(json_encode($error_array), true)); + } } // test generateDraftInvoice call from ajax call @@ -2052,7 +2162,7 @@ class TestInvoiceManagerCommand extends Command $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); if ($error) - error_log('TEST GENERATE DRAFT INVOICE NO ERROR WITH TRADE IN: Errors found when generating draft invoice' . print_r($error, true)); + error_log('TEST GENERATE DRAFT INVOICE NO ERROR WITH TRADE IN: Errors found when generating draft invoice ' . print_r($error, true)); else error_log('TEST GENERATE DRAFT INVOICE NO ERROR WITH TRADE IN: No errors here'); } @@ -2077,7 +2187,7 @@ class TestInvoiceManagerCommand extends Command $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); if ($error) - error_log('TEST GENERATE DRAFT INVOICE NO ERROR NO TRADE IN: Errors found when generating draft invoice' . print_r($error, true)); + error_log('TEST GENERATE DRAFT INVOICE NO ERROR NO TRADE IN: Errors found when generating draft invoice ' . print_r($error, true)); else error_log('TEST GENERATE DRAFT INVOICE NO ERROR NO TRADE IN: No errors here'); } @@ -2094,7 +2204,7 @@ class TestInvoiceManagerCommand extends Command // create array of invoice items $items = [[ - 'battery' => 1, + 'battery' => 1038, 'quantity' => 1, 'trade_in' => '', ], [ @@ -2113,20 +2223,131 @@ class TestInvoiceManagerCommand extends Command protected function testGenerateDraftInvoiceInvalidPromo() { + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + $criteria->setIsTaxable(); + + $promo_id = 99; + $service_charges = []; + + // create array of invoice items + $items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ]]; + + $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); + + if ($error) + error_log('TEST GENERATE DRAFT INVOICE PROMO ERROR: Errors found when generating draft invoice ' . print_r($error, true)); + else + error_log('TEST GENERATE DRAFT INVOICE PROMO ERROR: No errors here'); } protected function testGenerateDraftInvoiceNonBatterySales() { + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::JUMPSTART_TROUBLESHOOT); + $criteria->setIsTaxable(); + + $promo_id = 1; + $service_charges = []; + + // create array of invoice items + $items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ]]; + + $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); + + if ($error) + error_log('TEST GENERATE DRAFT NON BATTERY SALES: Errors found when generating draft invoice ' . print_r($error, true)); + else + error_log('TEST GENERATE DRAFT NON BATTERY SALES: No errors here'); } protected function testGenerateDraftInvoiceBatterySalesNoPromo() { + $criteria = new InvoiceCriteria(); + + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + $criteria->setIsTaxable(); + + $promo_id = ''; + $service_charges = []; + + // create array of invoice items + $items = [[ + 'battery' => 1038, + 'quantity' => 1, + 'trade_in' => '', + ]]; + + $error = $this->inv_manager->generateDraftInvoice($criteria, $promo_id, $service_charges, $items); + + if ($error) + error_log('TEST GENERATE DRAFT INVOICE BATTERY SALES NO PROMO: Errors found when generating draft invoice ' . print_r($error, true)); + else + error_log('TEST GENERATE DRAFT INVOICE BATTERY SALES NO PROMO: No errors here'); } // test generateInvoiceInvoice call from ajax call protected function testGenerateInvoice() { + $criteria = new InvoiceCriteria(); + + // TEST SCENARIO: new battery, trade-in different battery, premium, with discount, with tax + $criteria->setServiceType(ServiceType::BATTERY_REPLACEMENT_NEW); + + $battery_id = 1038; + $battery = $this->em->getRepository(Battery::class)->find($battery_id); + + $promo_id = 1; + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + // add battery + $criteria->addEntry($battery, null, 1); + + $trade_battery_id = 1037; + $trade_battery = $this->em->getRepository(Battery::class)->find($trade_battery_id); + + // add battery for trade in + $criteria->addEntry($trade_battery, 'premium', 1); + + $criteria->addPromo($promo); + + $criteria->setIsTaxable(); + + $invoice = $this->inv_manager->generateInvoice($criteria); + + if ($invoice != null) + { + error_log('TEST GENERATEINVOICE:'); + error_log('INVOICE'); + error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); + error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); + error_log('VAT: ' . $invoice->getVAT()); + error_log('DISCOUNT: ' . $invoice->getDiscount()); + error_log('TRADE-IN: ' . $invoice->getTradeIn()); + error_log('STATUS: ' . $invoice->getStatus()); + + $invoice_items = $invoice->getItems(); + + foreach ($invoice_items as $invoice_item) + { + error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + } + } + else + { + error_log('TEST GENERATE INVOICE: Error found. '); + } } } diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 41d8dde9..2c577546 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -125,14 +125,10 @@ class InvoiceManager // this is called by JobOrderController when JS script generateInvoice is called public function generateDraftInvoice($criteria, $promo_id, $service_charges, $items) { - error_log('generateDraftInvoice'); $ierror = $this->validatePromo($criteria, $promo_id); - error_log(print_r($ierror, true)); - if (!$ierror && !empty($items)) { - error_log('calling validateInvoiceItems'); // validate the invoice items (batteries and trade ins) $ierror = $this->validateInvoiceItems($criteria, $items); } @@ -303,8 +299,6 @@ class InvoiceManager // check if this is a valid promo $promo = $this->em->getRepository(Promo::class)->find($promo_id); - error_log('promo checkpoint'); - if (empty($promo)) return 'Invalid promo specified.'; @@ -315,7 +309,6 @@ class InvoiceManager protected function validateInvoiceItems($criteria, $invoice_items) { - error_log('validate 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) @@ -327,7 +320,6 @@ class InvoiceManager // check if this is a valid battery foreach ($invoice_items as $item) { - error_log($item['battery']); $battery = $this->em->getRepository(Battery::class)->find($item['battery']); if (empty($battery)) From e9f18ed18456e75d27be5ec7df77076eff4aade8 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jun 2023 21:34:15 -0400 Subject: [PATCH 15/25] Modify the admin panel to use the new invoice engine when creating a new JO. #744 --- config/services.yaml | 3 + src/Command/TestInvoiceManagerCommand.php | 166 ++++++------------ src/Service/InvoiceManager.php | 70 ++++++-- .../JobOrderHandler/ResqJobOrderHandler.php | 7 +- 4 files changed, 118 insertions(+), 128 deletions(-) diff --git a/config/services.yaml b/config/services.yaml index a5d7d05f..f2693988 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -169,6 +169,9 @@ services: # invoice generator interface App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\ResqInvoiceGenerator" + + # invoice manager + App\Service\InvoiceManager: ~ # job order generator App\Service\JobOrderHandler\ResqJobOrderHandler: diff --git a/src/Command/TestInvoiceManagerCommand.php b/src/Command/TestInvoiceManagerCommand.php index 62fbf0f8..6fd955cb 100644 --- a/src/Command/TestInvoiceManagerCommand.php +++ b/src/Command/TestInvoiceManagerCommand.php @@ -187,7 +187,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -222,7 +222,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -257,7 +257,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -291,7 +291,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY NO TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -329,7 +329,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -367,7 +367,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -405,7 +405,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -446,7 +446,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -487,7 +487,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -528,7 +528,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -569,7 +569,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -606,7 +606,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -642,7 +642,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -678,7 +678,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN SAME BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -717,7 +717,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' PREMIUM TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -756,7 +756,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' MOTOLITE TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -795,7 +795,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' OTHER TRADE IN DIFFERENT BATTERY NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -834,7 +834,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' QUANTITY TRADE IN NO DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -877,7 +877,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN WITH DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN WITH DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('PROMO ' . $promo->getName()); @@ -920,7 +920,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN WITH DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' NO TRADE IN WITH DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('PROMO ' . $promo->getName()); @@ -968,7 +968,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN SAME BATTERY WITH DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN SAME BATTERY WITH DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('PROMO ' . $promo->getName()); @@ -1016,7 +1016,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN DIFFERENT BATTERY WITH DISCOUNT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN DIFFERENT BATTERY WITH DISCOUNT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1060,7 +1060,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN SAME BATTERY WITH DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN SAME BATTERY WITH DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('PROMO ' . $promo->getName()); @@ -1106,7 +1106,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN DIFFERENT BATTERY WITH DISCOUNT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_NEW) . ' TRADE IN DIFFERENT BATTERY WITH DISCOUNT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1141,7 +1141,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1174,7 +1174,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::BATTERY_REPLACEMENT_WARRANTY) . ' WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1210,7 +1210,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1245,7 +1245,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1280,7 +1280,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1315,7 +1315,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1349,7 +1349,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH SERVICE FEE WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1382,7 +1382,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH SERVICE FEE WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1415,7 +1415,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' GAS WITH NO SERVICE FEE WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1448,7 +1448,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::EMERGENCY_REFUEL) . ' DIESEL WITH NO SERVICE FEE WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1478,7 +1478,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1506,7 +1506,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_TROUBLESHOOT) . ' WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1536,7 +1536,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1564,7 +1564,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::JUMPSTART_WARRANTY) . ' WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1600,7 +1600,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1634,7 +1634,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1669,7 +1669,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITH COOLANT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1702,7 +1702,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::OVERHEAT_ASSISTANCE) . ' WITHOUT COOLANT WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1732,7 +1732,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1760,7 +1760,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_RECHARGED) . ' WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1790,7 +1790,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1820,7 +1820,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::POST_REPLACEMENT) . ' WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1856,7 +1856,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1891,7 +1891,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE WITH TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE WITH TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1925,7 +1925,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITH SERVICE FEE WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1958,7 +1958,7 @@ class TestInvoiceManagerCommand extends Command foreach ($invoice_items as $invoice_item) { - error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE WITHOUT TAX ' . $invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); + error_log('TEST: ' . strtoupper(ServiceType::TIRE_REPAIR) . ' WITHOUT SERVICE FEE WITHOUT TAX ' . $invoice_item['title'] . ' ' . $invoice_item['quantity'] . ' ' . $invoice_item['price']); } error_log('TOTAL ' . print_r(json_encode($total), true)); @@ -1997,27 +1997,9 @@ class TestInvoiceManagerCommand extends Command // promo id $promo_id = 10; - $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); - if (empty($error_array)) - { - error_log('TEST GENERATEINVOICECRITERIA:'); - error_log('INVOICE'); - error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); - error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); - error_log('VAT: ' . $invoice->getVAT()); - error_log('DISCOUNT: ' . $invoice->getDiscount()); - error_log('TRADE-IN: ' . $invoice->getTradeIn()); - error_log('STATUS: ' . $invoice->getStatus()); - - $invoice_items = $invoice->getItems(); - - foreach ($invoice_items as $invoice_item) - { - error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); - } - } - else + if (!empty($error_array)) { error_log('TEST GENERATE INVOICE CRITERIA: Errors found when generating invoice ' . print_r(json_encode($error_array), true)); } @@ -2054,27 +2036,9 @@ class TestInvoiceManagerCommand extends Command // promo id $promo_id = 99; - $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); - if (empty($error_array)) - { - error_log('TEST GENERATEINVOICECRITERIA:'); - error_log('INVOICE'); - error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); - error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); - error_log('VAT: ' . $invoice->getVAT()); - error_log('DISCOUNT: ' . $invoice->getDiscount()); - error_log('TRADE-IN: ' . $invoice->getTradeIn()); - error_log('STATUS: ' . $invoice->getStatus()); - - $invoice_items = $invoice->getItems(); - - foreach ($invoice_items as $invoice_item) - { - error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); - } - } - else + if (!empty($error_array)) { error_log('TEST GENERATE INVOICE CRITERIA INVALID PROMO: Errors found when generating invoice ' . print_r(json_encode($error_array), true)); } @@ -2111,28 +2075,10 @@ class TestInvoiceManagerCommand extends Command // promo id $promo_id = 1; - $invoice = $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + $this->inv_manager->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); - if (empty($error_array)) + if (!empty($error_array)) { - error_log('TEST GENERATEINVOICECRITERIA:'); - error_log('INVOICE'); - error_log('TOTAL PRICE: ' . $invoice->getTotalPrice()); - error_log('VAT EXCLUSIVE PRICE: ' . $invoice->getVATExclusivePrice()); - error_log('VAT: ' . $invoice->getVAT()); - error_log('DISCOUNT: ' . $invoice->getDiscount()); - error_log('TRADE-IN: ' . $invoice->getTradeIn()); - error_log('STATUS: ' . $invoice->getStatus()); - - $invoice_items = $invoice->getItems(); - - foreach ($invoice_items as $invoice_item) - { - error_log($invoice_item->getTitle() . ' ' . $invoice_item->getQuantity() . ' ' . $invoice_item->getPrice()); - } - } - else - { error_log('TEST GENERATE INVOICE CRITERIA INVALID BATTERY: Errors found when generating invoice ' . print_r(json_encode($error_array), true)); } } diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 2c577546..291048c7 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -96,6 +96,8 @@ class InvoiceManager $ierror = $this->validatePromo($criteria, $promo_id); + error_log('generateInvoiceCriteria ' . count($invoice_items)); + if (!$ierror && !empty($invoice_items)) { // validate the invoice items (batteries and trade ins) @@ -109,17 +111,30 @@ class InvoiceManager else { // generate the invoice - // check which rules to apply - $rules = $this->check($criteria); + $invoice = $this->generateInvoice($criteria); - $invoice_data = $this->compute($criteria, $rules); + // validate + $ierrors = $this->validator->validate($invoice); - $invoice = $this->createInvoice($invoice_data); + // add errors to list + foreach ($ierrors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } - return $invoice; + // check if invoice already exists for JO + $old_invoice = $jo->getInvoice(); + if ($old_invoice != null) + { + // remove old invoice + $this->em->remove($old_invoice); + $this->em->flush(); + } + + // add invoice to JO + $jo->setInvoice($invoice); + + $this->em->persist($invoice); } - - return null; } // this is called by JobOrderController when JS script generateInvoice is called @@ -137,6 +152,7 @@ class InvoiceManager } // this is called by JobOrderController when JS script generateInvoice is called + // this is also called by generateInvoiceCriteria public function generateInvoice($criteria) { // no need to validate since generateDraftInvoice was called before this was called @@ -252,23 +268,33 @@ class InvoiceManager } $promo = null; + error_log('mogol compute items ' . count($items)); + foreach ($items as $item) { - $invoice_item = new InvoiceItem(); - - $invoice_item->setTitle($item['title']) - ->setQuantity($item['qty']) - ->setPrice($item['price']); + $title = $item['title']; + $quantity = $item['qty']; + $price = $item['price']; + $battery = null; if (isset($item['battery'])) - $invoice_item->setBattery($item['battery']); + $battery = $item['battery']; + $promo = null; if (isset($item['promo'])) $promo = $item['promo']; - $invoice_items[] = $invoice_item; + $invoice_items[] = [ + 'title' => $title, + 'quantity' => $quantity, + 'price' => $price, + 'battery' => $battery, + 'promo' => $promo, + ]; } + error_log('mogol compute invoice items ' . count($invoice_items)); + // also need to return the total and the promo $data[] = [ 'promo' => $promo, @@ -367,8 +393,20 @@ class InvoiceManager if (isset($data['promo'])) $promo = $data['promo']; - foreach ($invoice_items as $invoice_item) + error_log('mogol ' . count($invoice_items)); + + foreach ($invoice_items as $item) { + $invoice_item = new InvoiceItem(); + + $invoice_item->setInvoice($invoice) + ->setTitle($item['title']) + ->setQuantity($item['quantity']) + ->setPrice($item['price']); + + if ($item['battery'] != null) + $invoice_item->setBattery($item['battery']); + $invoice->addItem($invoice_item); } @@ -378,6 +416,8 @@ class InvoiceManager ->setDiscount($total['discount']) ->setTradeIn($total['ti_rate']) ->setStatus(InvoiceStatus::DRAFT); + + error_log('mogol total ' . $invoice->getTotalPrice()); } return $invoice; diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 4827bd59..4c5040dc 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -30,7 +30,6 @@ use App\Entity\EmergencyType; use App\Entity\OwnershipType; use App\Entity\CustomerLocation; -use App\Ramcar\InvoiceCriteria; use App\Ramcar\ServiceType; use App\Ramcar\TradeInType; use App\Ramcar\JOEventType; @@ -53,7 +52,6 @@ use App\Ramcar\CustomerClassification; use App\Ramcar\Gender; use App\Ramcar\CallerClassification; -use App\Service\InvoiceGeneratorInterface; use App\Service\JobOrderHandlerInterface; use App\Service\RiderAssignmentHandlerInterface; use App\Service\WarrantyHandler; @@ -66,6 +64,9 @@ use App\Service\HubSelector; use App\Service\HubDistributor; use App\Service\HubFilteringGeoChecker; +use App\Service\InvoiceManager; +use App\InvoiceCriteria; + use CrEOF\Spatial\PHP\Types\Geometry\Point; use Mosquitto\Client as MosquittoClient; @@ -95,7 +96,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface protected $template_hash; public function __construct(Security $security, EntityManagerInterface $em, - InvoiceGeneratorInterface $ic, ValidatorInterface $validator, + InvoiceManager $ic, ValidatorInterface $validator, TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah, string $country_code, WarrantyHandler $wh, RisingTideGateway $rt, PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence, From fa514ef26cd6e9e9aa22a2311a3886cff67072e1 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jun 2023 21:51:19 -0400 Subject: [PATCH 16/25] Remove debug messages. Add TODO task for front-end. #744 --- src/Service/InvoiceManager.php | 8 -------- templates/job-order/form.html.twig | 4 ++++ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index 291048c7..a9d1f8a8 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -268,8 +268,6 @@ class InvoiceManager } $promo = null; - error_log('mogol compute items ' . count($items)); - foreach ($items as $item) { $title = $item['title']; @@ -293,8 +291,6 @@ class InvoiceManager ]; } - error_log('mogol compute invoice items ' . count($invoice_items)); - // also need to return the total and the promo $data[] = [ 'promo' => $promo, @@ -393,8 +389,6 @@ class InvoiceManager if (isset($data['promo'])) $promo = $data['promo']; - error_log('mogol ' . count($invoice_items)); - foreach ($invoice_items as $item) { $invoice_item = new InvoiceItem(); @@ -416,8 +410,6 @@ class InvoiceManager ->setDiscount($total['discount']) ->setTradeIn($total['ti_rate']) ->setStatus(InvoiceStatus::DRAFT); - - error_log('mogol total ' . $invoice->getTotalPrice()); } return $invoice; diff --git a/templates/job-order/form.html.twig b/templates/job-order/form.html.twig index 9a8387b5..95c548b5 100644 --- a/templates/job-order/form.html.twig +++ b/templates/job-order/form.html.twig @@ -1714,6 +1714,8 @@ $(function() { } // add to invoice array + // TODO: need to figure out how to push battery and tradein separately + // right now, battery and trade in is one entry. Need to separate that into two entries invoiceItems.push({ battery: battery, quantity: qty, @@ -1752,6 +1754,8 @@ $(function() { var stype = $("#service_type").val(); var cvid = $("#customer-vehicle").val(); + console.log(JSON.stringify(invoiceItems)); + // generate invoice values $.ajax({ method: "POST", From 05073f3a0c593afb2efb8dc7877979e4dabb184f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 7 Jun 2023 05:30:37 -0400 Subject: [PATCH 17/25] Add frontend elements for testing JO saving. #744 --- src/Controller/JobOrderController.php | 9 ++-- .../JobOrderHandler/ResqJobOrderHandler.php | 12 +++++ templates/invoice/trade_in.html.twig | 46 +++++++++++++++++++ templates/invoice/trade_in.js.twig | 17 +++++++ templates/job-order/form.html.twig | 10 ++-- 5 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 templates/invoice/trade_in.html.twig create mode 100644 templates/invoice/trade_in.js.twig diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index c51a34c9..5c955f2b 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -16,7 +16,6 @@ use App\Entity\VehicleManufacturer; use App\Entity\Vehicle; use App\Entity\Hub; -use App\Service\InvoiceGeneratorInterface; use App\Service\JobOrderHandlerInterface; use App\Service\GISManagerInterface; use App\Service\MapTools; @@ -24,6 +23,7 @@ use App\Service\MQTTClient; use App\Service\APNSClient; use App\Service\InventoryManager; use App\Service\HubSelector; +use App\Service\InvoiceManager; use App\Service\RiderTracker; use App\Service\MotivConnector; @@ -713,7 +713,7 @@ class JobOrderController extends Controller } - public function generateInvoice(Request $req, InvoiceGeneratorInterface $ic) + public function generateInvoice(Request $req, InvoiceManager $ic) { // error_log('generating invoice...'); $error = false; @@ -724,8 +724,6 @@ class JobOrderController extends Controller $cvid = $req->request->get('cvid'); $service_charges = $req->request->get('service_charges', []); - // TODO: set if taxable here - $em = $this->getDoctrine()->getManager(); // get customer vehicle @@ -739,7 +737,8 @@ class JobOrderController extends Controller // instantiate invoice criteria $criteria = new InvoiceCriteria(); $criteria->setServiceType($stype) - ->setCustomerVehicle($cv); + ->setCustomerVehicle($cv) + ->setIsTaxable(); /* diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 4c5040dc..de3a63f5 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -29,6 +29,7 @@ use App\Entity\CustomerTag; use App\Entity\EmergencyType; use App\Entity\OwnershipType; use App\Entity\CustomerLocation; +use App\Entity\Battery; use App\Ramcar\ServiceType; use App\Ramcar\TradeInType; @@ -3442,8 +3443,19 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // db loaded $params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll(); + $params['trade_in_bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); + // list of batteries for trade-in + $ti_batteries = $em->getRepository(Battery::class)->findAll(); + $trade_in_batteries = []; + foreach ($ti_batteries as $ti_battery) + { + $battery_name = $ti_battery->getModel()->getName() . ' ' . $ti_battery->getSize()->getName(); + $trade_in_batteries[$ti_battery->getID()] = $battery_name; + } + $params['trade_in_batteries'] = $trade_in_batteries; + // list of emergency types $e_types = $em->getRepository(EmergencyType::class)->findBy([], ['name' => 'ASC']); $emergency_types = []; diff --git a/templates/invoice/trade_in.html.twig b/templates/invoice/trade_in.html.twig new file mode 100644 index 00000000..e033143d --- /dev/null +++ b/templates/invoice/trade_in.html.twig @@ -0,0 +1,46 @@ +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+
+ +
+
diff --git a/templates/invoice/trade_in.js.twig b/templates/invoice/trade_in.js.twig new file mode 100644 index 00000000..a93fce56 --- /dev/null +++ b/templates/invoice/trade_in.js.twig @@ -0,0 +1,17 @@ +// add trade in battery to invoice +$('#btn-add-trade-in-to-invoice').click(function() { + var bmfg = $("#invoice-trade-in-bmfg").val(); + var battery = $("#invoice-trade-in-battery").val(); + var tradeIn = $("#invoice-trade-in-type").val(); + var qty = $("#invoice-trade-in-quantity").val(); + + // add to invoice array + invoiceItems.push({ + battery: battery, + quantity: qty, + trade_in: tradeIn, + }); + + // regenerate the invoice + generateInvoice(); +}); diff --git a/templates/job-order/form.html.twig b/templates/job-order/form.html.twig index 95c548b5..b2e17e34 100644 --- a/templates/job-order/form.html.twig +++ b/templates/job-order/form.html.twig @@ -715,6 +715,7 @@ +
@@ -748,6 +750,7 @@
+ {% include('invoice/trade_in.html.twig') %} {% endif %} @@ -1190,7 +1193,6 @@