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..2d7f74d5 --- /dev/null +++ b/config/routes/resq_job_order.yaml @@ -0,0 +1,14 @@ +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] + +jo_resq_proc_unlock: + path: /resq-job-order/{id}/unlock/processor + controller: App\Controller\ResqJobOrderController::unlockProcessor + methods: [GET] diff --git a/src/Controller/ResqJobOrderController.php b/src/Controller/ResqJobOrderController.php new file mode 100644 index 00000000..da0df5ff --- /dev/null +++ b/src/Controller/ResqJobOrderController.php @@ -0,0 +1,170 @@ +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) + { + // 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 + $row['meta']['update_url'] = $this->generateUrl('jo_proc_form', ['id' => $orow->getID()]); + $row['meta']['unlock_url'] = $this->generateUrl('jo_resq_proc_unlock', ['id' => $orow->getID()]); + + $rows[] = $row; + } + + // response + return $this->json([ + 'meta' => $meta, + 'data' => $rows + ]); + } + + /** + * @Menu(selected="jo_resq_proc") + * @ParamConverter("job_order", class="App\Entity\JobOrder") + * @IsGranted("jo_resq_proc.list") + */ + public function unlockProcessor($id, EntityManagerInterface $em, JobOrder $jo) + { + $jo->setProcessedBy(null); + + $em->flush(); + + // redirect to list + return $this->redirectToRoute('jo_resq_proc'); + } + + + 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/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 %} + +
+
+
+

+ RESQ Job Orders (Dispatch) +

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %}