diff --git a/config/acl.yaml b/config/acl.yaml index ee514ab5..714742f5 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -272,6 +272,8 @@ access_keys: label: Hub View - id: jo_cancel.fulfill label: Fulfill Cancelled JO + - id: jo_resq_proc.list + label: RESQ Dispatch - id: support label: Customer Support Access diff --git a/config/menu.yaml b/config/menu.yaml index f80daadd..05eb17a9 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -132,6 +132,10 @@ main_menu: acl: jo_proc.list label: Dispatch parent: joborder + - id: jo_resq_proc + acl: jo_resq_proc.list + label: RESQ Dispatch + parent: joborder - id: jo_assign acl: jo_assign.list label: Rider Assignment diff --git a/config/routes/resq_job_order.yaml b/config/routes/resq_job_order.yaml new file mode 100644 index 00000000..5c506621 --- /dev/null +++ b/config/routes/resq_job_order.yaml @@ -0,0 +1,9 @@ +jo_resq_proc: + path: /resq-job-order/processing + controller: App\Controller\ResqJobOrderController::listProcessing + methods: [GET] + +jo_resq_proc_rows: + path: /resq-job-order/processing-rows + controller: App\Controller\ResqJobOrderController::datatableRows + methods: [POST] diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index f847a842..485709e4 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -316,7 +316,7 @@ class JobOrderController extends Controller /** * @Menu(selected="jo_proc") */ - public function processingForm(HubSelector $hub_selector, $id, JobOrderHandlerInterface $jo_handler, GISManagerInterface $gis, MotivConnector $motiv) + public function processingForm(HubSelector $hub_selector, $id, JobOrderHandlerInterface $jo_handler, GISManagerInterface $gis, MotivConnector $motiv, Request $req) { $this->denyAccessUnlessGranted('jo_proc.list', null, 'No access.'); @@ -337,6 +337,18 @@ class JobOrderController extends Controller $params['return_url'] = $this->generateUrl('jo_proc'); $params['map_js_file'] = $gis->getJSJOFile(); + // check for origin parameter + $origin = $req->query->get('origin', ''); + if (empty($origin)) + { + // set return url to default dispatch + $params['return_url'] = $this->generateUrl('jo_proc'); + } + else + { + // set return url to resq dispatch + $params['return_url'] = $this->generateUrl('jo_resq_proc'); + } $template = $params['template']; // response @@ -795,15 +807,25 @@ class JobOrderController extends Controller ]); } - public function unlockProcessor($id, JobOrderHandlerInterface $jo_handler) + public function unlockProcessor($id, JobOrderHandlerInterface $jo_handler, Request $req) { $this->denyAccessUnlessGranted('jo_proc.unlock', null, 'No access.'); // call unlockProcessor in job order service $jo_handler->unlockProcessor($id); - // redirect to list - return $this->redirectToRoute('jo_proc'); + // get the origin + $origin = $req->query->get('origin', ''); + if (empty($origin)) + { + // redirect to list + return $this->redirectToRoute('jo_proc'); + } + else + { + // redirect to resq list + return $this->redirectToRoute('jo_resq_proc'); + } } public function unlockAssignor($id, JobOrderHandlerInterface $jo_handler) diff --git a/src/Controller/ResqJobOrderController.php b/src/Controller/ResqJobOrderController.php new file mode 100644 index 00000000..8295077d --- /dev/null +++ b/src/Controller/ResqJobOrderController.php @@ -0,0 +1,158 @@ +container->getParameter('job_order_refresh_interval'); + + return $this->render('resq-job-order/list.processing.html.twig', $params); + } + + /** + * @IsGranted("jo_resq_proc.list") + */ + public function datatableRows(Request $req, JobOrderHandlerInterface $jo_handler) + { + // get query builder + $qb = $this->getDoctrine() + ->getRepository(JobOrder::class) + ->createQueryBuilder('q'); + + // get datatable params + $datatable = $req->request->get('datatable'); + + // count total records + $tquery = $qb->select('COUNT(q)'); + + $this->setQueryFilters($datatable, $tquery, $qb, JOStatus::PENDING, TransactionOrigin::MOBILE_APP); + + $total = $tquery->getQuery() + ->getSingleScalarResult(); + + // get current page number + $page = $datatable['pagination']['page'] ?? 1; + + $perpage = $datatable['pagination']['perpage']; + $offset = ($page - 1) * $perpage; + + // add metadata + $meta = [ + 'page' => $page, + 'perpage' => $perpage, + 'pages' => ceil($total / $perpage), + 'total' => $total, + 'sort' => 'asc', + 'field' => 'id' + ]; + + // build query + $query = $qb->select('q'); + + $this->setQueryFilters($datatable, $query, $qb, JOStatus::PENDING, TransactionOrigin::MOBILE_APP); + + // check if sorting is present, otherwise use default + if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) { + $order = $datatable['sort']['sort'] ?? 'asc'; + $query->orderBy('q.' . $datatable['sort']['field'], $order); + } else { + $query->orderBy('q.date_schedule', 'asc'); + } + + // get rows for this page + $query_obj = $query->setFirstResult($offset) + ->setMaxResults($perpage) + ->getQuery(); + + $obj_rows = $query_obj->getResult(); + + $statuses = JOStatus::getCollection(); + $service_types = ServiceType::getCollection(); + + // process rows + $rows = []; + foreach ($obj_rows as $orow) { + $is_vip = false; + $is_emergency = false; + + // check if customer is vip + $cust_class = $orow->getCustomer()->getCustomerClassification(); + if ($cust_class == CustomerClassification::VIP) + $is_vip = true; + + // check if customer is not willing to wait + $will_not_wait = $orow->getWillWait(); + if ($will_not_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT) + $is_emergency = true; + + // add row data + $row['id'] = $orow->getID(); + $row['customer_name'] = $orow->getCustomer()->getFirstName() . ' ' . $orow->getCustomer()->getLastName(); + $row['delivery_address'] = $orow->getDeliveryAddress(); + $row['date_schedule'] = $orow->getDateSchedule()->format("d M Y g:i A"); + $row['type'] = $orow->isAdvanceOrder() ? 'Advanced Order' : 'Immediate'; + $row['service_type'] = $service_types[$orow->getServiceType()]; + $row['status'] = $statuses[$orow->getStatus()]; + $row['flag_advance'] = $orow->isAdvanceOrder(); + $row['plate_number'] = $orow->getCustomerVehicle()->getPlateNumber(); + $row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP; + $row['is_vip'] = $is_vip; + $row['is_emergency'] = $is_emergency; + + $processor = $orow->getProcessedBy(); + if ($processor == null) + $row['processor'] = ''; + else + $row['processor'] = $orow->getProcessedBy()->getFullName(); + + // add the items for Actions + $jo_id = $orow->getID(); + + $row['meta']['update_url'] = $this->generateUrl('jo_proc_form', ['id' => $jo_id, 'origin' => 'resq']); + $row['meta']['unlock_url'] = $this->generateUrl('jo_proc_unlock', ['id' => $jo_id, 'origin' => 'resq']); + + $rows[] = $row; + } + + // response + return $this->json([ + 'meta' => $meta, + 'data' => $rows + ]); + } + + protected function setQueryFilters($datatable, &$query, $qb, $status, $source) + { + $query->where('q.status = :status') + ->andWhere('q.source = :source') + ->setParameter('status', $status) + ->setParameter('source', $source); + } +} diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index f94b5ee1..6d2e6dec 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -3583,6 +3583,13 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setParameter('end_current_date', $end_current_date) ->setParameter('statuses', $status, Connection::PARAM_STR_ARRAY); } + break; + case 'proc': + $query->where('q.status = :status') + ->andWhere('q.source <> :source') + ->setParameter('status', $status) + ->setParameter('source', TransactionOrigin::MOBILE_APP); + break; default: $query->where('q.status = :status') diff --git a/templates/resq-job-order/list.processing.html.twig b/templates/resq-job-order/list.processing.html.twig new file mode 100644 index 00000000..b9007f02 --- /dev/null +++ b/templates/resq-job-order/list.processing.html.twig @@ -0,0 +1,155 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +