Add battery size id to invoice item. Add saving of trade in items with battery size to invoice item. #803
This commit is contained in:
parent
cec648f894
commit
4b5ad97225
6 changed files with 151 additions and 27 deletions
|
|
@ -50,6 +50,13 @@ class InvoiceItem
|
||||||
*/
|
*/
|
||||||
protected $battery;
|
protected $battery;
|
||||||
|
|
||||||
|
// battery size for trade in items
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="BatterySize")
|
||||||
|
* @ORM\JoinColumn(name="battery_size_id", referencedColumnName="id")
|
||||||
|
*/
|
||||||
|
protected $battery_size;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->title = '';
|
$this->title = '';
|
||||||
|
|
@ -115,4 +122,15 @@ class InvoiceItem
|
||||||
{
|
{
|
||||||
return $this->battery;
|
return $this->battery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setBatterySize(BatterySize $battery_size)
|
||||||
|
{
|
||||||
|
$this->battery_size = $battery_size;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBatterySize()
|
||||||
|
{
|
||||||
|
return $this->battery_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,14 +117,19 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// if this is a trade in, add trade in
|
// if this is a trade in, add trade in
|
||||||
|
/*
|
||||||
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
||||||
$trade_in = $item['trade_in'];
|
$trade_in = $item['trade_in'];
|
||||||
else
|
else
|
||||||
$trade_in = null;
|
$trade_in = null; */
|
||||||
|
|
||||||
|
if (empty($item['trade_in']))
|
||||||
|
{
|
||||||
|
$trade_in = null;
|
||||||
$criteria->addEntry($battery, $trade_in, $qty);
|
$criteria->addEntry($battery, $trade_in, $qty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,24 @@
|
||||||
|
|
||||||
namespace App\InvoiceRule;
|
namespace App\InvoiceRule;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
use App\InvoiceRuleInterface;
|
use App\InvoiceRuleInterface;
|
||||||
|
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
|
use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
|
use App\Entity\Battery;
|
||||||
|
|
||||||
class TradeIn implements InvoiceRuleInterface
|
class TradeIn implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
|
protected $em;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em)
|
||||||
|
{
|
||||||
|
$this->em = $em;
|
||||||
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
{
|
{
|
||||||
return 'trade-in';
|
return 'trade-in';
|
||||||
|
|
@ -32,12 +44,12 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
// at this point, entry is a trade in
|
// at this point, entry is a trade in
|
||||||
// need to check if battery (coming from CRM) is set
|
// need to check if battery (coming from CRM) is set
|
||||||
// or battery_size is set (coming from rider app)
|
// or battery_size is set (coming from rider app)
|
||||||
if (isset($entry['battery']))
|
//if (isset($entry['battery']))
|
||||||
{
|
//{
|
||||||
$battery = $entry['battery'];
|
// $battery = $entry['battery'];
|
||||||
$batt_size = $battery->getSize();
|
// $batt_size = $battery->getSize();
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
$batt_size = $entry['battery_size'];
|
$batt_size = $entry['battery_size'];
|
||||||
|
|
||||||
$ti_rate = $this->getTradeInRate($batt_size, $trade_in_type);
|
$ti_rate = $this->getTradeInRate($batt_size, $trade_in_type);
|
||||||
|
|
@ -50,6 +62,7 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
$price = bcmul($ti_rate, -1, 2);
|
$price = bcmul($ti_rate, -1, 2);
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
|
'battery_size' => $batt_size,
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'title' => $this->getTitle($batt_size, $trade_in_type),
|
'title' => $this->getTitle($batt_size, $trade_in_type),
|
||||||
'price' => $price,
|
'price' => $price,
|
||||||
|
|
@ -67,6 +80,41 @@ class TradeIn implements InvoiceRuleInterface
|
||||||
|
|
||||||
public function validateInvoiceItems($criteria, $invoice_items)
|
public function validateInvoiceItems($criteria, $invoice_items)
|
||||||
{
|
{
|
||||||
|
// check service type. Only battery sales and battery warranty should have invoice items. Since this is the battery sales
|
||||||
|
// rule, we only check for battery sales.
|
||||||
|
$stype = $criteria->getServiceType();
|
||||||
|
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// return error if there's a problem, false otherwise
|
||||||
|
if (!empty($invoice_items))
|
||||||
|
{
|
||||||
|
// check if this is a valid battery
|
||||||
|
foreach ($invoice_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'];
|
||||||
|
$battery_size = $battery->getSize();
|
||||||
|
$criteria->addTradeInEntry($battery_size, $trade_in, $qty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
new InvoiceRule\Fuel($this->em, $this->pt_manager),
|
new InvoiceRule\Fuel($this->em, $this->pt_manager),
|
||||||
new InvoiceRule\TireRepair($this->em, $this->pt_manager),
|
new InvoiceRule\TireRepair($this->em, $this->pt_manager),
|
||||||
new InvoiceRule\DiscountType($this->em),
|
new InvoiceRule\DiscountType($this->em),
|
||||||
new InvoiceRule\TradeIn(),
|
new InvoiceRule\TradeIn($this->em),
|
||||||
new InvoiceRule\Tax($this->em, $this->pt_manager),
|
new InvoiceRule\Tax($this->em, $this->pt_manager),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +166,7 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
// (3) generateInvoiceCriteria
|
// (3) generateInvoiceCriteria
|
||||||
// (4) RiderAPIHandler's changeService
|
// (4) RiderAPIHandler's changeService
|
||||||
// (5) TAPI's JobOrderController
|
// (5) TAPI's JobOrderController
|
||||||
|
// (6) CAPI's RiderAppController
|
||||||
public function generateInvoice($criteria)
|
public function generateInvoice($criteria)
|
||||||
{
|
{
|
||||||
// no need to validate since generateDraftInvoice was called before this was called
|
// no need to validate since generateDraftInvoice was called before this was called
|
||||||
|
|
@ -214,17 +215,22 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
$price = $item['price'];
|
$price = $item['price'];
|
||||||
|
|
||||||
$battery = null;
|
$battery = null;
|
||||||
|
$battery_size = null;
|
||||||
if (isset($item['battery']))
|
if (isset($item['battery']))
|
||||||
$battery = $item['battery'];
|
$battery = $item['battery'];
|
||||||
|
|
||||||
if (isset($item['promo']))
|
if (isset($item['promo']))
|
||||||
$promo = $item['promo'];
|
$promo = $item['promo'];
|
||||||
|
|
||||||
|
if (isset($item['battery_size']))
|
||||||
|
$battery_size = $item['battery_size'];
|
||||||
|
|
||||||
$invoice_items[] = [
|
$invoice_items[] = [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'quantity' => $quantity,
|
'quantity' => $quantity,
|
||||||
'price' => $price,
|
'price' => $price,
|
||||||
'battery' => $battery,
|
'battery' => $battery,
|
||||||
|
'battery_size' => $battery_size,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,6 +284,9 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
if ($item['battery'] != null)
|
if ($item['battery'] != null)
|
||||||
$invoice_item->setBattery($item['battery']);
|
$invoice_item->setBattery($item['battery']);
|
||||||
|
|
||||||
|
if ($item['battery_size'] != null)
|
||||||
|
$invoice_item->setBatterySize($item['battery_size']);
|
||||||
|
|
||||||
$invoice->addItem($invoice_item);
|
$invoice->addItem($invoice_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2312,6 +2312,13 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$em = $this->em;
|
$em = $this->em;
|
||||||
$jo = $em->getRepository(JobOrder::class)->find($id);
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
||||||
|
|
||||||
|
// get the job order's invoice items
|
||||||
|
$invoice = $jo->getInvoice();
|
||||||
|
$invoice_items = [];
|
||||||
|
if ($invoice != null)
|
||||||
|
$invoice_items = $invoice->getItems();
|
||||||
|
|
||||||
|
$params['invoice_items'] = $invoice_items;
|
||||||
$params['obj'] = $jo;
|
$params['obj'] = $jo;
|
||||||
$params['mode'] = 'open_edit';
|
$params['mode'] = 'open_edit';
|
||||||
$params['cvid'] = $jo->getCustomerVehicle()->getID();
|
$params['cvid'] = $jo->getCustomerVehicle()->getID();
|
||||||
|
|
|
||||||
|
|
@ -636,7 +636,11 @@
|
||||||
<select class="form-control m-input" id="invoice-promo" name="invoice_promo">
|
<select class="form-control m-input" id="invoice-promo" name="invoice_promo">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
{% for promo in promos %}
|
{% for promo in promos %}
|
||||||
|
{% if obj.getInvoice and obj.getInvoice.getPromo %}
|
||||||
|
<option value="{{ promo.getID() }}" {{ obj.getInvoice.getPromo.getID == promo.getID ? ' selected'}}>{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
|
||||||
|
{% else %}
|
||||||
<option value="{{ promo.getID() }}">{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
|
<option value="{{ promo.getID() }}">{{ promo.getName() ~ ' (' ~ promo.getDiscountRate * 100 ~ '% applied to ' ~ discount_apply[promo.getDiscountApply] ~ ')' }}</option>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<div class="form-control-feedback hide" data-field="invoice_promo"></div>
|
<div class="form-control-feedback hide" data-field="invoice_promo"></div>
|
||||||
|
|
@ -1194,6 +1198,8 @@
|
||||||
<script src="/assets/vendors/custom/gmaps/gmaps.js" type="text/javascript"></script>
|
<script src="/assets/vendors/custom/gmaps/gmaps.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var invoiceItems = [];
|
||||||
|
|
||||||
// location search autocomplete
|
// location search autocomplete
|
||||||
var input = document.getElementById('m_gmap_address');
|
var input = document.getElementById('m_gmap_address');
|
||||||
|
|
||||||
|
|
@ -1218,6 +1224,7 @@ autocomplete.addListener('place_changed', function() {
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
var form_in_process = false;
|
var form_in_process = false;
|
||||||
|
var invoiceItems = [];
|
||||||
|
|
||||||
// openstreet maps stuff
|
// openstreet maps stuff
|
||||||
// TODO: move this to a service
|
// TODO: move this to a service
|
||||||
|
|
@ -1228,8 +1235,30 @@ $(function() {
|
||||||
|
|
||||||
var markerLayerGroup = L.layerGroup().addTo(osm_map);
|
var markerLayerGroup = L.layerGroup().addTo(osm_map);
|
||||||
|
|
||||||
|
function populateInvoiceItems()
|
||||||
|
{
|
||||||
|
console.log('populateInvoiceItems start');
|
||||||
|
{% if invoice_items is defined %}
|
||||||
|
{% for item in invoice_items %}
|
||||||
|
{% if item.getBattery is not null %}
|
||||||
|
var battery_id = {{ item.getBattery.getID }};
|
||||||
|
var qty = {{ item.getQuantity }};
|
||||||
|
|
||||||
|
console.log(battery_id);
|
||||||
|
{% else %}
|
||||||
|
// check if it's a trade in entry
|
||||||
|
var title = '{{ item.getTitle }}';
|
||||||
|
if (title.includes('Trade-in')) {
|
||||||
|
console.log(title + ' a trade in');
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
function selectPoint(lat, lng)
|
function selectPoint(lat, lng)
|
||||||
{
|
{
|
||||||
|
console.log('selectPoint start');
|
||||||
// check if point is in coverage area
|
// check if point is in coverage area
|
||||||
// commenting out the geofence call for CRM
|
// commenting out the geofence call for CRM
|
||||||
/*
|
/*
|
||||||
|
|
@ -1267,11 +1296,12 @@ $(function() {
|
||||||
$('#map_lng').val(lng);
|
$('#map_lng').val(lng);
|
||||||
|
|
||||||
// regenerate invoice
|
// regenerate invoice
|
||||||
generateInvoice();
|
// generateInvoice();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osm_map.on('click', function(e) {
|
osm_map.on('click', function(e) {
|
||||||
|
console.log('point clicked');
|
||||||
selectPoint(e.latlng.lat, e.latlng.lng);
|
selectPoint(e.latlng.lat, e.latlng.lng);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1285,6 +1315,7 @@ $(function() {
|
||||||
console.log(results);
|
console.log(results);
|
||||||
var lat = results[0].geometry.location.lat();
|
var lat = results[0].geometry.location.lat();
|
||||||
var lng = results[0].geometry.location.lng();
|
var lng = results[0].geometry.location.lng();
|
||||||
|
console.log('geocode point clicked');
|
||||||
selectPoint(lat, lng);
|
selectPoint(lat, lng);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1312,6 +1343,14 @@ $(function() {
|
||||||
// OSM code
|
// OSM code
|
||||||
var lat = {{ obj.getCoordinates.getLatitude }};
|
var lat = {{ obj.getCoordinates.getLatitude }};
|
||||||
var lng = {{ obj.getCoordinates.getLongitude }};
|
var lng = {{ obj.getCoordinates.getLongitude }};
|
||||||
|
|
||||||
|
console.log('set coordinate point clicked');
|
||||||
|
|
||||||
|
var promo = $("#invoice-promo").val();
|
||||||
|
console.log(promo);
|
||||||
|
|
||||||
|
populateInvoiceItems();
|
||||||
|
|
||||||
selectPoint(lat, lng);
|
selectPoint(lat, lng);
|
||||||
|
|
||||||
// remove placeholder text
|
// remove placeholder text
|
||||||
|
|
@ -1695,8 +1734,6 @@ $(function() {
|
||||||
placeholder: ""
|
placeholder: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
var invoiceItems = [];
|
|
||||||
|
|
||||||
{% include 'invoice/trade_in.js.twig' %}
|
{% include 'invoice/trade_in.js.twig' %}
|
||||||
|
|
||||||
// add to invoice
|
// add to invoice
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue