From 49317188c947feac527b8d5ba4c4d942bbc5c266 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 31 May 2023 03:57:30 -0400 Subject: [PATCH] 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; } }