denyAccessUnlessGranted('jo_in.list', null, 'No access.'); $params = $this->initParameters('jo_in'); $params['obj'] = new JobOrder(); $params['mode'] = 'create'; $params['submit_url'] = $this->generateUrl('jo_in_submit'); $params['return_url'] = $this->generateUrl('jo_in'); $em = $this->getDoctrine()->getManager(); // get parent associations $params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll(); $params['customers'] = $em->getRepository(Customer::class)->findAll(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); $params['service_types'] = ServiceType::getCollection(); $params['warranty_classes'] = WarrantyClass::getCollection(); $params['statuses'] = JOStatus::getCollection(); $params['discount_apply'] = DiscountApply::getCollection(); // response return $this->render('job-order/form.html.twig', $params); } public function incomingSubmit(Request $req, ValidatorInterface $validator) { $this->denyAccessUnlessGranted('jo_in.list', null, 'No access.'); // initialize error list $error_array = []; // create new row $em = $this->getDoctrine()->getManager(); $obj = new JobOrder(); // check if lat and lng are provided if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; } // check if customer vehicle is set if (empty($req->request->get('customer_vehicle'))) { $error_array['customer_vehicle'] = 'No vehicle selected.'; } else { // get customer vehicle $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); if (empty($cust_vehicle)) { $error_array['customer_vehicle'] = 'Invalid vehicle specified.'; } } if (empty($error_array)) { // coordinates $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); // set and save values $obj->setDateCreate(DateTime::createFromFormat("d M Y", $req->request->get('date_transaction'))) ->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) ->setCoordinates($point) ->setAdvanceOrder($req->request->get('flag_advance') ?? false) ->setCreatedBy($this->getUser()) ->setServiceType($req->request->get('service_type')) ->setWarrantyClass($req->request->get('warranty_class')) ->setCustomer($cust_vehicle->getCustomer()) ->setCustomerVehicle($cust_vehicle) ->setSource('web') ->setStatus(JOStatus::PENDING) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setAgentNotes($req->request->get('agent_notes')) ->setDeliveryAddress($req->request->get('delivery_address')); // validate $errors = $validator->validate($obj); // add errors to list foreach ($errors as $error) { $error_array[$error->getPropertyPath()] = $error->getMessage(); } } // check if any errors were found if (!empty($error_array)) { // return validation failure response return $this->json([ 'success' => false, 'errors' => $error_array ], 422); } // validated! save the entity $em->persist($obj); $em->flush(); // return successful response return $this->json([ 'success' => 'Changes have been saved!' ]); } protected function checkTier($tier) { // check specified tier switch ($tier) { case 'proc': $tier_key = 'jo_proc'; $tier_name = 'Processing'; $rows_route = 'jo_proc_rows'; $edit_route = 'jo_proc_form'; $jo_status = JOStatus::PENDING; break; case 'assign': $tier_key = 'jo_assign'; $tier_name = 'Assigning'; $rows_route = 'jo_assign_rows'; $edit_route = 'jo_assign_form'; $jo_status = JOStatus::RIDER_ASSIGN; break; default: $exception = $this->createAccessDeniedException('No access.'); throw $exception; } // check acl $this->denyAccessUnlessGranted($tier_key . '.list', null, 'No access.'); // return params if allowed access return [ 'key' => $tier_key, 'name' => $tier_name, 'rows_route' => $rows_route, 'edit_route' => $edit_route, 'jo_status' => $jo_status ]; } public function listRows($tier) { // check which job order tier is being called for and confirm access $tier_params = $this->checkTier($tier); $params = $this->initParameters($tier_params['key']); $params['tier_name'] = $tier_params['name']; $params['rows_route'] = $tier_params['rows_route']; // response return $this->render('job-order/list.html.twig', $params); } public function getRows(Request $req, $tier) { // check which job order tier is being called for and confirm access $tier_params = $this->checkTier($tier); // 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, $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 $query = $qb->select('q'); $this->setQueryFilters($datatable, $query, $qb, $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 $obj_rows = $query->setFirstResult($offset) ->setMaxResults($perpage) ->getQuery() ->getResult(); $statuses = JOStatus::getCollection(); $service_types = ServiceType::getCollection(); // process rows $rows = []; foreach ($obj_rows as $orow) { // add row data $row['id'] = $orow->getID(); $row['delivery_address'] = $orow->getDeliveryAddress(); $row['date_schedule'] = $orow->isAdvanceOrder() ? $orow->getDateSchedule()->format("d M Y g:i A") : 'Immediate'; $row['service_type'] = $service_types[$orow->getServiceType()]; $row['status'] = $statuses[$orow->getStatus()]; $row['flag_advance'] = $orow->isAdvanceOrder(); // add crud urls $row['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $row['id']]); $rows[] = $row; } // response return $this->json([ 'meta' => $meta, 'data' => $rows ]); } public function processingForm(MapTools $map_tools, $id) { $this->denyAccessUnlessGranted('jo_proc.list', null, 'No access.'); $params = $this->initParameters('jo_proc'); $params['mode'] = 'update-processing'; // get row data $em = $this->getDoctrine()->getManager(); $obj = $em->getRepository(JobOrder::class)->find($id); // make sure this row exists if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); // get parent associations $params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll(); $params['customers'] = $em->getRepository(Customer::class)->findAll(); $params['service_types'] = ServiceType::getCollection(); $params['warranty_classes'] = WarrantyClass::getCollection(); $params['statuses'] = JOStatus::getCollection(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); $params['discount_apply'] = DiscountApply::getCollection(); // get closest outlets $outlets = $map_tools->getClosestOutlets($obj->getCoordinates(), 10, date("H:i:s")); $params['outlets'] = []; // format duration and distance into friendly time foreach ($outlets as $outlet) { // duration $seconds = $outlet['duration']; if (!empty($seconds) && $seconds > 0) { $hours = floor($seconds / 3600); $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" : '') : ''); } else { $outlet['duration'] = false; } // distance $meters = $outlet['distance']; if (!empty($meters) && $meters > 0) { $outlet['distance'] = round($meters / 1000) . " km"; } else { $outlet['distance'] = false; } $params['outlets'][] = $outlet; } $params['obj'] = $obj; $params['submit_url'] = $this->generateUrl('jo_proc_submit', ['id' => $obj->getID()]); $params['return_url'] = $this->generateUrl('jo_proc'); // response return $this->render('job-order/form.html.twig', $params); } public function processingSubmit(Request $req, ValidatorInterface $validator, $id) { $this->denyAccessUnlessGranted('jo_proc.list', null, 'No access.'); // initialize error list $error_array = []; // get object data $em = $this->getDoctrine()->getManager(); $obj = $em->getRepository(JobOrder::class)->find($id); // make sure this object exists if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); // check if lat and lng are provided if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; } // check if outlet is set if (empty($req->request->get('outlet'))) { $error_array['outlet'] = 'No outlet selected.'; } else { // get outlet $outlet = $em->getRepository(Outlet::class)->find($req->request->get('outlet')); if (empty($outlet)) { $error_array['outlet'] = 'Invalid outlet specified.'; } } if (empty($error_array)) { // coordinates $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); // set and save values $obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) ->setCoordinates($point) ->setAdvanceOrder($req->request->get('flag_advance') ?? false) ->setServiceType($req->request->get('service_type')) ->setWarrantyClass($req->request->get('warranty_class')) ->setSource('web') ->setStatus(JOStatus::RIDER_ASSIGN) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setAgentNotes($req->request->get('agent_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) ->setOutlet($outlet); // validate $errors = $validator->validate($obj); // add errors to list foreach ($errors as $error) { $error_array[$error->getPropertyPath()] = $error->getMessage(); } } // check if any errors were found if (!empty($error_array)) { // return validation failure response return $this->json([ 'success' => false, 'errors' => $error_array ], 422); } // validated! save the entity $em->flush(); // return successful response return $this->json([ 'success' => 'Changes have been saved!' ]); } public function assigningForm(MapTools $map_tools, $id) { $this->denyAccessUnlessGranted('jo_assign.list', null, 'No access.'); $params = $this->initParameters('jo_assign'); $params['mode'] = 'update-assigning'; // get row data $em = $this->getDoctrine()->getManager(); $obj = $em->getRepository(JobOrder::class)->find($id); // make sure this row exists if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); // get parent associations $params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll(); $params['customers'] = $em->getRepository(Customer::class)->findAll(); $params['service_types'] = ServiceType::getCollection(); $params['warranty_classes'] = WarrantyClass::getCollection(); $params['statuses'] = JOStatus::getCollection(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); $params['discount_apply'] = DiscountApply::getCollection(); // get closest outlets $outlets = $map_tools->getClosestOutlets($obj->getCoordinates(), 10, date("H:i:s")); $params['outlets'] = []; // format duration and distance into friendly time foreach ($outlets as $outlet) { // duration $seconds = $outlet['duration']; if (!empty($seconds) && $seconds > 0) { $hours = floor($seconds / 3600); $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" : '') : ''); } else { $outlet['duration'] = false; } // distance $meters = $outlet['distance']; if (!empty($meters) && $meters > 0) { $outlet['distance'] = round($meters / 1000) . " km"; } else { $outlet['distance'] = false; } $params['outlets'][] = $outlet; } $params['obj'] = $obj; $params['submit_url'] = $this->generateUrl('jo_assign_submit', ['id' => $obj->getID()]); $params['return_url'] = $this->generateUrl('jo_assign'); // response return $this->render('job-order/form.html.twig', $params); } public function assigningSubmit(Request $req, ValidatorInterface $validator, $id) { $this->denyAccessUnlessGranted('jo_assign.list', null, 'No access.'); // initialize error list $error_array = []; // get object data $em = $this->getDoctrine()->getManager(); $obj = $em->getRepository(JobOrder::class)->find($id); // make sure this object exists if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); // check if lat and lng are provided if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; } // check if rider is set if (empty($req->request->get('rider'))) { $error_array['rider'] = 'No rider selected.'; } else { // get rider $rider = $em->getRepository(Rider::class)->find($req->request->get('rider')); if (empty($rider)) { $error_array['rider'] = 'Invalid rider specified.'; } } if (empty($error_array)) { // coordinates $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); // set and save values $obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) ->setCoordinates($point) ->setAdvanceOrder($req->request->get('flag_advance') ?? false) ->setServiceType($req->request->get('service_type')) ->setWarrantyClass($req->request->get('warranty_class')) ->setSource('web') ->setStatus(JOStatus::ASSIGNED) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setAgentNotes($req->request->get('agent_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) ->setAssignedBy($this->getUser()) ->setDateAssign(new DateTime()) ->setRider($rider); // validate $errors = $validator->validate($obj); // add errors to list foreach ($errors as $error) { $error_array[$error->getPropertyPath()] = $error->getMessage(); } } // check if any errors were found if (!empty($error_array)) { // return validation failure response return $this->json([ 'success' => false, 'errors' => $error_array ], 422); } // validated! save the entity $em->flush(); // return successful response return $this->json([ 'success' => 'Changes have been saved!' ]); } // 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 protected function setQueryFilters($datatable, &$query, $qb, $status) { $query->where('q.status = :status') ->setParameter('status', $status); // get only pending rows /* $query->where($qb->expr()->orX( $qb->expr()where('q.status', 'pending'); )); // apply filters if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) { $query->where('q.delivery_address LIKE :filter') ->orWhere($qb->expr()->concat('c.first_name', $qb->expr()->literal(' '), 'c.last_name') . ' LIKE :filter') ->orWhere('cv.plate_number LIKE :filter') ->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%'); } */ } public function generateInvoice(Request $req, InvoiceCreator $ic) { // create new invoice object $invoice = new InvoiceCriteria(); //$invoice-> } }