diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index acbccba7..a1dc2f97 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -227,20 +227,9 @@ class JobOrderController extends Controller { $this->denyAccessUnlessGranted('jo_open.edit', null, 'No access.'); - $em = $this->getDoctrine()->getManager(); - $jo = $em->getRepository(JobOrder::class)->find($id); - - $params['obj'] = $jo; - $params['mode'] = 'open_edit'; + $params = $jo_handler->initializeOpenEditForm($id); $params['submit_url'] = $this->generateUrl('jo_open_edit_submit', ['id' => $id]); $params['return_url'] = $this->generateUrl('jo_open'); - $params['cvid'] = $jo->getCustomerVehicle()->getID(); - $params['vid'] = $jo->getCustomerVehicle()->getVehicle()->getID(); - - $em = $this->getDoctrine()->getManager(); - - $this->fillDropdownParameters($params); - $this->fillFormTags($params); // response return $this->render('job-order/form.html.twig', $params); @@ -271,35 +260,14 @@ class JobOrderController extends Controller /** * @Menu(selected="jo_in") */ - public function incomingVehicleForm($cvid) + public function incomingVehicleForm($cvid, JobOrderHandlerInterface $jo_handler) { $this->denyAccessUnlessGranted('jo_in.list', null, 'No access.'); - $params['mode'] = 'create_vehicle'; + $params = $jo_handler->initializeIncomingVehicleForm($cvid); + $params['submit_url'] = $this->generateUrl('jo_in_submit'); $params['return_url'] = $this->generateUrl('jo_in'); - $params['cvid'] = $cvid; - - $em = $this->getDoctrine()->getManager(); - - // get customer vehicle - $cv = $em->getRepository(CustomerVehicle::class)->find($cvid); - $params['vid'] = $cv->getVehicle()->getID(); - - // make sure this customer vehicle exists - if (empty($cv)) - { - $em->getConnection()->rollback(); - throw $this->createNotFoundException('The job order does not exist'); - } - - $jo = new JobOrder(); - $jo->setCustomerVehicle($cv) - ->setCustomer($cv->getCustomer()); - - $params['obj'] = $jo; - $this->fillDropdownParameters($params); - $this->fillFormTags($params); // response return $this->render('job-order/form.html.twig', $params); @@ -610,121 +578,13 @@ class JobOrderController extends Controller /** * @Menu(selected="jo_proc") */ - public function processingForm(MapTools $map_tools, $id) + public function processingForm(MapTools $map_tools, $id, JobOrderHandlerInterface $jo_handler) { $this->denyAccessUnlessGranted('jo_proc.list', null, 'No access.'); - $em = $this->getDoctrine()->getManager(); + $params = $jo_handler->initializeDispatchForm($id, $map_tools); - // manual transaction since we're locking - $em->getConnection()->beginTransaction(); - - try - { - - // lock and get data - $obj = $em->getRepository(JobOrder::class)->find($id, LockMode::PESSIMISTIC_READ); - - // make sure this job order exists - if (empty($obj)) - { - $em->getConnection()->rollback(); - throw $this->createNotFoundException('The job order does not exist'); - } - - // check status - if ($obj->getStatus() != JOStatus::PENDING) - { - $em->getConnection()->rollback(); - throw $this->createNotFoundException('The job order does not have a pending status'); - } - - // check if we are the processor - $processor = $obj->getProcessedBy(); - $user = $this->getUser(); - // TODO: go back to list page and display alert / flash that says they cannot access it because they - // are not the processor - if ($processor != null && $processor->getID() != $user->getID()) - { - $em->getConnection()->rollback(); - throw $this->createAccessDeniedException('Not the processor'); - } - - // make this user be the processor - $obj->setProcessedBy($user); - $em->flush(); - - $em->getConnection()->commit(); - } - catch(PessimisticLockException $e) - { - throw $this->createAccessDeniedException('Not the processor'); - } - - // NOTE: we are able to lock, everything should be fine now - - $params['mode'] = 'update-processing'; - $params['status_cancelled'] = JOStatus::CANCELLED; - - $this->fillDropdownParameters($params); - $this->fillFormTags($params); - - // get rejections - $rejections = $obj->getHubRejections(); - - // get rejection reasons - $params['rejection_reasons'] = JORejectionReason::getCollection(); - - // get closest hubs - $hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s")); - - $params['hubs'] = []; - - // format duration and distance into friendly time - foreach ($hubs as $hub) { - // duration - $seconds = $hub['duration']; - - if (!empty($seconds) && $seconds > 0) { - $hours = floor($seconds / 3600); - $minutes = ceil(($seconds / 60) % 60); - - $hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : ''); - } else { - $hub['duration'] = false; - } - - // distance - $meters = $hub['distance']; - - if (!empty($meters) && $meters > 0) { - $hub['distance'] = round($meters / 1000) . " km"; - } else { - $hub['distance'] = false; - } - - // counters - $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); - $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders()); - - // check for rejection - $hub['flag_rejected'] = false; - $hub_id = $hub['hub']->getID(); - - foreach ($rejections as $robj) - { - if ($robj->getHub()->getID() === $hub_id) - { - $hub['flag_rejected'] = true; - break; - } - } - - $params['hubs'][] = $hub; - } - - $params['obj'] = $obj; - $params['submit_url'] = $this->generateUrl('jo_proc_submit', ['id' => $obj->getID()]); + $params['submit_url'] = $this->generateUrl('jo_proc_submit', ['id' => $id]); $params['return_url'] = $this->generateUrl('jo_proc'); // response @@ -1338,57 +1198,15 @@ class JobOrderController extends Controller /** * @Menu(selected="jo_all") */ - public function allForm($id) + public function allForm($id, JobOrderHandlerInterface $jo_handler) { $this->denyAccessUnlessGranted('jo_all.list', null, 'No access.'); - $em = $this->getDoctrine()->getManager(); + $params = $jo_handler->initializeAllForm($id); - $params['mode'] = 'update-all'; - - // get row data - $obj = $em->getRepository(JobOrder::class)->find($id); - - // make sure this row exists - if (empty($obj)) - throw $this->createNotFoundException('The job order does not exist'); - - $this->fillDropdownParameters($params); - $this->fillFormTags($params); - - $params['obj'] = $obj; - $params['status_cancelled'] = JOStatus::CANCELLED; $params['return_url'] = $this->generateUrl('jo_all'); $params['submit_url'] = ''; - // timeline stuff (descending by time) - $params['timeline'] = [ - [ - 'date' => date("M j"), - 'time' => date("g:i A"), - 'event' => "Event 4", - 'color' => "#f4516c" - ], - [ - 'date' => date("M j"), - 'time' => date("g:i A"), - 'event' => "Event 3", - 'color' => "#34bfa3" - ], - [ - 'date' => date("M j"), - 'time' => date("g:i A"), - 'event' => "Event 2", - 'color' => "#716aca" - ], - [ - 'date' => date("M j"), - 'time' => date("g:i A"), - 'event' => "Event 1", - 'color' => "#ffb822" - ], - ]; - // response return $this->render('job-order/form.html.twig', $params); } diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index f6239ded..73a1bbfe 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -7,6 +7,9 @@ use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\HttpFoundation\Request; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\LockMode; +use Doctrine\ORM\PessimisticLockException; use App\Entity\JobOrder; use App\Entity\Battery; @@ -16,6 +19,7 @@ use App\Entity\CustomerVehicle; use App\Entity\Hub; use App\Entity\Promo; use App\Entity\Rider; +use App\Entity\JORejection; use App\Ramcar\InvoiceCriteria; use App\Ramcar\ServiceType; @@ -27,11 +31,13 @@ use App\Ramcar\DiscountApply; use App\Ramcar\ModeOfPayment; use App\Ramcar\TransactionOrigin; use App\Ramcar\FacilitatedType; +use App\Ramcar\JORejectionReason; use App\Service\InvoiceGeneratorInterface; use App\Service\JobOrderHandlerInterface; use App\Service\MQTTClient; use App\Service\APNSClient; +use App\Service\MapTools; use CrEOF\Spatial\PHP\Types\Geometry\Point; @@ -579,6 +585,207 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface return $params; } + // initialize incoming vehicle form + public function initializeIncomingVehicleForm(int $cvid) + { + $params['mode'] = 'create_vehicle'; + $params['cvid'] = $cvid; + + $em = $this->em; + + // get customer vehicle + $cv = $em->getRepository(CustomerVehicle::class)->find($cvid); + $params['vid'] = $cv->getVehicle()->getID(); + + // make sure this customer vehicle exists + if (empty($cv)) + { + $em->getConnection()->rollback(); + throw $this->createNotFoundException('The job order does not exist'); + } + + $jo = new JobOrder(); + $jo->setCustomerVehicle($cv) + ->setCustomer($cv->getCustomer()); + + $params['obj'] = $jo; + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + return $params; + } + + // initialize all job orders form for a specific job order id + public function initializeAllForm($id) + { + $em = $this->em; + + $params['mode'] = 'update-all'; + + // get row data + $obj = $em->getRepository(JobOrder::class)->find($id); + + // make sure this row exists + if (empty($obj)) + throw $this->createNotFoundException('The job order does not exist'); + + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + $params['obj'] = $obj; + $params['status_cancelled'] = JOStatus::CANCELLED; + + // timeline stuff (descending by time) + $params['timeline'] = [ + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 4", + 'color' => "#f4516c" + ], + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 3", + 'color' => "#34bfa3" + ], + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 2", + 'color' => "#716aca" + ], + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 1", + 'color' => "#ffb822" + ], + ]; + + return $params; + } + + // initialize dispatch/processing job order form + public function initializeDispatchForm($id, $map_tools) + { + $em = $this->em; + + // manual transaction since we're locking + $em->getConnection()->beginTransaction(); + + try + { + // lock and get data + $obj = $em->getRepository(JobOrder::class)->find($id, LockMode::PESSIMISTIC_READ); + + // make sure this job order exists + if (empty($obj)) + { + $em->getConnection()->rollback(); + throw $this->createNotFoundException('The job order does not exist'); + } + + // check status + if ($obj->getStatus() != JOStatus::PENDING) + { + $em->getConnection()->rollback(); + throw $this->createNotFoundException('The job order does not have a pending status'); + } + + // check if we are the processor + $processor = $obj->getProcessedBy(); + // get current user + $user = $this->security->getUser(); + if ($user != null) + { + // TODO: go back to list page and display alert / flash that says they cannot access it because they + // are not the processor + if ($processor != null && $processor->getID() != $user->getID()) + { + $em->getConnection()->rollback(); + throw $this->createAccessDeniedException('Not the processor'); + } + + // make this user be the processor + $obj->setProcessedBy($user); + } + $em->flush(); + + $em->getConnection()->commit(); + } + catch(PessimisticLockException $e) + { + throw $this->createAccessDeniedException('Not the processor'); + } + + // NOTE: we are able to lock, everything should be fine now + + $params['mode'] = 'update-processing'; + $params['status_cancelled'] = JOStatus::CANCELLED; + + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + // get rejections + $rejections = $obj->getHubRejections(); + + // get rejection reasons + $params['rejection_reasons'] = JORejectionReason::getCollection(); + + // get closest hubs + $hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s")); + + $params['hubs'] = []; + + // format duration and distance into friendly time + foreach ($hubs as $hub) { + // duration + $seconds = $hub['duration']; + + if (!empty($seconds) && $seconds > 0) { + $hours = floor($seconds / 3600); + $minutes = ceil(($seconds / 60) % 60); + + $hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : ''); + } else { + $hub['duration'] = false; + } + + // distance + $meters = $hub['distance']; + + if (!empty($meters) && $meters > 0) { + $hub['distance'] = round($meters / 1000) . " km"; + } else { + $hub['distance'] = false; + } + + // counters + $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); + $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders()); + + // check for rejection + $hub['flag_rejected'] = false; + $hub_id = $hub['hub']->getID(); + + foreach ($rejections as $robj) + { + if ($robj->getHub()->getID() === $hub_id) + { + $hub['flag_rejected'] = true; + break; + } + } + + $params['hubs'][] = $hub; + } + + $params['obj'] = $obj; + + return $params; + } + protected function fillDropdownParameters(&$params) { $em = $this->em; diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index b165212e..052dce72 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -7,6 +7,9 @@ use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\HttpFoundation\Request; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\LockMode; +use Doctrine\ORM\PessimisticLockException; use App\Entity\JobOrder; use App\Entity\Battery; @@ -16,6 +19,7 @@ use App\Entity\CustomerVehicle; use App\Entity\Hub; use App\Entity\Promo; use App\Entity\Rider; +use App\Entity\JORejection; use App\Ramcar\InvoiceCriteria; use App\Ramcar\ServiceType; @@ -27,11 +31,13 @@ use App\Ramcar\DiscountApply; use App\Ramcar\ModeOfPayment; use App\Ramcar\TransactionOrigin; use App\Ramcar\FacilitatedType; +use App\Ramcar\JORejectionReason; use App\Service\InvoiceGeneratorInterface; use App\Service\JobOrderHandlerInterface; use App\Service\MQTTClient; use App\Service\APNSClient; +use App\Service\MapTools; use CrEOF\Spatial\PHP\Types\Geometry\Point; @@ -579,6 +585,207 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface return $params; } + // initialize incoming vehicle form + public function initializeIncomingVehicleForm(int $cvid) + { + $params['mode'] = 'create_vehicle'; + $params['cvid'] = $cvid; + + $em = $this->em; + + // get customer vehicle + $cv = $em->getRepository(CustomerVehicle::class)->find($cvid); + $params['vid'] = $cv->getVehicle()->getID(); + + // make sure this customer vehicle exists + if (empty($cv)) + { + $em->getConnection()->rollback(); + throw $this->createNotFoundException('The job order does not exist'); + } + + $jo = new JobOrder(); + $jo->setCustomerVehicle($cv) + ->setCustomer($cv->getCustomer()); + + $params['obj'] = $jo; + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + return $params; + } + + // initialize all job orders form for a specific job order id + public function initializeAllForm($id) + { + $em = $this->em; + + $params['mode'] = 'update-all'; + + // get row data + $obj = $em->getRepository(JobOrder::class)->find($id); + + // make sure this row exists + if (empty($obj)) + throw $this->createNotFoundException('The job order does not exist'); + + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + $params['obj'] = $obj; + $params['status_cancelled'] = JOStatus::CANCELLED; + + // timeline stuff (descending by time) + $params['timeline'] = [ + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 4", + 'color' => "#f4516c" + ], + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 3", + 'color' => "#34bfa3" + ], + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 2", + 'color' => "#716aca" + ], + [ + 'date' => date("M j"), + 'time' => date("g:i A"), + 'event' => "Event 1", + 'color' => "#ffb822" + ], + ]; + + return $params; + } + + // initialize dispatch/processing job order form + public function initializeDispatchForm($id, $map_tools) + { + $em = $this->em; + + // manual transaction since we're locking + $em->getConnection()->beginTransaction(); + + try + { + // lock and get data + $obj = $em->getRepository(JobOrder::class)->find($id, LockMode::PESSIMISTIC_READ); + + // make sure this job order exists + if (empty($obj)) + { + $em->getConnection()->rollback(); + throw $this->createNotFoundException('The job order does not exist'); + } + + // check status + if ($obj->getStatus() != JOStatus::PENDING) + { + $em->getConnection()->rollback(); + throw $this->createNotFoundException('The job order does not have a pending status'); + } + + // check if we are the processor + $processor = $obj->getProcessedBy(); + // get current user + $user = $this->security->getUser(); + if ($user != null) + { + // TODO: go back to list page and display alert / flash that says they cannot access it because they + // are not the processor + if ($processor != null && $processor->getID() != $user->getID()) + { + $em->getConnection()->rollback(); + throw $this->createAccessDeniedException('Not the processor'); + } + + // make this user be the processor + $obj->setProcessedBy($user); + } + $em->flush(); + + $em->getConnection()->commit(); + } + catch(PessimisticLockException $e) + { + throw $this->createAccessDeniedException('Not the processor'); + } + + // NOTE: we are able to lock, everything should be fine now + + $params['mode'] = 'update-processing'; + $params['status_cancelled'] = JOStatus::CANCELLED; + + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + // get rejections + $rejections = $obj->getHubRejections(); + + // get rejection reasons + $params['rejection_reasons'] = JORejectionReason::getCollection(); + + // get closest hubs + $hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s")); + + $params['hubs'] = []; + + // format duration and distance into friendly time + foreach ($hubs as $hub) { + // duration + $seconds = $hub['duration']; + + if (!empty($seconds) && $seconds > 0) { + $hours = floor($seconds / 3600); + $minutes = ceil(($seconds / 60) % 60); + + $hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : ''); + } else { + $hub['duration'] = false; + } + + // distance + $meters = $hub['distance']; + + if (!empty($meters) && $meters > 0) { + $hub['distance'] = round($meters / 1000) . " km"; + } else { + $hub['distance'] = false; + } + + // counters + $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); + $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders()); + + // check for rejection + $hub['flag_rejected'] = false; + $hub_id = $hub['hub']->getID(); + + foreach ($rejections as $robj) + { + if ($robj->getHub()->getID() === $hub_id) + { + $hub['flag_rejected'] = true; + break; + } + } + + $params['hubs'][] = $hub; + } + + $params['obj'] = $obj; + + return $params; + } + protected function fillDropdownParameters(&$params) { $em = $this->em; diff --git a/src/Service/JobOrderHandlerInterface.php b/src/Service/JobOrderHandlerInterface.php index 193a7952..4dae3034 100644 --- a/src/Service/JobOrderHandlerInterface.php +++ b/src/Service/JobOrderHandlerInterface.php @@ -6,6 +6,7 @@ use Symfony\Component\HttpFoundation\Request; use App\Service\MQTTClient; use App\Service\APNSClient; +use App\Service\MapTools; interface JobOrderHandlerInterface { @@ -29,4 +30,13 @@ interface JobOrderHandlerInterface // initialize open edit job order form public function initializeOpenEditForm(int $id); + + // initialize incoming vehicle form + public function initializeIncomingVehicleForm(int $cvid); + + // initialize all job orders form for a specific job order id + public function initializeAllForm(int $id); + + // initialize dispatch/processing job order form + public function initializeDispatchForm(int $id, MapTools $map_tools); }