Compare commits
4 commits
master
...
810-auto-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4520f6987 | ||
|
|
aa042a435b | ||
|
|
3c79d1fe28 | ||
|
|
0f909ad7e0 |
14 changed files with 252 additions and 695 deletions
|
|
@ -65,11 +65,6 @@ cust_api_battery_list:
|
|||
controller: App\Controller\CustomerAppAPI\VehicleController::getCompatibleBatteries
|
||||
methods: [GET]
|
||||
|
||||
cust_api_jo_request:
|
||||
path: /apiv2/job_order
|
||||
controller: App\Controller\CustomerAppAPI\JobOrderController::requestJobOrder
|
||||
methods: [POST]
|
||||
|
||||
cust_api_estimate:
|
||||
path: /apiv2/estimate
|
||||
controller: App\Controller\CustomerAppAPI\EstimateController::getEstimate
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ services:
|
|||
# fetching services directly from the container via $container->get() won't work.
|
||||
# The best practice is to be explicit about your dependencies anyway.
|
||||
|
||||
_instanceof:
|
||||
# make every hub filter public
|
||||
App\Service\HubFilter\HubFilterInterface:
|
||||
public: true
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
|
|
@ -332,27 +337,10 @@ services:
|
|||
$rt: "@App\\Service\\RisingTideGateway"
|
||||
$trans: "@Symfony\\Contracts\\Translation\\TranslatorInterface"
|
||||
|
||||
App\Service\HubFilter\Filters\DateAndTimeHubFilter:
|
||||
public: true
|
||||
|
||||
App\Service\HubFilter\Filters\JoTypeHubFilter:
|
||||
public: true
|
||||
|
||||
App\Service\HubFilter\Filters\MaxResultsHubFilter:
|
||||
public: true
|
||||
|
||||
App\Service\HubFilter\Filters\PaymentMethodHubFilter:
|
||||
public: true
|
||||
|
||||
App\Service\HubFilter\Filters\RiderAvailabilityHubFilter:
|
||||
public: true
|
||||
|
||||
App\Service\HubFilter\Filters\InventoryHubFilter:
|
||||
public: true
|
||||
arguments:
|
||||
$im: "@App\\Service\\InventoryManager"
|
||||
|
||||
App\Service\HubFilter\Filters\RoundRobinHubFilter:
|
||||
public: true
|
||||
arguments:
|
||||
$hub_distributor: "@App\\Service\\HubDistributor"
|
||||
|
|
|
|||
|
|
@ -995,411 +995,6 @@ class JobOrderController extends ApiController
|
|||
]);
|
||||
}
|
||||
|
||||
// TODO: remove later
|
||||
// mobile app no longer calls this
|
||||
public function requestJobOrder(
|
||||
Request $req,
|
||||
InvoiceGeneratorInterface $ic,
|
||||
GeofenceTracker $geo,
|
||||
MapTools $map_tools,
|
||||
InventoryManager $im,
|
||||
MQTTClientApiv2 $mclientv2,
|
||||
FCMSender $fcmclient,
|
||||
RiderAssignmentHandlerInterface $rah,
|
||||
PromoLogger $promo_logger,
|
||||
HubSelector $hub_select,
|
||||
HubDistributor $hub_dist,
|
||||
HubFilterLogger $hub_filter_logger,
|
||||
HubFilteringGeoChecker $hub_geofence,
|
||||
JobOrderManager $jo_manager,
|
||||
PriceTierManager $pt_manager
|
||||
) {
|
||||
// validate params
|
||||
$validity = $this->validateRequest($req, [
|
||||
'service_type',
|
||||
'cv_id',
|
||||
// 'batt_id',
|
||||
'long',
|
||||
'lat',
|
||||
'warranty',
|
||||
'mode_of_payment',
|
||||
]);
|
||||
|
||||
if (!$validity['is_valid']) {
|
||||
return new ApiResponse(false, $validity['error']);
|
||||
}
|
||||
|
||||
// trade in type
|
||||
$trade_in_batt = $req->request->get('trade_in_batt');
|
||||
$trade_in_type = $req->request->get('trade_in_type', '');
|
||||
|
||||
// address
|
||||
$address = $req->request->get('delivery_address', 'Set by mobile application');
|
||||
|
||||
// instructions
|
||||
$instructions = $req->request->get('delivery_instructions', '');
|
||||
|
||||
// longitude and latitude
|
||||
$long = $req->request->get('long');
|
||||
$lat = $req->request->get('lat');
|
||||
|
||||
// geofence
|
||||
$is_covered = $geo->isCovered($long, $lat);
|
||||
if (!$is_covered) {
|
||||
// TODO: put geofence error message in config file somewhere
|
||||
return new ApiResponse(false, $this->getGeoErrorMessage());
|
||||
}
|
||||
|
||||
$jo = new JobOrder();
|
||||
$jo->setSource(TransactionOrigin::MOBILE_APP)
|
||||
->setStatus(JOStatus::PENDING)
|
||||
->setDeliveryInstructions('')
|
||||
->setTier1Notes('')
|
||||
->setTier2Notes('')
|
||||
->setDeliveryAddress($address)
|
||||
->setTradeInType($trade_in_type)
|
||||
->setDeliveryInstructions($instructions)
|
||||
// TODO: error check for valid mode of payment
|
||||
->setModeOfPayment($req->request->get('mode_of_payment'));
|
||||
|
||||
// customer
|
||||
$cust = $this->session->getCustomer();
|
||||
if ($cust == null) {
|
||||
return new ApiResponse(false, 'No customer information found.');
|
||||
}
|
||||
|
||||
// check if customer has more than one job order already
|
||||
$flag_cust_new = false;
|
||||
|
||||
$cust_jo_count = $jo_manager->getCustomerJobOrderCount($cust->getID());
|
||||
if ($cust_jo_count <= 1)
|
||||
$flag_cust_new = true;
|
||||
|
||||
$jo->setCustomer($cust);
|
||||
$jo->setCustNew($flag_cust_new);
|
||||
|
||||
// validate service type
|
||||
$stype = $req->request->get('service_type');
|
||||
if (!ServiceType::validate($stype)) {
|
||||
return new ApiResponse(false, 'Invalid service type.');
|
||||
}
|
||||
$jo->setServiceType($stype);
|
||||
|
||||
// validate warranty
|
||||
$warr = $req->request->get('warranty');
|
||||
if (!WarrantyClass::validate($warr)) {
|
||||
return new ApiResponse(false, 'Invalid warranty class.');
|
||||
}
|
||||
$jo->setWarrantyClass($warr);
|
||||
|
||||
// set coordinates
|
||||
$point = new Point($long, $lat);
|
||||
$jo->setCoordinates($point);
|
||||
|
||||
// make invoice criteria
|
||||
$icrit = new InvoiceCriteria();
|
||||
$icrit->setServiceType($stype);
|
||||
|
||||
// check promo
|
||||
$promo_id = $req->request->get('promo_id');
|
||||
if (!empty($promo_id)) {
|
||||
$promo = $this->em->getRepository(Promo::class)->find($promo_id);
|
||||
if ($promo == null) {
|
||||
return new ApiResponse(false, 'Invalid promo id.');
|
||||
}
|
||||
|
||||
// put in criteria
|
||||
$icrit->addPromo($promo);
|
||||
}
|
||||
|
||||
// check customer vehicle
|
||||
$cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id'));
|
||||
if ($cv == null) {
|
||||
return new ApiResponse(false, 'Invalid customer vehicle id.');
|
||||
}
|
||||
$icrit->setCustomerVehicle($cv);
|
||||
$jo->setCustomerVehicle($cv);
|
||||
|
||||
// check if customer owns vehicle
|
||||
if ($cust->getID() != $cv->getCustomer()->getID()) {
|
||||
return new ApiResponse(false, 'Customer does not own vehicle.');
|
||||
}
|
||||
|
||||
// check battery
|
||||
$batt_id = $req->request->get('batt_id');
|
||||
if ($batt_id != null) {
|
||||
$batt = $this->em->getRepository(Battery::class)->find($batt_id);
|
||||
if ($batt == null) {
|
||||
return new ApiResponse(false, 'Invalid battery id.');
|
||||
}
|
||||
} else
|
||||
$batt = null;
|
||||
|
||||
/*
|
||||
// put battery in criteria
|
||||
$icrit->addBattery($batt);
|
||||
*/
|
||||
|
||||
// check trade-in
|
||||
// only allow motolite, other, none
|
||||
switch ($trade_in_type) {
|
||||
case TradeInType::MOTOLITE:
|
||||
case TradeInType::OTHER:
|
||||
break;
|
||||
|
||||
default:
|
||||
$trade_in_type = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// add the actual battery item first
|
||||
$icrit->addEntry($batt, null, 1);
|
||||
|
||||
// if we have a trade in, add it as well
|
||||
if (!empty($trade_in_type) && !empty($trade_in_batt)) {
|
||||
$ti_batt_obj = $this->em->getRepository(Battery::class)->find($trade_in_batt);
|
||||
if (!empty($ti_batt_obj)) {
|
||||
$battery_size = $ti_batt_obj->getSize();
|
||||
$icrit->addTradeInEntry($battery_size, $trade_in_type, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// set taxable
|
||||
$icrit->setIsTaxable();
|
||||
|
||||
// set JO source
|
||||
$icrit->setSource(TransactionOrigin::MOBILE_APP);
|
||||
|
||||
// set price tier
|
||||
$pt_id = $pt_manager->getPriceTier($jo->getCoordinates());
|
||||
$icrit->setPriceTier($pt_id);
|
||||
|
||||
// send to invoice generator
|
||||
$invoice = $ic->generateInvoice($icrit);
|
||||
$jo->setInvoice($invoice);
|
||||
|
||||
// set more hub criteria fields
|
||||
$hub_criteria = new HubCriteria();
|
||||
$hub_criteria->setPoint($jo->getCoordinates());
|
||||
|
||||
// get distance limit for mobile from env
|
||||
$limit_distance = $_ENV['CUST_DISTANCE_LIMIT'];
|
||||
|
||||
// set distance limit
|
||||
$hub_criteria->setLimitDistance($limit_distance);
|
||||
|
||||
if ($hub_geofence->isCovered($long, $lat)) {
|
||||
// TODO: set this properly, since the other flags
|
||||
// are on default values.
|
||||
// if true, set other values for HubCriteria
|
||||
// error_log('Area is covered by hub filtering');
|
||||
$hub_criteria->setJoType($jo->getServiceType())
|
||||
->setPaymentMethod($jo->getModeOfPayment())
|
||||
->setRoundRobin(true);
|
||||
}
|
||||
|
||||
// add battery to items
|
||||
$sku = $batt->getSAPCode();
|
||||
if (!empty($sku))
|
||||
$hub_criteria->addItem($batt->getSAPCode(), 1);
|
||||
|
||||
// get customer id. No JO id at this point
|
||||
$customer_id = $cust->getID();
|
||||
|
||||
$hub_criteria->setCustomerId($customer_id);
|
||||
|
||||
// find nearest hubs
|
||||
$nearest_hubs = $hub_select->find($hub_criteria);
|
||||
|
||||
$assigned_rider = null;
|
||||
if (!empty($nearest_hubs)) {
|
||||
// go through the hub list, find the nearest hub
|
||||
// with an available rider
|
||||
//error_log('found nearest hub ' . $nearest_hub->getID());
|
||||
foreach ($nearest_hubs as $nearest_hub) {
|
||||
$available_riders = $nearest_hub['hub']->getAvailableRiders();
|
||||
if (count($available_riders) >= 1) {
|
||||
if (count($available_riders) == 1) {
|
||||
$assigned_rider = $available_riders[0];
|
||||
} else {
|
||||
// TODO: the setting of riders into an array
|
||||
// will no longer be necessary when the contents
|
||||
// of randomizeRider changes
|
||||
$riders = [];
|
||||
foreach ($available_riders as $rider) {
|
||||
$riders[] = $rider;
|
||||
}
|
||||
|
||||
$assigned_rider = $this->randomizeRider($riders);
|
||||
}
|
||||
|
||||
$jo->setHub($nearest_hub['hub']);
|
||||
$jo->setRider($assigned_rider);
|
||||
$jo->setStatus(JOStatus::ASSIGNED);
|
||||
$jo->setStatusAutoAssign(AutoAssignStatus::HUB_AND_RIDER_ASSIGNED);
|
||||
|
||||
$assigned_rider->setAvailable(false);
|
||||
|
||||
// set rider's current job order
|
||||
$assigned_rider->setCurrentJobOrder($jo);
|
||||
|
||||
// update redis hub_jo_count for hub
|
||||
$hub_dist->incrementJoCountForHub($nearest_hub['hub']);
|
||||
|
||||
// break out of loop
|
||||
break;
|
||||
} else {
|
||||
// log hub into hub_filter_log
|
||||
$hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider', null, $cust->getID());
|
||||
// continue to go through list to find hub with an available rider
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->em->persist($jo);
|
||||
$this->em->persist($invoice);
|
||||
|
||||
// add event log for JO
|
||||
$event = new JOEvent();
|
||||
$event->setDateHappen(new DateTime())
|
||||
->setTypeID(JOEventType::CREATE)
|
||||
->setJobOrder($jo);
|
||||
$this->em->persist($event);
|
||||
|
||||
// check JO status
|
||||
if ($jo->getStatus() == JOStatus::ASSIGNED) {
|
||||
// add event logs for hub and rider assignments
|
||||
$hub_assign_event = new JOEvent();
|
||||
$hub_assign_event->setDateHappen(new DateTime())
|
||||
->setTypeID(JOEventType::HUB_ASSIGN)
|
||||
->setJobOrder($jo);
|
||||
|
||||
$this->em->persist($hub_assign_event);
|
||||
|
||||
$rider_assign_event = new JOEvent();
|
||||
$rider_assign_event->setDateHappen(new DateTime())
|
||||
->setTypeID(JOEventType::RIDER_ASSIGN)
|
||||
->setJobOrder($jo);
|
||||
|
||||
$this->em->persist($rider_assign_event);
|
||||
|
||||
// user mqtt event
|
||||
$payload = [
|
||||
'event' => 'outlet_assign',
|
||||
];
|
||||
$mclientv2->sendEvent($jo, $payload);
|
||||
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
|
||||
|
||||
$rah->assignJobOrder($jo, $jo->getRider());
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
|
||||
// make invoice json data
|
||||
$invoice_data = [
|
||||
'total_price' => $invoice->getTotalPrice(),
|
||||
'vat_ex_price' => (float) $invoice->getVATExclusivePrice(),
|
||||
'vat' => $invoice->getVAT(),
|
||||
'discount' => $invoice->getDiscount(),
|
||||
'trade_in' => $invoice->getTradeIn(),
|
||||
];
|
||||
$items = $invoice->getItems();
|
||||
$items_data = [];
|
||||
foreach ($items as $item) {
|
||||
$items_data[] = [
|
||||
'title' => $item->getTitle(),
|
||||
'qty' => $item->getQuantity() + 0,
|
||||
'price' => $item->getPrice() + 0.0,
|
||||
];
|
||||
}
|
||||
$invoice_data['items'] = $items_data;
|
||||
|
||||
// check service type
|
||||
if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) {
|
||||
$customer = $cv->getCustomer();
|
||||
$customer_tags = $customer->getCustomerTagObjects();
|
||||
if (!empty($customer_tags)) {
|
||||
foreach ($customer_tags as $customer_tag) {
|
||||
// TODO: not too comfy with this being hardcoded
|
||||
if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) {
|
||||
// remove associated entity
|
||||
$customer->removeCustomerTag($customer_tag);
|
||||
|
||||
// log the availment of promo from customer
|
||||
$created_by = $req->query->get('session_key');
|
||||
$cust_id = $jo->getCustomer()->getID();
|
||||
$cust_fname = $jo->getCustomer()->getFirstName();
|
||||
$cust_lname = $jo->getCustomer()->getLastName();
|
||||
$jo_id = $jo->getID();
|
||||
$invoice_id = $jo->getInvoice()->getID();
|
||||
// TODO: check if we store total price of invoice or just the discounted amount
|
||||
$amount = $jo->getInvoice()->getTotalPrice();
|
||||
$promo_logger->logPromoInfo(
|
||||
$created_by,
|
||||
$cust_id,
|
||||
$cust_fname,
|
||||
$cust_lname,
|
||||
$jo_id,
|
||||
$invoice_id,
|
||||
$amount
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// response
|
||||
return new ApiResponse(true, '', [
|
||||
'jo_id' => $jo->getID(),
|
||||
'invoice' => $invoice_data,
|
||||
]);
|
||||
}
|
||||
|
||||
// commenting it out. Modify the getJOHistory instead to just get the fulfilled
|
||||
// and cancelled job orders, since ongoing is not yet part of history
|
||||
/*
|
||||
public function getCompletedJobOrders(Request $req, EntityManagerInterface $em, RiderTracker $rt)
|
||||
{
|
||||
// validate params
|
||||
$validity = $this->validateRequest($req);
|
||||
|
||||
if (!$validity['is_valid']) {
|
||||
return new ApiResponse(false, $validity['error']);
|
||||
}
|
||||
|
||||
// get customer
|
||||
$cust = $this->session->getCustomer();
|
||||
if ($cust == null)
|
||||
{
|
||||
return new ApiResponse(false, 'No customer information found.');
|
||||
}
|
||||
|
||||
$completed_jos = $this->getCompletedJOs($cust);
|
||||
|
||||
// initialize data
|
||||
$jo_data = [];
|
||||
foreach ($completed_jos as $jo)
|
||||
{
|
||||
$jo_data[] = $this->generateJobOrderData($req, $jo, $rt);
|
||||
}
|
||||
|
||||
// response
|
||||
return new ApiResponse(true, '', [
|
||||
'completed_job_orders' => $jo_data,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getCompletedJOs($cust)
|
||||
{
|
||||
$completed_jos = $this->em->getRepository(JobOrder::class)->findBy([
|
||||
'customer' => $cust,
|
||||
'status' => [JOStatus::CANCELLED, JOStatus::FULFILLED],
|
||||
], ['date_schedule' => 'desc']);
|
||||
|
||||
return $completed_jos;
|
||||
}
|
||||
*/
|
||||
|
||||
protected function generateJobOrderData($req, $jo, $rt)
|
||||
{
|
||||
$status = $jo->getStatus();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Service\HubFilter;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
|
|
@ -12,18 +13,19 @@ use App\Entity\JORejection;
|
|||
use App\Ramcar\ServiceType;
|
||||
use App\Ramcar\JORejectionReason;
|
||||
use App\Service\RisingTideGateway;
|
||||
use App\Ramcar\HubCriteria;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class BaseHubFilter
|
||||
{
|
||||
protected $id;
|
||||
protected $jo_id;
|
||||
protected $customer_id;
|
||||
protected $cust;
|
||||
protected $hub_filter_logger;
|
||||
protected $em;
|
||||
protected $rt;
|
||||
protected $trans;
|
||||
protected $crit;
|
||||
|
||||
public function __construct(HubFilterLogger $hub_filter_logger, EntityManagerInterface $em, RisingTideGateway $rt, TranslatorInterface $trans)
|
||||
{
|
||||
|
|
@ -37,36 +39,22 @@ class BaseHubFilter
|
|||
error_log("-------------------");
|
||||
}
|
||||
|
||||
public function initialize(HubCriteria $crit, Customer $cust): void
|
||||
{
|
||||
$this->crit = $crit;
|
||||
$this->cust = $cust;
|
||||
}
|
||||
|
||||
public function getID(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setJOID(int $jo_id)
|
||||
{
|
||||
$this->jo_id = $jo_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getJOID(): int
|
||||
{
|
||||
return $this->jo_id;
|
||||
}
|
||||
|
||||
public function setCustomerID(int $customer_id)
|
||||
{
|
||||
$this->customer_id = $customer_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomerID(): int
|
||||
{
|
||||
return $this->customer_id;
|
||||
}
|
||||
|
||||
public function log(Hub $hub): void
|
||||
{
|
||||
$this->hub_filter_logger->logFilteredHub($hub, $this->getID(), $this->getJOID(), $this->getCustomerID());
|
||||
$jo_id = $this->crit->getJobOrderId();
|
||||
|
||||
$this->hub_filter_logger->logFilteredHub($hub, $this->getID(), $jo_id, $this->cust->getID());
|
||||
|
||||
// log to file
|
||||
$filename = '/../../../var/log/hub_rejection.log';
|
||||
|
|
@ -74,7 +62,7 @@ class BaseHubFilter
|
|||
|
||||
// build log entry
|
||||
$entry = implode("", [
|
||||
"[JO: " . $this->getJOID() . "]",
|
||||
"[JO: " . $jo_id . "]",
|
||||
"[" . $date . "]",
|
||||
"[" . $this->getID() . "]",
|
||||
" " . $hub->getName() . " (ID: " . $hub->getID() . ")",
|
||||
|
|
@ -86,7 +74,12 @@ class BaseHubFilter
|
|||
|
||||
protected function createRejectionEntry($hub, $reason, $remarks = ""): JORejection
|
||||
{
|
||||
$jo = $this->em->getRepository(JobOrder::class)->find($this->getJOID());
|
||||
$jo_id = $this->crit->getJobOrderId();
|
||||
$jo = null;
|
||||
|
||||
if (!empty($jo_id)) {
|
||||
$jo = $this->em->getRepository(JobOrder::class)->find($jo_id);
|
||||
}
|
||||
|
||||
$robj = new JORejection();
|
||||
$robj->setDateCreate(new DateTime())
|
||||
|
|
@ -103,7 +96,7 @@ class BaseHubFilter
|
|||
|
||||
protected function sendSMSMessage($hub, $order_date, $service_type, $rejection, $reason = "", $remarks = ""): void
|
||||
{
|
||||
$jo_id = $this->getJOID();
|
||||
$jo_id = $this->crit->getJobOrderId();
|
||||
|
||||
// check if we already have a rejection record for this hub and JO. this also means an SMS was already sent
|
||||
$rejection_count = $this->em->createQueryBuilder()
|
||||
|
|
|
|||
|
|
@ -4,21 +4,22 @@ namespace App\Service\HubFilter\Filters;
|
|||
|
||||
use App\Service\HubFilter\BaseHubFilter;
|
||||
use App\Service\HubFilter\HubFilterInterface;
|
||||
use App\Ramcar\HubCriteria;
|
||||
|
||||
class DateAndTimeHubFilter extends BaseHubFilter implements HubFilterInterface
|
||||
{
|
||||
protected $id = 'date_and_time';
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'date_time',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
if ($params['date_time'] == null)
|
||||
$filter_time = $this->crit->getDateTime();
|
||||
|
||||
if ($filter_time == null)
|
||||
return $hubs;
|
||||
|
||||
$results = [];
|
||||
|
|
@ -32,22 +33,27 @@ class DateAndTimeHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
// is open/available on date/day
|
||||
$hub = $hub_data['hub'];
|
||||
|
||||
$time_open = $hub->getTimeOpen()->format("H:i:s");
|
||||
$time_close = $hub->getTimeClose()->format("H:i:s");
|
||||
$time_open = $hub->getTimeOpen();
|
||||
$time_close = $hub->getTimeClose();
|
||||
|
||||
$filter_time = $params['date_time']->format("H:i:s");
|
||||
// normalize dates to be the same as filter time
|
||||
$time_open->setDate(
|
||||
$filter_time->format('Y'),
|
||||
$filter_time->format('m'),
|
||||
$filter_time->format('d')
|
||||
);
|
||||
|
||||
$time_close->setDate(
|
||||
$filter_time->format('Y'),
|
||||
$filter_time->format('m'),
|
||||
$filter_time->format('d')
|
||||
);
|
||||
|
||||
// check filter time falls within operating hours
|
||||
if (($filter_time >= $time_open) &&
|
||||
($filter_time <= $time_close))
|
||||
{
|
||||
$results[] = [
|
||||
'hub' => $hub,
|
||||
'db_distance' => $hub_data['db_distance'],
|
||||
'distance' => $hub_data['distance'],
|
||||
'duration' => $hub_data['duration'],
|
||||
'jo_count' => 0,
|
||||
'inventory' => $hub_data['inventory'],
|
||||
];
|
||||
$results[] = $hub_data;
|
||||
}
|
||||
else
|
||||
$this->log($hub);
|
||||
|
|
|
|||
59
src/Service/HubFilter/Filters/DistanceHubFilter.php
Normal file
59
src/Service/HubFilter/Filters/DistanceHubFilter.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\HubFilter\Filters;
|
||||
|
||||
use App\Entity\Hub;
|
||||
use App\Service\HubFilter\BaseHubFilter;
|
||||
use App\Service\HubFilter\HubFilterInterface;
|
||||
|
||||
class DistanceHubFilter extends BaseHubFilter implements HubFilterInterface
|
||||
{
|
||||
protected $id = 'not_within_distance';
|
||||
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return !$this->crit->isEmergency();
|
||||
}
|
||||
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
$results = [];
|
||||
foreach ($hubs as $hub_data)
|
||||
{
|
||||
$hub = $hub_data['hub'];
|
||||
$dist = $hub_data['distance'];
|
||||
|
||||
// check if within distance threshold
|
||||
if ($dist < $this->crit->getLimitDistance()) {
|
||||
// log to legacy file
|
||||
$this->logHubWithinDistance($hub, $dist);
|
||||
|
||||
// add to results
|
||||
$results[] = $hub_data;
|
||||
} else {
|
||||
$this->log($hub);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
// NOTE: pulled from old hub selector class to maintain the log file
|
||||
protected function logHubWithinDistance(Hub $hub, float $distance): void
|
||||
{
|
||||
// log to file
|
||||
$filename = '/../../../../var/log/closest_hubs_selected.log';
|
||||
$date = date("Y-m-d H:i:s");
|
||||
|
||||
// build log entry
|
||||
$entry = implode("", [
|
||||
"[JO: " . $this->crit->getJobOrderId() . "]",
|
||||
"[" . $date . "]",
|
||||
"[Distance: " . $distance . " vs " . $this->crit->getLimitDistance() . "]",
|
||||
" " . $hub->getName() . " (ID: " . $hub->getID() . ")",
|
||||
"\r\n",
|
||||
]);
|
||||
|
||||
@file_put_contents(__DIR__ . $filename, $entry, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,45 +28,40 @@ class InventoryHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
$this->im = $im;
|
||||
}
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'flag_inventory_check',
|
||||
'customer_class',
|
||||
'jo_type',
|
||||
'jo_origin',
|
||||
'order_date',
|
||||
'service_type',
|
||||
'items',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
$jo_id = $this->crit->getJobOrderId();
|
||||
$jo_type = $this->crit->getJoType();
|
||||
|
||||
// check if this is enabled
|
||||
if (!$params['flag_inventory_check']) {
|
||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": DISABLED");
|
||||
if (!$this->crit->hasInventoryCheck()) {
|
||||
error_log("INVENTORY CHECK " . $jo_id . ": DISABLED");
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
// check customer class
|
||||
if ((!empty($params['customer_class']) && $params['customer_class'] == CustomerClassification::VIP) ||
|
||||
$params['jo_origin'] === TransactionOrigin::VIP) {
|
||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": VIP CLASS");
|
||||
if ((!empty($params['customer_class']) && $this->crit->getCustomerClass() == CustomerClassification::VIP) ||
|
||||
$this->crit->getJoOrigin() === TransactionOrigin::VIP) {
|
||||
error_log("INVENTORY CHECK " . $jo_id . ": VIP CLASS");
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
// check item list is not empty
|
||||
if (empty($params['items'])) {
|
||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": NO ITEMS");
|
||||
error_log("INVENTORY CHECK " . $jo_id . ": NO ITEMS");
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
// check this is a battery item related JO
|
||||
if ($params['jo_type'] != ServiceType::BATTERY_REPLACEMENT_NEW &&
|
||||
$params['jo_type'] != ServiceType::BATTERY_REPLACEMENT_WARRANTY
|
||||
if ($jo_type != ServiceType::BATTERY_REPLACEMENT_NEW &&
|
||||
$jo_type != ServiceType::BATTERY_REPLACEMENT_WARRANTY
|
||||
) {
|
||||
error_log("INVENTORY CHECK " . $this->getJOID() . ": INVALID SERVICE TYPE: " . $params['jo_type']);
|
||||
error_log("INVENTORY CHECK " . $jo_id . ": INVALID SERVICE TYPE: " . $jo_type);
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +79,8 @@ class InventoryHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
$qtys = [];
|
||||
|
||||
// call inventory manager for all hubs for selected SKUs
|
||||
$skus = array_keys($params['items']);
|
||||
$items = $this->crit->getItems();
|
||||
$skus = array_keys($items);
|
||||
|
||||
error_log("CHECKING INVENTORY FOR " . count($skus) . " ITEM(S) ON HUBS " . count($branch_codes) . "...");
|
||||
|
||||
|
|
@ -96,7 +92,7 @@ class InventoryHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
foreach ($branches as $branch) {
|
||||
if (isset($branch['BranchCode'])) {
|
||||
// filter out branch if it does not have sufficient inventory
|
||||
if (!isset($params['items'][$branch['SapCode']]) || $branch['Quantity'] < $params['items'][$branch['SapCode']] &&
|
||||
if (!isset($params['items'][$branch['SapCode']]) || $branch['Quantity'] < $items[$branch['SapCode']] &&
|
||||
!isset($hubs_to_filter[$branch['BranchCode']])
|
||||
) {
|
||||
error_log("FILTERING BRANCH WITH NO INVENTORY: " . $branch['BranchCode']);
|
||||
|
|
@ -124,8 +120,6 @@ class InventoryHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
// check if we are filtering this hub
|
||||
if (isset($hubs_to_filter[$branch_code]) || empty($branch_code) || !isset($qtys[$branch_code])) {
|
||||
// if we have a JO, create rejection record and notify
|
||||
$jo_id = $this->getJOID();
|
||||
|
||||
if (!empty($jo_id)) {
|
||||
// create rejection report entry
|
||||
$robj = $this->createRejectionEntry(
|
||||
|
|
@ -137,8 +131,8 @@ class InventoryHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
// build SMS message
|
||||
$this->sendSMSMessage(
|
||||
$hub,
|
||||
$params['order_date'],
|
||||
$params['service_type'],
|
||||
$this->crit->getOrderDate(),
|
||||
$this->crit->getServiceType(),
|
||||
$robj,
|
||||
JORejectionReason::getName(JORejectionReason::NO_STOCK_SALES),
|
||||
"Requested SKU(s) - " . $battery_string
|
||||
|
|
|
|||
|
|
@ -9,20 +9,17 @@ class JoTypeHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
{
|
||||
protected $id = 'job_order_type';
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'flag_emergency',
|
||||
'jo_type',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
if ($params['flag_emergency'])
|
||||
if ($this->crit->isEmergency())
|
||||
return $hubs;
|
||||
|
||||
if (empty($params['jo_type']))
|
||||
if (empty($this->crit->getJoType()))
|
||||
return $hubs;
|
||||
|
||||
$results = [];
|
||||
|
|
|
|||
|
|
@ -9,22 +9,22 @@ class MaxResultsHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
{
|
||||
protected $id = 'max_results';
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'limit_results',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
if (empty($params['limit_results']))
|
||||
$limit_results = $this->crit->getLimitResults();
|
||||
|
||||
if (empty($limit_results))
|
||||
return $hubs;
|
||||
|
||||
$results = [];
|
||||
for ($i = 0; $i < count($hubs); $i++)
|
||||
{
|
||||
if ($i < $params['limit_results'])
|
||||
if ($i < $limit_results)
|
||||
$results[] = $hubs[$i];
|
||||
else
|
||||
$this->log($hubs[$i]['hub']);
|
||||
|
|
|
|||
|
|
@ -9,20 +9,17 @@ class PaymentMethodHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
{
|
||||
protected $id = 'no_payment_method';
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'flag_emergency',
|
||||
'payment_method',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
if ($params['flag_emergency'])
|
||||
if ($this->crit->isEmergency())
|
||||
return $hubs;
|
||||
|
||||
if (empty($params['payment_method']))
|
||||
if (empty($this->crit->getPaymentMethod()))
|
||||
return $hubs;
|
||||
|
||||
$results = [];
|
||||
|
|
@ -37,7 +34,7 @@ class PaymentMethodHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
$flag_found_pmethod = false;
|
||||
foreach ($payment_methods as $pmethod)
|
||||
{
|
||||
if ($pmethod == $params['payment_method'])
|
||||
if ($pmethod == $this->crit->getPaymentMethod())
|
||||
{
|
||||
$results[] = [
|
||||
'hub' => $hub,
|
||||
|
|
|
|||
|
|
@ -12,26 +12,24 @@ class RiderAvailabilityHubFilter extends BaseHubFilter implements HubFilterInter
|
|||
{
|
||||
protected $id = 'no_available_rider';
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'flag_riders_check',
|
||||
'customer_class',
|
||||
'order_date',
|
||||
'service_type',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
$cust_class = $this->crit->getCustomerClass();
|
||||
$jo_id = $this->crit->getJobOrderId();
|
||||
|
||||
// check if this is enabled
|
||||
if (!$params['flag_riders_check']) {
|
||||
if (!$this->crit->hasRidersCheck()) {
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
// check customer class
|
||||
if (!empty($params['customer_class']) && $params['customer_class'] == CustomerClassification::VIP) {
|
||||
error_log("RIDER CHECK " . $this->getJOID() . ": VIP CLASS");
|
||||
if (!empty($cust_class) && $cust_class == CustomerClassification::VIP) {
|
||||
error_log("RIDER CHECK " . $jo_id . ": VIP CLASS");
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
|
|
@ -45,8 +43,6 @@ class RiderAvailabilityHubFilter extends BaseHubFilter implements HubFilterInter
|
|||
error_log("TOTAL RIDERS: " . $available_riders);
|
||||
if ($available_riders === 0) {
|
||||
// if we have a JO, create rejection record and notify
|
||||
$jo_id = $this->getJOID();
|
||||
|
||||
if (!empty($jo_id)) {
|
||||
// create rejection report entry
|
||||
$robj = $this->createRejectionEntry($hub, JORejectionReason::NO_RIDER_AVAILABLE);
|
||||
|
|
@ -54,8 +50,8 @@ class RiderAvailabilityHubFilter extends BaseHubFilter implements HubFilterInter
|
|||
// build SMS message
|
||||
$this->sendSMSMessage(
|
||||
$hub,
|
||||
$params['order_date'],
|
||||
$params['service_type'],
|
||||
$this->crit->getOrderDate(),
|
||||
$this->crit->getServiceType(),
|
||||
$robj,
|
||||
JORejectionReason::getName(JORejectionReason::NO_RIDER_AVAILABLE),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -23,16 +23,14 @@ class RoundRobinHubFilter extends BaseHubFilter implements HubFilterInterface
|
|||
$this->hub_distributor = $hub_distributor;
|
||||
}
|
||||
|
||||
public function getRequestedParams() : array
|
||||
public function isApplicable() : bool
|
||||
{
|
||||
return [
|
||||
'flag_round_robin',
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array
|
||||
public function filter(array $hubs) : array
|
||||
{
|
||||
if (!$params['flag_round_robin'])
|
||||
if (!$this->crit->isRoundRobin())
|
||||
return $hubs;
|
||||
|
||||
$results = [];
|
||||
|
|
|
|||
|
|
@ -2,19 +2,16 @@
|
|||
|
||||
namespace App\Service\HubFilter;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Ramcar\HubCriteria;
|
||||
|
||||
interface HubFilterInterface
|
||||
{
|
||||
public function initialize(HubCriteria $crit, Customer $cust);
|
||||
|
||||
public function getID() : string;
|
||||
|
||||
public function filter(array $hubs, array $params = []) : array;
|
||||
public function isApplicable() : bool;
|
||||
|
||||
public function setJOID(int $jo_id);
|
||||
|
||||
public function getJOID() : int;
|
||||
|
||||
public function setCustomerID(int $customer_id);
|
||||
|
||||
public function getCustomerID() : int;
|
||||
|
||||
public function getRequestedParams() : array;
|
||||
public function filter(array $hubs) : array;
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
|
@ -15,6 +16,7 @@ use App\Service\HubFilterLogger;
|
|||
use App\Service\RisingTideGateway;
|
||||
|
||||
use App\Ramcar\HubCriteria;
|
||||
use App\Service\HubFilter\HubFilterInterface;
|
||||
|
||||
class HubSelector
|
||||
{
|
||||
|
|
@ -26,9 +28,7 @@ class HubSelector
|
|||
protected $trans;
|
||||
protected $rt;
|
||||
|
||||
public function __construct(ContainerInterface $container, EntityManagerInterface $em, InventoryManager $im,
|
||||
HubDistributor $hub_distributor, HubFilterLogger $hub_filter_logger,
|
||||
TranslatorInterface $trans, RisingTideGateway $rt)
|
||||
public function __construct(ContainerInterface $container, EntityManagerInterface $em, InventoryManager $im, HubDistributor $hub_distributor, HubFilterLogger $hub_filter_logger, TranslatorInterface $trans, RisingTideGateway $rt)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->em = $em;
|
||||
|
|
@ -51,84 +51,87 @@ class HubSelector
|
|||
return $enabled_filters;
|
||||
}
|
||||
|
||||
public function find(HubCriteria $criteria)
|
||||
public function find(HubCriteria $criteria): array
|
||||
{
|
||||
$point = $criteria->getPoint();
|
||||
$limit_results = $criteria->getLimitResults();
|
||||
$limit_distance = $criteria->getLimitDistance();
|
||||
$jo_type = $criteria->getJoType();
|
||||
$flag_inventory_check = $criteria->hasInventoryCheck();
|
||||
$flag_riders_check = $criteria->hasRidersCheck();
|
||||
$items = $criteria->getItems();
|
||||
$date_time = $criteria->getDateTime();
|
||||
$payment_method = $criteria->getPaymentMethod();
|
||||
$flag_emergency = $criteria->isEmergency();
|
||||
$flag_round_robin = $criteria->isRoundRobin();
|
||||
$jo_id = $criteria->getJobOrderId();
|
||||
$jo_origin = $criteria->getJoOrigin();
|
||||
$customer_id = $criteria->getCustomerId();
|
||||
$customer_class = $criteria->getCustomerClass();
|
||||
// get all the hubs
|
||||
$hubs = $this->getHubList($criteria->getPoint());
|
||||
|
||||
// needed for JORejection records and SMS notifs
|
||||
$order_date = $criteria->getOrderDate();
|
||||
$service_type = $criteria->getServiceType();
|
||||
// get customer record
|
||||
$cust = $this->em->getRepository(Customer::class)->find($criteria->getCustomerId());
|
||||
|
||||
// error_log('payment methods ' . $payment_method);
|
||||
// error_log('distance limit ' . $limit_distance);
|
||||
// error_log('emergency flag ' . $flag_emergency);
|
||||
|
||||
// get all the hubs within distance
|
||||
$filtered_hubs = $this->getClosestHubs($point, $limit_distance, $jo_id, $customer_id);
|
||||
|
||||
// build param list
|
||||
$params = [
|
||||
'date_time' => $date_time,
|
||||
'flag_inventory_check' => $flag_inventory_check,
|
||||
'customer_class' => $customer_class,
|
||||
'jo_type' => $jo_type,
|
||||
'jo_origin' => $jo_origin,
|
||||
'order_date' => $order_date,
|
||||
'service_type' => $service_type,
|
||||
'items' => $items,
|
||||
'flag_emergency' => $flag_emergency,
|
||||
'limit_results' => $limit_results,
|
||||
'payment_method' => $payment_method,
|
||||
'flag_riders_check' => $flag_riders_check,
|
||||
'flag_round_robin' => $flag_round_robin,
|
||||
];
|
||||
// get all areas that cover the JO location
|
||||
$areas = $this->getAreaCoverage($criteria);
|
||||
|
||||
// loop through all enabled filters
|
||||
foreach ($this->getActiveFilters() as $hub_filter) {
|
||||
// no hubs left to filter
|
||||
if (empty($filtered_hubs)) {
|
||||
if (empty($hubs)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// initialize the filter
|
||||
$f = $this->container->get($hub_filter);
|
||||
$f->initialize($criteria, $cust);
|
||||
|
||||
// check if supported area is exempted from this filter
|
||||
if ($this->isExemptedByArea($f->getID(), $point)) {
|
||||
if ($this->isExemptedByArea($areas, $f)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$f->setJOID($jo_id);
|
||||
$f->setCustomerID($customer_id);
|
||||
|
||||
// get requested params only
|
||||
$req_params = array_intersect_key($params, array_flip($f->getRequestedParams()));
|
||||
|
||||
// filter hub list
|
||||
$filtered_hubs = $f->filter($filtered_hubs, $req_params);
|
||||
|
||||
// error_log($f->getID() . ' hubs ' . json_encode($filtered_hubs));
|
||||
// run the filter
|
||||
$hubs = $f->filter($hubs, $criteria);
|
||||
}
|
||||
|
||||
// error_log('final hub list ' . json_encode($filtered_hubs));
|
||||
// error_log('final hub list ' . json_encode($hubs));
|
||||
|
||||
return $filtered_hubs;
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
protected function getClosestHubs(Point $point, $limit_distance, $jo_id, $customer_id)
|
||||
protected function isExemptedByArea(array $areas, HubFilterInterface $filter): bool
|
||||
{
|
||||
$is_exempted = false;
|
||||
|
||||
if (!empty($areas)) {
|
||||
// check if at least one area has this filter enabled
|
||||
$has_support = false;
|
||||
|
||||
foreach ($areas as $area) {
|
||||
// get all exceptions
|
||||
$exceptions = $area->getHubFilterExceptions();
|
||||
|
||||
// if any area has this filter enabled, consider it enabled and move on
|
||||
if (!isset($exceptions[$filter->getID()])) {
|
||||
$has_support = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// none of the areas have this filter enabled, consider it exempted
|
||||
if (!$has_support) {
|
||||
error_log("skipping filter " . $filter->getID() . " due to exempted area");
|
||||
$is_exempted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// filter is in place
|
||||
return $is_exempted;
|
||||
}
|
||||
|
||||
protected function getAreaCoverage(HubCriteria $criteria): array
|
||||
{
|
||||
$point = $criteria->getPoint();
|
||||
$long = $point->getLongitude();
|
||||
$lat = $point->getLatitude();
|
||||
|
||||
// get supported area given a set of coordinates
|
||||
$query = $this->em->createQuery('SELECT s from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true');
|
||||
|
||||
return $query->setParameter('long', $long)
|
||||
->setParameter('lat', $lat)
|
||||
->getResult();
|
||||
}
|
||||
|
||||
protected function getHubList(Point $point): array
|
||||
{
|
||||
// get closest hubs based on st_distance function from db
|
||||
$query_string = 'SELECT h, st_distance(h.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Hub h WHERE h.status_open = true ORDER BY dist';
|
||||
|
|
@ -141,49 +144,34 @@ class HubSelector
|
|||
$result = $query->getResult();
|
||||
|
||||
$hubs = [];
|
||||
$hubs_data = [];
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$hubs[] = $row[0];
|
||||
|
||||
// get coordinates of hub
|
||||
$hub_coordinates = $row[0]->getCoordinates();
|
||||
|
||||
$cust_lat = $point->getLatitude();
|
||||
$cust_lng = $point->getLongitude();
|
||||
|
||||
$hub_lat = $hub_coordinates->getLatitude();
|
||||
$hub_lng = $hub_coordinates->getLongitude();
|
||||
|
||||
foreach ($result as $row) {
|
||||
$hub = $row[0];
|
||||
|
||||
// get distance in kilometers from customer point to hub point
|
||||
$dist = $this->distance($cust_lat, $cust_lng, $hub_lat, $hub_lng);
|
||||
$dist = $this->getKmDistance($point, $hub->getCoordinates());
|
||||
|
||||
if ($dist < $limit_distance)
|
||||
{
|
||||
$hubs_data[] = [
|
||||
'hub' => $row[0],
|
||||
'db_distance' => $row['dist'],
|
||||
'distance' => $dist,
|
||||
'duration' => 0,
|
||||
'jo_count' => 0,
|
||||
'inventory' => 0,
|
||||
];
|
||||
|
||||
// log to file
|
||||
$this->logClosestHubResult($jo_id, $row[0], $dist, $limit_distance);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->hub_filter_logger->logFilteredHub($row[0], 'not_within_distance', $jo_id, $customer_id);
|
||||
}
|
||||
$hubs[] = [
|
||||
'hub' => $hub,
|
||||
'db_distance' => $row['dist'],
|
||||
'distance' => $dist,
|
||||
'duration' => 0,
|
||||
'jo_count' => 0,
|
||||
'inventory' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
return $hubs_data;
|
||||
return $hubs;
|
||||
}
|
||||
|
||||
// convert db distance to kilometers
|
||||
protected function distance($lat1, $lon1, $lat2, $lon2)
|
||||
protected function getKmDistance(Point $point1, Point $point2): float
|
||||
{
|
||||
// get coordinates in radians
|
||||
$lat1 = $point1->getLatitude();
|
||||
$lon1 = $point1->getLongitude();
|
||||
$lat2 = $point2->getLatitude();
|
||||
$lon2 = $point2->getLongitude();
|
||||
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2))
|
||||
return 0;
|
||||
|
||||
|
|
@ -193,53 +181,7 @@ class HubSelector
|
|||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
|
||||
return round(($miles * 1.609344), 1);
|
||||
}
|
||||
|
||||
protected function isExemptedByArea(string $filter_id, Point $coordinates): bool
|
||||
{
|
||||
$long = $coordinates->getLongitude();
|
||||
$lat = $coordinates->getLatitude();
|
||||
|
||||
// get supported area given a set of coordinates
|
||||
$query = $this->em->createQuery('SELECT s from App\Entity\SupportedArea s where st_contains(s.coverage_area, point(:long, :lat)) = true');
|
||||
$area = $query->setParameter('long', $long)
|
||||
->setParameter('lat', $lat)
|
||||
->setMaxResults(1)
|
||||
->getOneOrNullResult();
|
||||
|
||||
if ($area !== null) {
|
||||
// get all exceptions
|
||||
$exceptions = $area->getHubFilterExceptions();
|
||||
|
||||
if (isset($exceptions[$filter_id])) {
|
||||
error_log("FILTER " . $filter_id . " DISABLED FOR AREA: " . $area->getName());
|
||||
|
||||
// disable this filter for this area
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// filter is in place
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function logClosestHubResult($jo_id, $hub, $distance, $limit_distance)
|
||||
{
|
||||
// log to file
|
||||
$filename = '/../../var/log/closest_hubs_selected.log';
|
||||
$date = date("Y-m-d H:i:s");
|
||||
|
||||
// build log entry
|
||||
$entry = implode("", [
|
||||
"[JO: " . $jo_id . "]",
|
||||
"[" . $date . "]",
|
||||
"[Distance: " . $distance . " vs " . $limit_distance . "]",
|
||||
" " . $hub->getName() . " (ID: " . $hub->getID() . ")",
|
||||
"\r\n",
|
||||
]);
|
||||
|
||||
@file_put_contents(__DIR__ . $filename, $entry, FILE_APPEND);
|
||||
return round($miles * 1.609344, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue