diff --git a/config/acl.yaml b/config/acl.yaml index 25e04dbc..f95f9eb1 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -266,6 +266,8 @@ access_keys: label: Walk-in Edit - id: jo_autoassign.test label: Autoassign Test + - id: jo_hub.list + label: Hub View - id: support label: Customer Support Access diff --git a/config/menu.yaml b/config/menu.yaml index b0096cf5..f04dd4f9 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -122,6 +122,10 @@ main_menu: acl: jo_all.list label: View All parent: joborder + - id: jo_hub_view + acl: jo_hub.list + label: Hub View + parent: joborder - id: support acl: support.menu diff --git a/config/resq.menu.yaml b/config/resq.menu.yaml index b0096cf5..69f0b806 100644 --- a/config/resq.menu.yaml +++ b/config/resq.menu.yaml @@ -122,6 +122,9 @@ main_menu: acl: jo_all.list label: View All parent: joborder + - id: jo_hub.view + label: Hub View + parent: joborder - id: support acl: support.menu diff --git a/config/routes/job_order.yaml b/config/routes/job_order.yaml index f239402d..586ed81f 100644 --- a/config/routes/job_order.yaml +++ b/config/routes/job_order.yaml @@ -235,3 +235,21 @@ jo_autoassign_test_submit: path: /job-order/autoassign controller: App\Controller\JobOrderController::autoAssignSubmit methods: [POST] + +jo_hub_view: + path: /job-order/hub-view + controller: App\Controller\JobOrderController::hubView + methods: [GET] + +jo_hub_view_rows: + path: /job-order/hub-view-rows + controller: App\Controller\JobOrderController::getHubViewRows + methods: [POST] + defaults: + tier: "hub_view_all" + +jo_hub_view_form: + path: /job-order/hub-view/{id} + controller: App\Controller\JobOrderController::hubViewForm + methods: [GET] + diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index d8866203..f23fc73c 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -1065,6 +1065,95 @@ class JobOrderController extends Controller ]); } + /** + * @Menu(selected="jo_hub_view") + */ + public function hubView(JobOrderHandlerInterface $jo_handler) + { + $this->denyAccessUnlessGranted('jo_hub.list', null, 'No access.'); + + $template = $jo_handler->getTwigTemplate('jo_hub_list'); + + $params = $jo_handler->getOtherParameters(); + $params['table_refresh_rate'] = $this->container->getParameter('job_order_refresh_interval'); + + return $this->render($template, $params); + } + + public function getHubViewRows(Request $req, $tier, JobOrderHandlerInterface $jo_handler) + { + try + { + $params = $jo_handler->getHubViewRows($req, $tier); + } + catch (AccessDeniedHttpException $e) + { + throw $this->createAccessDeniedException($e->getMessage()); + } + + $rows = $params['rows']; + $meta = $params['meta']; + $tier_params = $params['tier_params']; + + foreach ($rows as $key => $data) { + // add crud urls + $jo_id = $rows[$key]['id']; + + if ($tier == 'open') + { + $rows[$key]['meta']['reassign_hub_url'] = $this->generateUrl('jo_open_hub_form', ['id' => $jo_id]); + $rows[$key]['meta']['reassign_rider_url'] = $this->generateUrl('jo_open_rider_form', ['id' => $jo_id]); + // $rows[$key]['meta']['edit_url'] = $this->generateUrl('jo_open_edit_form', ['id' => $jo_id]); + $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); + } + else + { + // $rows[$key]['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $jo_id]); + $rows[$key]['meta']['update_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); + } + + if ($tier_params['unlock_route'] != '') + $rows[$key]['meta']['unlock_url'] = $this->generateUrl($tier_params['unlock_route'], ['id' => $jo_id]); + + } + + // response + return $this->json([ + 'meta' => $meta, + 'data' => $rows + ]); + } + + /** + * @Menu(selected="jo_hub_view") + */ + public function hubViewForm($id, JobOrderHandlerInterface $jo_handler, + GISManagerInterface $gis, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('jo_hub.list', null, 'No access.'); + + try + { + $params = $jo_handler->initializeHubViewForm($id); + } + catch (NotFoundHttpException $e) + { + throw $this->createNotFoundException($e->getMessage()); + } + + $params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll(); + $params['vmakes'] = $em->getRepository(Vehicle::class)->findAll(); + $params['return_url'] = $this->generateUrl('jo_hub_view'); + $params['submit_url'] = ''; + $params['map_js_file'] = $gis->getJSJOFile(); + + $template = $params['template']; + + // response + return $this->render($template, $params); + } + + /** * @Menu(selected="jo_autoassign") */ diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 54deda2f..b6971ce1 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -2341,6 +2341,9 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // get riders for dropdown $params['riders'] = $this->em->getRepository(Rider::class)->findAll(); + // get hubs for dropdown + $params['hubs'] = $this->em->getRepository(Hub::class)->findAll(); + return $params; } @@ -2509,6 +2512,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->template_hash['jo_list_open'] = 'job-order/list.open.html.twig'; $this->template_hash['jo_list_all'] = 'job-order/list.all.html.twig'; $this->template_hash['jo_popup'] = 'job-order/popup.html.twig'; + $this->template_hash['jo_hub_list'] = 'job-order/list.hubview.html.twig'; + $this->template_hash['jo_hub_view_form'] = 'job-order/form.html.twig'; } protected function checkTier($tier) @@ -2564,6 +2569,14 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $unlock_route = ''; $jo_status = ''; break; + case 'hub_view_all': + $tier_key = 'jo_hub'; + $tier_name = 'Open'; + $rows_route = 'jo_hub_view_rows'; + $edit_route = 'jo_hub_view_form'; + $unlock_route = ''; + $jo_status = ''; + break; default: throw new AccessDeniedHttpException('No access.'); } @@ -2695,6 +2708,35 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setParameter('date_end', $date_end); } break; + case 'hub_view_all': + if (isset($datatable['query']['data-rows-search'])) + { + $query->innerJoin('q.cus_vehicle', 'cv') + ->innerJoin('q.customer', 'c') + ->where('cv.plate_number like :filter') + ->orWhere('c.phone_mobile like :filter') + ->orWhere('c.first_name like :filter or c.last_name like :filter') + ->setParameter('filter', $datatable['query']['data-rows-search'] . '%'); + } + if (isset($datatable['query']['hub'])) + { + $query->innerJoin('q.hub', 'h') + ->andWhere('h.id = :hub_id') + ->setParameter('hub_id', $datatable['query']['hub']); + } + + $c_date = new DateTime(); + $start_curr_date = $c_date->format('Y-m-d') . ' ' . '00:00:00'; + $end_curr_date = $c_date->format('Y-m-d') . ' ' . '23:59:00'; + + $start_current_date = DateTime::createFromFormat('Y-m-d H:i:s', $start_curr_date); + $end_current_date = DateTime::createFromFormat('Y-m-d H:i:s', $end_curr_date); + + $query->andWhere('q.date_schedule >= :start_current_date') + ->andWhere('q.date_schedule <= :end_current_date') + ->setParameter('start_current_date', $start_current_date) + ->setParameter('end_current_date', $end_current_date); + break; default: $query->where('q.status = :status') ->setParameter('status', $status); @@ -2708,4 +2750,165 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface return $tier; } + + public function getHubViewRows(Request $req, $tier) + { + // check which job order tier is being called for and confirm access + $tier_params = $this->checkTier($tier); + + // get current user + $user = $this->security->getUser(); + if ($user == null) + throw new AccessDeniedHttpException('No access.'); + + $hubs = $user->getHubs(); + + // get query builder + $qb = $this->em->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, $hubs, $tier, $tier_params['jo_status']); + + $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 + $qb = $this->em->getRepository(JobOrder::class) + ->createQueryBuilder('q'); + $query = $qb->select('q'); + + $this->setQueryFilters($datatable, $query, $qb, $hubs, $tier, $tier_params['jo_status']); + + // 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(); + + // error_log($query_obj->getSQL()); + + $obj_rows = $query_obj->getResult(); + + $statuses = JOStatus::getCollection(); + $service_types = ServiceType::getCollection(); + + // process rows + $rows = []; + foreach ($obj_rows as $orow) { + // 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; + + $processor = $orow->getProcessedBy(); + if ($processor == null) + $row['processor'] = ''; + else + $row['processor'] = $orow->getProcessedBy()->getFullName(); + + $assignor = $orow->getAssignedBy(); + if ($assignor == null) + $row['assignor'] = ''; + else + $row['assignor'] = $orow->getAssignedBy()->getFullName(); + + $rows[] = $row; + } + + $params['meta'] = $meta; + $params['rows'] = $rows; + $params['tier_params'] = $tier_params; + + return $params; + } + + public function initializeHubViewForm($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 new NotFoundHttpException('The job order does not exist'); + + $this->fillDropdownParameters($params); + $this->fillFormTags($params); + + // get template to display + $params['template'] = $this->getTwigTemplate('jo_hub_view_form'); + + $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; + } + } diff --git a/templates/job-order/list.hubview.html.twig b/templates/job-order/list.hubview.html.twig new file mode 100644 index 00000000..d59a76dc --- /dev/null +++ b/templates/job-order/list.hubview.html.twig @@ -0,0 +1,152 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +