Merge branch '343-cmb-discount' into '270-final-cmb-fixes'

Change computation of discount for CMB. #343

See merge request jankstudio/resq!385
This commit is contained in:
Kendrick Chan 2020-02-17 06:21:50 +00:00
commit 6656890fd8
8 changed files with 105 additions and 64 deletions

View file

@ -605,7 +605,7 @@ class JobOrderController extends Controller
* @Menu(selected="jo_all") * @Menu(selected="jo_all")
*/ */
public function allForm($id, JobOrderHandlerInterface $jo_handler, public function allForm($id, JobOrderHandlerInterface $jo_handler,
GISManagerInterface $gis) GISManagerInterface $gis, EntityManagerInterface $em)
{ {
$this->denyAccessUnlessGranted('jo_all.list', null, 'No access.'); $this->denyAccessUnlessGranted('jo_all.list', null, 'No access.');
@ -618,6 +618,8 @@ class JobOrderController extends Controller
throw $this->createNotFoundException($e->getMessage()); throw $this->createNotFoundException($e->getMessage());
} }
$params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll();
$params['vmakes'] = $em->getRepository(Vehicle::class)->findAll();
$params['return_url'] = $this->generateUrl('jo_all'); $params['return_url'] = $this->generateUrl('jo_all');
$params['submit_url'] = ''; $params['submit_url'] = '';
$params['map_js_file'] = $gis->getJSJOFile(); $params['map_js_file'] = $gis->getJSJOFile();
@ -736,7 +738,7 @@ class JobOrderController extends Controller
*/ */
// TODO: this snippet should be in the invoice generator // TODO: this snippet should be in the invoice generator
$error = $ic->invoicePromo($criteria, $promo_id); $error = $ic->validateDiscount($criteria, $promo_id);
if (!$error) if (!$error)
$error = $ic->invoiceBatteries($criteria, $items); $error = $ic->invoiceBatteries($criteria, $items);

View file

@ -280,6 +280,12 @@ class JobOrder
*/ */
protected $hub_rejections; protected $hub_rejections;
// meta
/**
* @ORM\Column(type="json")
*/
protected $meta;
public function __construct() public function __construct()
{ {
$this->date_create = new DateTime(); $this->date_create = new DateTime();
@ -297,6 +303,8 @@ class JobOrder
$this->trade_in_type = null; $this->trade_in_type = null;
$this->flag_rider_rating = false; $this->flag_rider_rating = false;
$this->flag_coolant = false; $this->flag_coolant = false;
$this->meta = [];
} }
public function getID() public function getID()
@ -802,4 +810,15 @@ class JobOrder
{ {
return $this->hub_rejections; return $this->hub_rejections;
} }
public function addMeta($id, $value)
{
$this->meta[$id] = $value;
return $this;
}
public function getMeta($id)
{
return $this->meta[$id];
}
} }

View file

@ -12,6 +12,7 @@ class InvoiceCriteria
protected $promos; protected $promos;
protected $cv; protected $cv;
protected $flag_coolant; protected $flag_coolant;
protected $discount;
// entries are battery and trade-in combos // entries are battery and trade-in combos
protected $entries; protected $entries;
@ -23,6 +24,7 @@ class InvoiceCriteria
$this->entries = []; $this->entries = [];
$this->cv = null; $this->cv = null;
$this->flag_coolant = false; $this->flag_coolant = false;
$this->discount = 0;
} }
public function setServiceType($stype) public function setServiceType($stype)
@ -125,4 +127,15 @@ class InvoiceCriteria
{ {
return $this->flag_coolant; return $this->flag_coolant;
} }
public function setDiscount($discount)
{
$this->discount = $discount;
return $this;
}
public function getDiscount()
{
return $this->discount;
}
} }

View file

@ -17,7 +17,6 @@ use App\Ramcar\FuelType;
use App\Entity\Invoice; use App\Entity\Invoice;
use App\Entity\InvoiceItem; use App\Entity\InvoiceItem;
use App\Entity\Battery; use App\Entity\Battery;
use App\Entity\Promo;
use App\Entity\User; use App\Entity\User;
use App\Service\InvoiceGeneratorInterface; use App\Service\InvoiceGeneratorInterface;
@ -106,10 +105,6 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
// break; // break;
} }
// TODO: check if any promo is applied
// apply discounts
$promos = $criteria->getPromos();
// get current user // get current user
$user = $this->security->getUser(); $user = $this->security->getUser();
if ($user != null) if ($user != null)
@ -140,7 +135,8 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
$criteria->setServiceType($jo->getServiceType()) $criteria->setServiceType($jo->getServiceType())
->setCustomerVehicle($jo->getCustomerVehicle()); ->setCustomerVehicle($jo->getCustomerVehicle());
$ierror = $this->invoicePromo($criteria, $promo_id); $discount = $promo_id;
$ierror = $this->validateDiscount($criteria, $discount);
if (!$ierror && !empty($invoice_items)) if (!$ierror && !empty($invoice_items))
{ {
@ -224,27 +220,26 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
return 0; return 0;
} }
public function invoicePromo(InvoiceCriteria $criteria, $promo_id) public function validateDiscount(InvoiceCriteria $criteria, $discount)
{ {
// return error if there's a problem, false otherwise // return error if there's a problem, false otherwise
// check service type // check service type
$stype = $criteria->getServiceType(); $stype = $criteria->getServiceType();
if ($stype != CMBServiceType::BATTERY_REPLACEMENT_NEW) if ($stype != CMBServiceType::BATTERY_REPLACEMENT_NEW)
return null; return null;
// check if discount is blank or 0
if (empty($promo_id)) if ((empty($discount)) || ($discount == 0))
{ {
return false; return false;
} }
// check if this is a valid promo // check if discount is greater than 50 or negative number
$promo = $this->em->getRepository(Promo::class)->find($promo_id); if (($discount > 50) || ($discount < 0))
return 'Invalid discount specified';
if (empty($promo)) $criteria->setDiscount($discount);
return 'Invalid promo specified.';
$criteria->addPromo($promo);
return false; return false;
} }
@ -389,33 +384,14 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
protected function processDiscount(&$total, InvoiceCriteria $criteria, Invoice $invoice) protected function processDiscount(&$total, InvoiceCriteria $criteria, Invoice $invoice)
{ {
$promos = $criteria->getPromos(); $discount = $criteria->getDiscount();
if (count($promos) < 1)
return;
// 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;
}
// if discount is higher than 0, display in invoice // if discount is higher than 0, display in invoice
if ($discount > 0) if ($discount > 0)
{ {
$item = new InvoiceItem(); $item = new InvoiceItem();
$item->setInvoice($invoice) $item->setInvoice($invoice)
->setTitle('Promo discount') ->setTitle('Discount')
->setQuantity(1) ->setQuantity(1)
->setPrice(-1 * $discount); ->setPrice(-1 * $discount);
$invoice->addItem($item); $invoice->addItem($item);
@ -425,7 +401,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
$total['total_price'] -= $discount; $total['total_price'] -= $discount;
// process // process
$invoice->setPromo($promo); $invoice->setDiscount($discount);
} }
protected function processJumpstart(&$total, $invoice) protected function processJumpstart(&$total, $invoice)

View file

@ -18,6 +18,7 @@ use App\Entity\Invoice;
use App\Entity\InvoiceItem; use App\Entity\InvoiceItem;
use App\Entity\User; use App\Entity\User;
use App\Entity\Battery; use App\Entity\Battery;
use App\Entity\Promo;
use App\Service\InvoiceGeneratorInterface; use App\Service\InvoiceGeneratorInterface;

View file

@ -522,6 +522,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
} }
} }
// get discount and set to meta
$discount = $req->request->get('invoice_promo');
// check if discount is greater than 50 or negative number
if (($discount > 50) || ($discount < 0))
$error_array['invoice_promo'] = 'Invalid discount specified';
if (empty($error_array)) if (empty($error_array))
{ {
// get current user // get current user
@ -551,7 +558,9 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
->setHub($hub) ->setHub($hub)
->setRider($rider); ->setRider($rider);
// check if user is null, meaning call to create came from API $jo->addMeta('discount', $discount);
// check if user is null, meaning call to create came from API
if ($user != null) if ($user != null)
{ {
$jo->setCreatedBy($user); $jo->setCreatedBy($user);
@ -2488,6 +2497,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$hub_coordinates = $hub->getCoordinates(); $hub_coordinates = $hub->getCoordinates();
} }
// get discount and set to meta
$discount = $req->request->get('invoice_promo');
// check if discount is greater than 50 or negative number
if (($discount > 50) || ($discount < 0))
$error_array['invoice_promo'] = 'Invalid discount specified';
if (empty($error_array)) if (empty($error_array))
{ {
// get current user // get current user
@ -2513,6 +2529,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
->setCoordinates($hub_coordinates) ->setCoordinates($hub_coordinates)
->setHub($hub); ->setHub($hub);
$jo->addMeta('discount', $discount);
// check if user is null, meaning call to create came from API // check if user is null, meaning call to create came from API
if ($user != null) if ($user != null)
{ {

View file

@ -500,22 +500,13 @@
<div class="col-lg-6"> <div class="col-lg-6">
<label>Discount Type</label> <label>Discount Type</label>
{% if ftags.invoice_edit %} {% if ftags.invoice_edit %}
<select class="form-control m-input" id="invoice-promo" name="invoice_promo"> <input type="number" id="invoice-promo" name="invoice_promo" class="form-control m-input min = "0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}">
<option value="">None</option>
{% for promo in promos %}
<option value="{{ promo.getID() }}">{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="invoice_promo"></div> <div class="form-control-feedback hide" data-field="invoice_promo"></div>
{% else %} {% else %}
<input type="text" id="invoice-promo" class="form-control m-input" value="{{ obj.getInvoice.getPromo.getName|default('None') }}" disabled> <input type="number" id="invoice-promo" name="invoice_promo" class="form-control m-input min="0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}" disabled>
{% endif %} {% endif %}
</div> </div>
<div class="col-lg-3"> <div class="col-lg-6">
<label>Promo Discount</label>
<input type="text" id="invoice-promo-discount" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount|number_format(2) : '0.00' }}" disabled>
</div>
<div class="col-lg-3">
<label>Trade In</label> <label>Trade In</label>
<input type="text" id="invoice-trade-in" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getTradeIn|number_format(2) : '0.00' }}" disabled> <input type="text" id="invoice-trade-in" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getTradeIn|number_format(2) : '0.00' }}" disabled>
</div> </div>
@ -1277,6 +1268,21 @@ $(function() {
var invoiceItems = []; var invoiceItems = [];
// populate invoiceItems if editing so that we don't lose the battery
{% if mode in ['open-edit', 'onestep-edit', 'walk-in-edit'] %}
{% if (obj.getInvoice and obj.getInvoice.getItems|length > 0) %}
{% for item in obj.getInvoice.getItems %}
{% if item.getBattery() %}
invoiceItems.push({
battery: {{ item.getBattery().getID() }},
quantity: {{ item.getQuantity() }},
trade_in: {{ obj.getInvoice().getTradeIn }},
});
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
// add to invoice // add to invoice
$("#btn-add-to-invoice").click(function() { $("#btn-add-to-invoice").click(function() {
var bmfg = $("#invoice-bmfg").val(); var bmfg = $("#invoice-bmfg").val();

View file

@ -395,22 +395,13 @@
<div class="col-lg-6"> <div class="col-lg-6">
<label>Discount Type</label> <label>Discount Type</label>
{% if ftags.invoice_edit %} {% if ftags.invoice_edit %}
<select class="form-control m-input" id="invoice-promo" name="invoice_promo"> <input type="number" id="invoice-promo" name="invoice_promo" class="form-control m-input min = "0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}">
<option value="">None</option>
{% for promo in promos %}
<option value="{{ promo.getID() }}">{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="invoice_promo"></div> <div class="form-control-feedback hide" data-field="invoice_promo"></div>
{% else %} {% else %}
<input type="text" id="invoice-promo" class="form-control m-input" value="{{ obj.getInvoice.getPromo.getName|default('None') }}" disabled> <input type="number" id="invoice-promo" name="invoice_promo" class="form-control m-input min="0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}" disabled>
{% endif %} {% endif %}
</div> </div>
<div class="col-lg-3"> <div class="col-lg-6">
<label>Promo Discount</label>
<input type="text" id="invoice-promo-discount" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount|number_format(2) : '0.00' }}" disabled>
</div>
<div class="col-lg-3">
<label>Trade In</label> <label>Trade In</label>
<input type="text" id="invoice-trade-in" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getTradeIn|number_format(2) : '0.00' }}" disabled> <input type="text" id="invoice-trade-in" class="form-control m-input text-right" value="{{ obj.getInvoice ? obj.getInvoice.getTradeIn|number_format(2) : '0.00' }}" disabled>
</div> </div>
@ -892,6 +883,21 @@ var vdata = false;
var invoiceItems = []; var invoiceItems = [];
// populate invoiceItems if editing so that we don't lose the battery
{% if mode in ['open-edit', 'onestep-edit', 'walk-in-edit'] %}
{% if (obj.getInvoice and obj.getInvoice.getItems|length > 0) %}
{% for item in obj.getInvoice.getItems %}
{% if item.getBattery() %}
invoiceItems.push({
battery: {{ item.getBattery().getID() }},
quantity: {{ item.getQuantity() }},
trade_in: {{ obj.getInvoice().getTradeIn }},
});
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
// add to invoice // add to invoice
$("#btn-add-to-invoice").click(function() { $("#btn-add-to-invoice").click(function() {
var bmfg = $("#invoice-bmfg").val(); var bmfg = $("#invoice-bmfg").val();