Add discount type rule and test cases. #744
This commit is contained in:
parent
725704e951
commit
f760b2c02a
3 changed files with 326 additions and 6 deletions
|
|
@ -16,6 +16,7 @@ use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\CustomerVehicle;
|
use App\Entity\CustomerVehicle;
|
||||||
|
use App\Entity\Promo;
|
||||||
|
|
||||||
class TestInvoiceManagerCommand extends Command
|
class TestInvoiceManagerCommand extends Command
|
||||||
{
|
{
|
||||||
|
|
@ -66,7 +67,18 @@ class TestInvoiceManagerCommand extends Command
|
||||||
$this->testBatterySalesTradeInQuantityNoDiscountWithoutTax();
|
$this->testBatterySalesTradeInQuantityNoDiscountWithoutTax();
|
||||||
|
|
||||||
// battery sales with discount with tax
|
// battery sales with discount with tax
|
||||||
|
$this->testBatterySalesNoTradeInWithDiscountWithTax();
|
||||||
|
|
||||||
// battery sales with discount without tax
|
// 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
|
// battery replacement warranty with tax
|
||||||
$this->testBatteryReplacementWarrantyWithTax();
|
$this->testBatteryReplacementWarrantyWithTax();
|
||||||
|
|
@ -126,8 +138,6 @@ class TestInvoiceManagerCommand extends Command
|
||||||
$this->testTireRepairWithServiceFeeWithoutTax();
|
$this->testTireRepairWithServiceFeeWithoutTax();
|
||||||
$this->testTireRepairWithoutServiceFeeWithoutTax();
|
$this->testTireRepairWithoutServiceFeeWithoutTax();
|
||||||
|
|
||||||
// TEST SCENARIO: new battery with discount
|
|
||||||
// TEST SCENARIO: new battery with discount and trade-in
|
|
||||||
return 0;
|
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
|
// battery replacement warranty with tax
|
||||||
protected function testBatteryReplacementWarrantyWithTax()
|
protected function testBatteryReplacementWarrantyWithTax()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -42,15 +42,44 @@ class DiscountType implements InvoiceInterface
|
||||||
switch ($apply_to)
|
switch ($apply_to)
|
||||||
{
|
{
|
||||||
case DiscountApply::SRP:
|
case DiscountApply::SRP:
|
||||||
$discount = round($total['sell_price'] * $rate, 2);
|
$discount = bcmul($total['sell_price'], $rate, 2);
|
||||||
break;
|
break;
|
||||||
case DiscountApply::OPL:
|
case DiscountApply::OPL:
|
||||||
// $discount = round($total['sell_price'] * 0.6 / 0.7 * $rate, 2);
|
// $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;
|
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;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getTitle()
|
||||||
|
{
|
||||||
|
$title = 'Promo discount';
|
||||||
|
|
||||||
|
return $title;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,10 +162,15 @@ class InvoiceManager
|
||||||
{
|
{
|
||||||
if (isset($active_rules['discount_type']))
|
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)
|
foreach ($items as $item)
|
||||||
{
|
{
|
||||||
$invoice_item = new InvoiceItem();
|
$invoice_item = new InvoiceItem();
|
||||||
|
|
@ -177,11 +182,15 @@ class InvoiceManager
|
||||||
if (isset($item['battery']))
|
if (isset($item['battery']))
|
||||||
$invoice_item->setBattery($item['battery']);
|
$invoice_item->setBattery($item['battery']);
|
||||||
|
|
||||||
|
if (isset($item['promo']))
|
||||||
|
$promo = $item['promo'];
|
||||||
|
|
||||||
$invoice_items[] = $invoice_item;
|
$invoice_items[] = $invoice_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
// also need to return the total
|
// also need to return the total and the promo
|
||||||
$data[] = [
|
$data[] = [
|
||||||
|
'promo' => $promo,
|
||||||
'invoice_items' => $invoice_items,
|
'invoice_items' => $invoice_items,
|
||||||
'total' => $total,
|
'total' => $total,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue