Associate job orders with hubs instead of outlets, filter assigning list to user assigned hubs only #17

This commit is contained in:
Ramon Gutierrez 2018-02-19 13:51:07 +08:00
parent bc65a4ac39
commit d4cc431bac
4 changed files with 73 additions and 60 deletions

View file

@ -14,7 +14,8 @@ use App\Entity\JobOrder;
use App\Entity\BatteryManufacturer; use App\Entity\BatteryManufacturer;
use App\Entity\Customer; use App\Entity\Customer;
use App\Entity\CustomerVehicle; use App\Entity\CustomerVehicle;
use App\Entity\Outlet; //use App\Entity\Outlet;
use App\Entity\Hub;
use App\Entity\Promo; use App\Entity\Promo;
use App\Entity\Rider; use App\Entity\Rider;
use App\Entity\Battery; use App\Entity\Battery;
@ -23,6 +24,7 @@ use App\Service\InvoiceCreator;
use App\Service\MapTools; use App\Service\MapTools;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\LockMode; use Doctrine\DBAL\LockMode;
use Doctrine\ORM\PessimisticLockException; use Doctrine\ORM\PessimisticLockException;
@ -239,6 +241,10 @@ class JobOrderController extends BaseController
// check which job order tier is being called for and confirm access // check which job order tier is being called for and confirm access
$tier_params = $this->checkTier($tier); $tier_params = $this->checkTier($tier);
// get current user
$user = $this->getUser();
$hubs = $user->getHubs();
// get query builder // get query builder
$qb = $this->getDoctrine() $qb = $this->getDoctrine()
->getRepository(JobOrder::class) ->getRepository(JobOrder::class)
@ -250,7 +256,7 @@ class JobOrderController extends BaseController
// count total records // count total records
$tquery = $qb->select('COUNT(q)'); $tquery = $qb->select('COUNT(q)');
$this->setQueryFilters($datatable, $tquery, $qb, $tier_params['jo_status']); $this->setQueryFilters($datatable, $tquery, $qb, $hubs, $tier, $tier_params['jo_status']);
$total = $tquery->getQuery() $total = $tquery->getQuery()
->getSingleScalarResult(); ->getSingleScalarResult();
@ -274,7 +280,7 @@ class JobOrderController extends BaseController
// build query // build query
$query = $qb->select('q'); $query = $qb->select('q');
$this->setQueryFilters($datatable, $query, $qb, $tier_params['jo_status']); $this->setQueryFilters($datatable, $query, $qb, $hubs, $tier, $tier_params['jo_status']);
// check if sorting is present, otherwise use default // check if sorting is present, otherwise use default
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) { if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
@ -396,35 +402,35 @@ class JobOrderController extends BaseController
$params['discount_apply'] = DiscountApply::getCollection(); $params['discount_apply'] = DiscountApply::getCollection();
$params['trade_in_types'] = TradeInType::getCollection(); $params['trade_in_types'] = TradeInType::getCollection();
// get closest outlets // get closest hubs
$outlets = $map_tools->getClosestOutlets($obj->getCoordinates(), 10, date("H:i:s")); $hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 10, date("H:i:s"));
$params['outlets'] = []; $params['hubs'] = [];
// format duration and distance into friendly time // format duration and distance into friendly time
foreach ($outlets as $outlet) { foreach ($hubs as $hub) {
// duration // duration
$seconds = $outlet['duration']; $seconds = $hub['duration'];
if (!empty($seconds) && $seconds > 0) { if (!empty($seconds) && $seconds > 0) {
$hours = floor($seconds / 3600); $hours = floor($seconds / 3600);
$minutes = ceil(($seconds / 60) % 60); $minutes = ceil(($seconds / 60) % 60);
$outlet['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : ''); $hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : '');
} else { } else {
$outlet['duration'] = false; $hub['duration'] = false;
} }
// distance // distance
$meters = $outlet['distance']; $meters = $hub['distance'];
if (!empty($meters) && $meters > 0) { if (!empty($meters) && $meters > 0) {
$outlet['distance'] = round($meters / 1000) . " km"; $hub['distance'] = round($meters / 1000) . " km";
} else { } else {
$outlet['distance'] = false; $hub['distance'] = false;
} }
$params['outlets'][] = $outlet; $params['hubs'][] = $hub;
} }
$params['obj'] = $obj; $params['obj'] = $obj;
@ -465,15 +471,15 @@ class JobOrderController extends BaseController
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
} }
// check if outlet is set // check if hub is set
if (empty($req->request->get('outlet'))) { if (empty($req->request->get('hub'))) {
$error_array['outlet'] = 'No outlet selected.'; $error_array['hub'] = 'No hub selected.';
} else { } else {
// get outlet // get hub
$outlet = $em->getRepository(Outlet::class)->find($req->request->get('outlet')); $hub = $em->getRepository(Hub::class)->find($req->request->get('hub'));
if (empty($outlet)) { if (empty($hub)) {
$error_array['outlet'] = 'Invalid outlet specified.'; $error_array['hub'] = 'Invalid hub specified.';
} }
} }
@ -492,7 +498,7 @@ class JobOrderController extends BaseController
->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setDeliveryInstructions($req->request->get('delivery_instructions'))
->setAgentNotes($req->request->get('agent_notes')) ->setAgentNotes($req->request->get('agent_notes'))
->setDeliveryAddress($req->request->get('delivery_address')) ->setDeliveryAddress($req->request->get('delivery_address'))
->setOutlet($outlet); ->setHub($hub);
// validate // validate
$errors = $validator->validate($obj); $errors = $validator->validate($obj);
@ -583,35 +589,35 @@ class JobOrderController extends BaseController
$params['discount_apply'] = DiscountApply::getCollection(); $params['discount_apply'] = DiscountApply::getCollection();
$params['trade_in_types'] = TradeInType::getCollection(); $params['trade_in_types'] = TradeInType::getCollection();
// get closest outlets // get closest hubs
$outlets = $map_tools->getClosestOutlets($obj->getCoordinates(), 10, date("H:i:s")); $hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 10, date("H:i:s"));
$params['outlets'] = []; $params['hubs'] = [];
// format duration and distance into friendly time // format duration and distance into friendly time
foreach ($outlets as $outlet) { foreach ($hubs as $hub) {
// duration // duration
$seconds = $outlet['duration']; $seconds = $hub['duration'];
if (!empty($seconds) && $seconds > 0) { if (!empty($seconds) && $seconds > 0) {
$hours = floor($seconds / 3600); $hours = floor($seconds / 3600);
$minutes = ceil(($seconds / 60) % 60); $minutes = ceil(($seconds / 60) % 60);
$outlet['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : ''); $hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : '');
} else { } else {
$outlet['duration'] = false; $hub['duration'] = false;
} }
// distance // distance
$meters = $outlet['distance']; $meters = $hub['distance'];
if (!empty($meters) && $meters > 0) { if (!empty($meters) && $meters > 0) {
$outlet['distance'] = round($meters / 1000) . " km"; $hub['distance'] = round($meters / 1000) . " km";
} else { } else {
$outlet['distance'] = false; $hub['distance'] = false;
} }
$params['outlets'][] = $outlet; $params['hubs'][] = $hub;
} }
$params['obj'] = $obj; $params['obj'] = $obj;
@ -704,11 +710,18 @@ class JobOrderController extends BaseController
// TODO: re-enable search, figure out how to group the orWhere filters into one, so can execute that plus the pending filter // TODO: re-enable search, figure out how to group the orWhere filters into one, so can execute that plus the pending filter
// check if datatable filter is present and append to query // check if datatable filter is present and append to query
protected function setQueryFilters($datatable, &$query, $qb, $status) protected function setQueryFilters($datatable, &$query, $qb, $hubs, $tier, $status)
{ {
$query->where('q.status = :status') $query->where('q.status = :status')
->setParameter('status', $status); ->setParameter('status', $status);
// on assigning, filter by assigned hub
if ($tier == 'assign')
{
$query->andWhere('q.hub IN (:hubs)')
->setParameter('hubs', $hubs, Connection::PARAM_STR_ARRAY);
}
// get only pending rows // get only pending rows
/* /*
$query->where($qb->expr()->orX( $query->where($qb->expr()->orX(

View file

@ -23,11 +23,11 @@ class Hub
*/ */
protected $riders; protected $riders;
// outlets under this hub // job orders assigned to hub
/** /**
* @ORM\OneToMany(targetEntity="Outlet", mappedBy="hub") * @ORM\OneToMany(targetEntity="JobOrder", mappedBy="hub")
*/ */
protected $outlets; protected $job_orders;
/** /**
* @ORM\ManyToMany(targetEntity="User", mappedBy="hubs", fetch="EXTRA_LAZY") * @ORM\ManyToMany(targetEntity="User", mappedBy="hubs", fetch="EXTRA_LAZY")
@ -47,11 +47,6 @@ class Hub
return $this->riders; return $this->riders;
} }
public function getOutlets()
{
return $this->outlets;
}
public function getUsers() public function getUsers()
{ {
return $this->users; return $this->users;
@ -61,4 +56,9 @@ class Hub
{ {
return $this->users->count(); return $this->users->count();
} }
public function getJobOrders()
{
return $this->job_orders;
}
} }

View file

@ -116,12 +116,12 @@ class JobOrder
*/ */
protected $cus_vehicle; protected $cus_vehicle;
// assigned outlet // assigned hub
/** /**
* @ORM\ManyToOne(targetEntity="Outlet", inversedBy="job_orders") * @ORM\ManyToOne(targetEntity="Hub", inversedBy="job_orders")
* @ORM\JoinColumn(name="outlet_id", referencedColumnName="id") * @ORM\JoinColumn(name="hub_id", referencedColumnName="id")
*/ */
protected $outlet; protected $hub;
// assigned rider // assigned rider
/** /**
@ -324,15 +324,15 @@ class JobOrder
return $this->cus_vehicle; return $this->cus_vehicle;
} }
public function setOutlet(Outlet $outlet) public function setHub(Hub $hub)
{ {
$this->outlet = $outlet; $this->hub = $hub;
return $this; return $this;
} }
public function getOutlet() public function getHub()
{ {
return $this->outlet; return $this->hub;
} }
public function setRider(Rider $rider) public function setRider(Rider $rider)

View file

@ -23,7 +23,7 @@ class MapTools
$this->gmaps_api_key = $gmaps_api_key; $this->gmaps_api_key = $gmaps_api_key;
} }
protected function mapGetDistances(Point $point, $outlets) protected function mapGetDistances(Point $point, $hubs)
{ {
$client = new GuzzleClient(); $client = new GuzzleClient();
@ -32,9 +32,9 @@ class MapTools
// destinations // destinations
$dests = []; $dests = [];
foreach ($outlets as $outlet) foreach ($hubs as $hub)
{ {
$coord = $outlet->getCoordinates(); $coord = $hub->getCoordinates();
$dests[] = round($coord->getLatitude(),5) . ',' . round($point->getLongitude(), 5); $dests[] = round($coord->getLatitude(),5) . ',' . round($point->getLongitude(), 5);
} }
$dests_value = implode('|', $dests); $dests_value = implode('|', $dests);
@ -57,10 +57,10 @@ class MapTools
return $res->getBody(); return $res->getBody();
} }
public function getClosestOutlets(Point $point, $limit, $time = false) public function getClosestHubs(Point $point, $limit, $time = false)
{ {
// get closest outlets based on st_distance function from db // get closest hubs based on st_distance function from db
$query = $this->em->createQuery('SELECT o, st_distance(o.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Outlet o' . ($time ? ' WHERE :time BETWEEN o.time_open AND o.time_close' : '') . ' ORDER BY dist') $query = $this->em->createQuery('SELECT h, st_distance(o.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Hub h' . ($time ? ' WHERE :time BETWEEN h.time_open AND h.time_close' : '') . ' ORDER BY dist')
->setParameter('lat', $point->getLatitude()) ->setParameter('lat', $point->getLatitude())
->setParameter('lng', $point->getLongitude()); ->setParameter('lng', $point->getLongitude());
@ -73,14 +73,14 @@ class MapTools
// error_log($query->getSql()); // error_log($query->getSql());
$result = $query->getResult(); $result = $query->getResult();
$outlets = []; $hubs = [];
$final_data = []; $final_data = [];
foreach ($result as $row) foreach ($result as $row)
{ {
//error_log($row[0]->getName() . ' - ' . $row['dist']); //error_log($row[0]->getName() . ' - ' . $row['dist']);
$outlets[] = $row[0]; $hubs[] = $row[0];
$final_data[] = [ $final_data[] = [
'outlet' => $row[0], 'hub' => $row[0],
'db_distance' => $row['dist'], 'db_distance' => $row['dist'],
'distance' => 0, 'distance' => 0,
'duration' => 0, 'duration' => 0,
@ -88,7 +88,7 @@ class MapTools
} }
// get actual distance details with eta from google maps api // get actual distance details with eta from google maps api
$raw_res = $this->mapGetDistances($point, $outlets); $raw_res = $this->mapGetDistances($point, $hubs);
$res = json_decode($raw_res, true); $res = json_decode($raw_res, true);
//error_log(print_r($res, true)); //error_log(print_r($res, true));