Add price tier checking for battery sales. #782
This commit is contained in:
parent
29ad8d57a4
commit
b6763bfd3e
10 changed files with 141 additions and 16 deletions
|
|
@ -310,3 +310,8 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$server_key: "%env(FCM_SERVER_KEY)%"
|
$server_key: "%env(FCM_SERVER_KEY)%"
|
||||||
$sender_id: "%env(FCM_SENDER_ID)%"
|
$sender_id: "%env(FCM_SENDER_ID)%"
|
||||||
|
|
||||||
|
# price tier manager
|
||||||
|
App\Service\PriceTierManager:
|
||||||
|
arguments:
|
||||||
|
$em: "@doctrine.orm.entity_manager"
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ use App\Service\HubSelector;
|
||||||
|
|
||||||
use App\Service\RiderTracker;
|
use App\Service\RiderTracker;
|
||||||
use App\Service\MotivConnector;
|
use App\Service\MotivConnector;
|
||||||
|
use App\Service\PriceTierManager;
|
||||||
|
|
||||||
use App\Service\GeofenceTracker;
|
use App\Service\GeofenceTracker;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
@ -42,6 +43,8 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
use Catalyst\MenuBundle\Annotation\Menu;
|
use Catalyst\MenuBundle\Annotation\Menu;
|
||||||
|
|
||||||
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||||
|
|
||||||
class JobOrderController extends Controller
|
class JobOrderController extends Controller
|
||||||
{
|
{
|
||||||
public function getJobOrders(Request $req, JobOrderHandlerInterface $jo_handler)
|
public function getJobOrders(Request $req, JobOrderHandlerInterface $jo_handler)
|
||||||
|
|
@ -741,7 +744,7 @@ class JobOrderController extends Controller
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateInvoice(Request $req, InvoiceGeneratorInterface $ic)
|
public function generateInvoice(Request $req, InvoiceGeneratorInterface $ic, PriceTierManager $pt_manager)
|
||||||
{
|
{
|
||||||
// error_log('generating invoice...');
|
// error_log('generating invoice...');
|
||||||
$error = false;
|
$error = false;
|
||||||
|
|
@ -752,6 +755,19 @@ class JobOrderController extends Controller
|
||||||
$cvid = $req->request->get('cvid');
|
$cvid = $req->request->get('cvid');
|
||||||
$service_charges = $req->request->get('service_charges', []);
|
$service_charges = $req->request->get('service_charges', []);
|
||||||
|
|
||||||
|
// coordinates
|
||||||
|
// need to check if lng and lat are set
|
||||||
|
$lng = $req->request->get('coord_lng', 0);
|
||||||
|
$lat = $req->request->get('coord_lat', 0);
|
||||||
|
|
||||||
|
$price_tier = 0;
|
||||||
|
if (($lng != 0) && ($lat != 0))
|
||||||
|
{
|
||||||
|
$coordinates = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
||||||
|
$price_tier = $pt_manager->getPriceTier($coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
// get customer vehicle
|
// get customer vehicle
|
||||||
|
|
@ -767,8 +783,8 @@ class JobOrderController extends Controller
|
||||||
$criteria->setServiceType($stype)
|
$criteria->setServiceType($stype)
|
||||||
->setCustomerVehicle($cv)
|
->setCustomerVehicle($cv)
|
||||||
->setIsTaxable()
|
->setIsTaxable()
|
||||||
->setSource(TransactionOrigin::CALL);
|
->setSource(TransactionOrigin::CALL)
|
||||||
|
->setPriceTier($price_tier);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// if it's a jumpstart or troubleshoot only, we know what to charge already
|
// if it's a jumpstart or troubleshoot only, we know what to charge already
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,19 @@ use App\Ramcar\TradeInType;
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
|
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
|
use App\Entity\ItemType;
|
||||||
|
|
||||||
|
use App\Service\PriceTierManager;
|
||||||
|
|
||||||
class BatterySales implements InvoiceRuleInterface
|
class BatterySales implements InvoiceRuleInterface
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $em;
|
||||||
|
protected $pt_manager;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em)
|
public function __construct(EntityManagerInterface $em, PriceTierManager $pt_manager)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
|
$this->pt_manager = $pt_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
|
|
@ -28,6 +33,9 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
public function compute($criteria, &$total)
|
public function compute($criteria, &$total)
|
||||||
{
|
{
|
||||||
$stype = $criteria->getServiceType();
|
$stype = $criteria->getServiceType();
|
||||||
|
$pt = $criteria->getPriceTier();
|
||||||
|
|
||||||
|
error_log('price tier ' . $pt);
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
if ($stype == $this->getID())
|
if ($stype == $this->getID())
|
||||||
|
|
@ -47,8 +55,13 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
|
|
||||||
if ($trade_in == null)
|
if ($trade_in == null)
|
||||||
{
|
{
|
||||||
// battery purchase
|
// check if price tier has item price for battery
|
||||||
$price = $batt->getSellingPrice();
|
$pt_price = $this->getPriceTierItemPrice($pt, $batt);
|
||||||
|
|
||||||
|
if ($pt_price == null)
|
||||||
|
$price = $batt->getSellingPrice();
|
||||||
|
else
|
||||||
|
$price = $pt_price;
|
||||||
|
|
||||||
$items[] = [
|
$items[] = [
|
||||||
'service_type' => $this->getID(),
|
'service_type' => $this->getID(),
|
||||||
|
|
@ -114,6 +127,25 @@ class BatterySales implements InvoiceRuleInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getPriceTierItemPrice($pt_id, $batt)
|
||||||
|
{
|
||||||
|
// price tier is default
|
||||||
|
if ($pt_id == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// find the item type battery
|
||||||
|
$item_type = $this->em->getRepository(ItemType::class)->findOneBy(['code' => 'battery']);
|
||||||
|
if ($item_type == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$item_type_id = $item_type->getID();
|
||||||
|
$item_id = $batt->getID();
|
||||||
|
|
||||||
|
$price = $this->pt_manager->getItemPrice($pt_id, $item_type_id, $item_id);
|
||||||
|
|
||||||
|
return $price;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getTitle($battery)
|
protected function getTitle($battery)
|
||||||
{
|
{
|
||||||
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName();
|
$title = $battery->getModel()->getName() . ' ' . $battery->getSize()->getName();
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate invoice criteria
|
// generate invoice criteria
|
||||||
public function generateInvoiceCriteria($jo, $discount, $invoice_items, $source = null, &$error_array)
|
public function generateInvoiceCriteria($jo, $discount, $invoice_items, $price_tier = null, $source = null, &$error_array)
|
||||||
{
|
{
|
||||||
$em = $this->em;
|
$em = $this->em;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate invoice criteria
|
// generate invoice criteria
|
||||||
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source = null, &$error_array)
|
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $price_tier = null, $source = null, &$error_array)
|
||||||
{
|
{
|
||||||
$em = $this->em;
|
$em = $this->em;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Service;
|
||||||
|
|
||||||
use App\Entity\Invoice;
|
use App\Entity\Invoice;
|
||||||
use App\Entity\JobOrder;
|
use App\Entity\JobOrder;
|
||||||
|
use App\Entity\PriceTier;
|
||||||
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
|
|
||||||
|
|
@ -13,7 +14,7 @@ interface InvoiceGeneratorInterface
|
||||||
public function generateInvoice(InvoiceCriteria $criteria);
|
public function generateInvoice(InvoiceCriteria $criteria);
|
||||||
|
|
||||||
// generate invoice criteria
|
// generate invoice criteria
|
||||||
public function generateInvoiceCriteria(JobOrder $jo, int $promo_id, array $invoice_items, $source, array &$error_array);
|
public function generateInvoiceCriteria(JobOrder $jo, int $promo_id, array $invoice_items, $source, PriceTier $price_tier, array &$error_array);
|
||||||
|
|
||||||
// prepare draft for invoice
|
// prepare draft for invoice
|
||||||
public function generateDraftInvoice(InvoiceCriteria $criteria, int $promo_id, array $service_charges, array $items);
|
public function generateDraftInvoice(InvoiceCriteria $criteria, int $promo_id, array $service_charges, array $items);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||||
use App\InvoiceRule;
|
use App\InvoiceRule;
|
||||||
|
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
|
use App\Service\PriceTierManager;
|
||||||
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
use App\Ramcar\InvoiceStatus;
|
use App\Ramcar\InvoiceStatus;
|
||||||
|
|
@ -28,12 +29,14 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
protected $em;
|
protected $em;
|
||||||
protected $validator;
|
protected $validator;
|
||||||
protected $available_rules;
|
protected $available_rules;
|
||||||
|
protected $pt_manager;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, Security $security, ValidatorInterface $validator)
|
public function __construct(EntityManagerInterface $em, Security $security, ValidatorInterface $validator, PriceTierManager $pt_manager)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->security = $security;
|
$this->security = $security;
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
|
$this->pt_manager = $pt_manager;
|
||||||
|
|
||||||
$this->available_rules = $this->getAvailableRules();
|
$this->available_rules = $this->getAvailableRules();
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +45,7 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
{
|
{
|
||||||
// TODO: get list of invoice rules from .env or a json file?
|
// TODO: get list of invoice rules from .env or a json file?
|
||||||
return [
|
return [
|
||||||
new InvoiceRule\BatterySales($this->em),
|
new InvoiceRule\BatterySales($this->em, $this->pt_manager),
|
||||||
new InvoiceRule\BatteryReplacementWarranty($this->em),
|
new InvoiceRule\BatteryReplacementWarranty($this->em),
|
||||||
new InvoiceRule\Jumpstart($this->em),
|
new InvoiceRule\Jumpstart($this->em),
|
||||||
new InvoiceRule\JumpstartWarranty($this->em),
|
new InvoiceRule\JumpstartWarranty($this->em),
|
||||||
|
|
@ -58,12 +61,13 @@ class InvoiceManager implements InvoiceGeneratorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is called when JO is submitted
|
// this is called when JO is submitted
|
||||||
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, &$error_array)
|
public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $price_tier, &$error_array)
|
||||||
{
|
{
|
||||||
// instantiate the invoice criteria
|
// instantiate the invoice criteria
|
||||||
$criteria = new InvoiceCriteria();
|
$criteria = new InvoiceCriteria();
|
||||||
$criteria->setServiceType($jo->getServiceType())
|
$criteria->setServiceType($jo->getServiceType())
|
||||||
->setCustomerVehicle($jo->getCustomerVehicle());
|
->setCustomerVehicle($jo->getCustomerVehicle())
|
||||||
|
->setPriceTier($price_tier);
|
||||||
|
|
||||||
// set if taxable
|
// set if taxable
|
||||||
// NOTE: ideally, this should be a parameter when calling generateInvoiceCriteria. But that
|
// NOTE: ideally, this should be a parameter when calling generateInvoiceCriteria. But that
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ use App\Service\HubSelector;
|
||||||
use App\Service\HubDistributor;
|
use App\Service\HubDistributor;
|
||||||
use App\Service\HubFilteringGeoChecker;
|
use App\Service\HubFilteringGeoChecker;
|
||||||
use App\Service\JobOrderManager;
|
use App\Service\JobOrderManager;
|
||||||
|
use App\Service\PriceTierManager;
|
||||||
|
|
||||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||||
|
|
||||||
|
|
@ -96,6 +97,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
protected $cust_distance_limit;
|
protected $cust_distance_limit;
|
||||||
protected $hub_filter_enable;
|
protected $hub_filter_enable;
|
||||||
protected $jo_manager;
|
protected $jo_manager;
|
||||||
|
protected $pt_manager;
|
||||||
|
|
||||||
protected $template_hash;
|
protected $template_hash;
|
||||||
|
|
||||||
|
|
@ -104,7 +106,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
||||||
string $country_code, WarrantyHandler $wh, RisingTideGateway $rt,
|
string $country_code, WarrantyHandler $wh, RisingTideGateway $rt,
|
||||||
PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence,
|
PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence,
|
||||||
string $cust_distance_limit, string $hub_filter_enabled, JobOrderManager $jo_manager)
|
string $cust_distance_limit, string $hub_filter_enabled, JobOrderManager $jo_manager, PriceTierManager $pt_manager)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->ic = $ic;
|
$this->ic = $ic;
|
||||||
|
|
@ -121,6 +123,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$this->cust_distance_limit = $cust_distance_limit;
|
$this->cust_distance_limit = $cust_distance_limit;
|
||||||
$this->hub_filter_enabled = $hub_filter_enabled;
|
$this->hub_filter_enabled = $hub_filter_enabled;
|
||||||
$this->jo_manager = $jo_manager;
|
$this->jo_manager = $jo_manager;
|
||||||
|
$this->pt_manager = $pt_manager;
|
||||||
|
|
||||||
$this->loadTemplates();
|
$this->loadTemplates();
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +588,9 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
{
|
{
|
||||||
$source = $jo->getSource();
|
$source = $jo->getSource();
|
||||||
|
|
||||||
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $error_array);
|
// TODO: set the price tier according to location.
|
||||||
|
$price_tier = $this->pt_manager->getPriceTier($jo->getCoordinates());
|
||||||
|
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $source, $price_tier, $error_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
|
|
|
||||||
58
src/Service/PriceTierManager.php
Normal file
58
src/Service/PriceTierManager.php
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||||
|
|
||||||
|
use App\Entity\PriceTier;
|
||||||
|
|
||||||
|
class PriceTierManager
|
||||||
|
{
|
||||||
|
protected $em;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em)
|
||||||
|
{
|
||||||
|
$this->em = $em;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemPrice($pt_id, $item_type_id, $item_id)
|
||||||
|
{
|
||||||
|
// find the item price, given the price tier, battery id, and item type (battery)
|
||||||
|
$db_conn = $this->em->getConnection();
|
||||||
|
|
||||||
|
$ip_sql = 'SELECT ip.price AS price
|
||||||
|
FROM item_price ip
|
||||||
|
WHERE ip.price_tier_id = :pt_id
|
||||||
|
AND ip.item_type_id = :it_id
|
||||||
|
AND ip.item_id = :item_id';
|
||||||
|
|
||||||
|
$ip_stmt = $db_conn->prepare($ip_sql);
|
||||||
|
$ip_stmt->bindValue('pt_id', $pt_id);
|
||||||
|
$ip_stmt->bindValue('it_id', $item_type_id);
|
||||||
|
$ip_stmt->bindValue('item_id', $item_id);
|
||||||
|
|
||||||
|
$ip_result = $ip_stmt->executeQuery();
|
||||||
|
|
||||||
|
$actual_price = 0;
|
||||||
|
// go through rows
|
||||||
|
while ($row = $ip_result->fetchAssociative())
|
||||||
|
{
|
||||||
|
// get the price
|
||||||
|
$price = $row['price'];
|
||||||
|
|
||||||
|
// actual price
|
||||||
|
$actual_price = number_format($price / 100, 2, '.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $actual_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriceTier(Point $point)
|
||||||
|
{
|
||||||
|
// TODO: get location's price tier, given a set of coordinates
|
||||||
|
// for now, hardcoded for testing purposes
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1761,6 +1761,8 @@ $(function() {
|
||||||
var table = $("#invoice-table tbody");
|
var table = $("#invoice-table tbody");
|
||||||
var stype = $("#service_type").val();
|
var stype = $("#service_type").val();
|
||||||
var cvid = $("#customer-vehicle").val();
|
var cvid = $("#customer-vehicle").val();
|
||||||
|
var lng = $("#map_lng").val();
|
||||||
|
var lat = $("#map_lat").val();
|
||||||
|
|
||||||
console.log(JSON.stringify(invoiceItems));
|
console.log(JSON.stringify(invoiceItems));
|
||||||
|
|
||||||
|
|
@ -1772,7 +1774,9 @@ $(function() {
|
||||||
'stype': stype,
|
'stype': stype,
|
||||||
'items': invoiceItems,
|
'items': invoiceItems,
|
||||||
'promo': promo,
|
'promo': promo,
|
||||||
'cvid': cvid
|
'cvid': cvid,
|
||||||
|
'coord_lng': lng,
|
||||||
|
'coord_lat': lat,
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done(function(response) {
|
||||||
// mark as invoice changed
|
// mark as invoice changed
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue