denyAccessUnlessGranted('ticket.list', null, 'No access.'); return $this->render('ticket/list.html.twig'); } public function rows(Request $req) { $this->denyAccessUnlessGranted('ticket.list', null, 'No access.'); // get query builder $qb = $this->getDoctrine() ->getRepository(Ticket::class) ->createQueryBuilder('q'); // get datatable params $datatable = $req->request->get('datatable'); // count total records $tquery = $qb->select('COUNT(q)'); // add filters to count query $this->setQueryFilters($datatable, $tquery, $qb); $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'); // add filters to query $this->setQueryFilters($datatable, $query, $qb); // 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.id', 'asc'); } // get rows for this page $obj_rows = $query->setFirstResult($offset) ->setMaxResults($perpage) ->getQuery() ->getResult(); // process rows $rows = []; foreach ($obj_rows as $orow) { // add row data $row['id'] = $orow->getID(); $row['date_create'] = $orow->getDateCreate()->format("d M Y g:i A"); $row['first_name'] = $orow->getFirstName(); $row['last_name'] = $orow->getLastName(); $row['contact_num'] = $orow->getContactNumber(); $row['status'] = TicketStatus::getName($orow->getStatus()); $row['ticket_type'] = $orow->getTicketTypeText(); $row['plate_number'] = $orow->getPlateNumber(); // add row metadata $row['meta'] = [ 'update_url' => '', 'delete_url' => '' ]; // add crud urls if ($this->isGranted('ticket.update')) $row['meta']['update_url'] = $this->generateUrl('ticket_update', ['id' => $row['id']]); if ($this->isGranted('ticket.delete')) $row['meta']['delete_url'] = $this->generateUrl('ticket_delete', ['id' => $row['id']]); $rows[] = $row; } // response return $this->json([ 'meta' => $meta, 'data' => $rows ]); } /** * @Menu(selected="ticket_list") */ public function addForm(Request $req, EntityManagerInterface $em, $customer_id, $job_order_id) { $this->denyAccessUnlessGranted('ticket.add', null, 'No access.'); $params['obj'] = new Ticket(); $params['mode'] = 'create'; $params['customer'] = false; $params['job_order'] = false; $customer = false; // get customer data if ($customer_id) { $customer = $em->getRepository(Customer::class)->find($customer_id); // make sure this row exists if (empty($customer)) throw $this->createNotFoundException('This customer does not exist'); // add to view $params['customer'] = $customer; // get job order data if ($job_order_id) { $job_order = $em->getRepository(JobOrder::class)->find($job_order_id); // make sure this row exists if (empty($job_order)) throw $this->createNotFoundException('This job order does not exist'); // add to view $params['job_order'] = $job_order; } else { $job_order = null; } } // get parent associations $params['ticket_types'] = TicketType::getCollection(); $params['statuses'] = TicketStatus::getCollection(); $params['other_ticket_type'] = TicketType::OTHER; $params['redirect_url'] = $this->generateUrl('ticket_list'); $params['soa_types'] = SourceOfAwareness::getCollection(); $params['sets'] = $this->generateFormSets($em); // set redirect url if ($customer) { $referer = $req->headers->get('referer'); $cust_update_url = $this->generateUrl('customer_update', ['id' => $customer->getID()], UrlGeneratorInterface::ABSOLUTE_URL); if ($referer == $cust_update_url) $params['redirect_url'] = $cust_update_url; if ($job_order) { $job_order_url = $this->generateUrl('jo_proc_form', ['id' => $job_order->getID()], UrlGeneratorInterface::ABSOLUTE_URL); if ($referer == $job_order_url) $params['redirect_url'] = $job_order_url; } } // response return $this->render('ticket/form.html.twig', $params); } public function addSubmit(Request $req, ValidatorInterface $validator, $customer_id, $job_order_id) { $this->denyAccessUnlessGranted('ticket.add', null, 'No access.'); $em = $this->getDoctrine()->getManager(); // get customer data if ($customer_id) { $customer = $em->getRepository(Customer::class)->find($customer_id); // make sure this row exists if (empty($customer)) throw $this->createNotFoundException('This customer does not exist'); // set autopopulated fields $first_name = $customer->getFirstName(); $last_name = $customer->getLastName(); $contact_num = $customer->getPhoneMobile(); // get job order data if ($job_order_id) { $job_order = $em->getRepository(JobOrder::class)->find($job_order_id); // make sure this row exists if (empty($job_order)) throw $this->createNotFoundException('This job order does not exist'); } } else { // get values directly from form $first_name = $req->request->get('first_name'); $last_name = $req->request->get('last_name'); $contact_num = $req->request->get('contact_num'); } // create new row $obj = new Ticket(); // get ticket type //$ticket_type = $req->request->get('ticket_type'); //$other_ticket_type = ''; //if ($ticket_type == TicketType::OTHER) { // $other_ticket_type = $req->request->get('other_ticket_type'); //} // get the "new" ticket type $ttype_id = $req->request->get('new_ticket_type'); $sub_ttype_id = $req->request->get('sub_ticket_type'); // get other description if any $other_desc = $req->request->get('other_desc'); // get source of awareness if any $soa_type = $req->request->get('source_of_awareness'); // get remarks $remarks = $req->request->get('remarks', ''); // set and save values $obj->setFirstName($first_name) ->setLastName($last_name) ->setContactNumber($contact_num) ->setStatus($req->request->get('status')) //->setTicketType($ticket_type) //->setOtherTicketType($other_ticket_type) ->setDetails($req->request->get('details')) ->setPlateNumber($req->request->get('plate_number')) ->setDateCreate(new DateTime()) ->setCreatedBy($this->getUser()) ->setSourceOfAwareness($soa_type) ->setRemarks($remarks) ->setOtherDescription($other_desc); // if assigned to customer, set association if ($customer_id) { $obj->setCustomer($customer); } // if linked to job order, set association if ($job_order_id) { $obj->setJobOrder($job_order); } // initialize error list $error_array = []; // validate $errors = $validator->validate($obj); // custom validation for other ticket type //if ($ticket_type == TicketType::OTHER && empty($other_ticket_type)) { // $error_array['other_ticket_type'] = 'Ticket type not specified.'; //} // get ticket and sub ticket type objects $ttype = $em->getRepository(NewTicketType::class)->find($ttype_id); if (empty($ttype)) $error_array['new_ticket_type'] = 'Ticket type not specified.'; $sub_ttype = $em->getRepository(SubTicketType::class)->find($sub_ttype_id); if (empty($sub_ttype)) $error_array['sub_ticket_type'] = 'Sub ticket type not specified.'; // set the ticket type and sub ticket type for ticket $obj->setNewTicketType($ttype) ->setSubTicketType($sub_ttype); // 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); } else { // validated! save the entity $em->persist($obj); $em->flush(); // return successful response return $this->json([ 'success' => 'Changes have been saved!' ]); } } /** * @Menu(selected="ticket_list") */ public function updateForm(Request $req, $id, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('ticket.update', null, 'No access.'); $params['mode'] = 'update'; // get row data $obj = $em->getRepository(Ticket::class)->find($id); // make sure this row exists if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); $customer = $obj->getCustomer(); $job_order = $obj->getJobOrder(); // get parent associations $params['customer'] = $customer; $params['job_order'] = $job_order; $params['ticket_types'] = TicketType::getCollection(); $params['statuses'] = TicketStatus::getCollection(); $params['other_ticket_type'] = TicketType::OTHER; $params['redirect_url'] = $this->generateUrl('ticket_list'); $params['soa_types'] = SourceOfAwareness::getCollection(); $params['sets'] = $this->generateFormSets($em); // set redirect url if ($customer) { $referer = $req->headers->get('referer'); $cust_update_url = $this->generateUrl('customer_update', ['id' => $customer->getID()], UrlGeneratorInterface::ABSOLUTE_URL); if ($referer == $cust_update_url) $params['redirect_url'] = $cust_update_url; } // optimized get related tickets $rel_tix = []; // one query for each so we use indeces if (!empty($obj->getFirstName()) && !empty($obj->getLastName())) $rel_tix[] = $em->getRepository(Ticket::class)->findBy(['first_name' => $obj->getFirstName(), 'last_name' => $obj->getLastName()]); if (!empty($obj->getContactNumber())) $rel_tix[] = $em->getRepository(Ticket::class)->findBy(['contact_num' => $obj->getContactNumber()]); if (!empty($obj->getPlateNumber())) $rel_tix[] = $em->getRepository(Ticket::class)->findBy(['plate_number' => $obj->getPlateNumber()]); $consolidated_rel_tix = []; foreach ($rel_tix as $rel_tickets) { foreach ($rel_tickets as $rticket) { $rtid = $rticket->getID(); $consolidated_rel_tix[$rtid] = $rticket; } } $params['related_tickets'] = $consolidated_rel_tix; /* // get related tickets $qb = $em->getRepository(Ticket::class) ->createQueryBuilder('q'); $query = $qb->select('q') ->where('(q.first_name = :first_name and q.last_name = :last_name)') ->orWhere('q.contact_num = :contact_num') ->orWhere('q.plate_number = :plate_number') ->setParameter('first_name', $obj->getFirstName()) ->setParameter('last_name', $obj->getLastName()) ->setParameter('contact_num', $obj->getContactNumber()) ->setParameter('plate_number', $obj->getPlateNumber()) ->orderBy('q.date_create', 'desc'); $params['related_tickets'] = $query->getQuery() ->getResult(); */ $params['obj'] = $obj; // response return $this->render('ticket/form.html.twig', $params); } public function updateSubmit(Request $req, ValidatorInterface $validator, $id) { $this->denyAccessUnlessGranted('ticket.update', null, 'No access.'); // get row data $em = $this->getDoctrine()->getManager(); $obj = $em->getRepository(Ticket::class)->find($id); // make sure this row exists if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); // get customer data if (!empty($obj->getCustomer())) { $customer = $obj->getCustomer(); // make sure this row exists if (empty($customer)) throw $this->createNotFoundException('This customer does not exist'); // set autopopulated fields to remain the same $first_name = $obj->getFirstName(); $last_name = $obj->getLastName(); $contact_num = $obj->getContactNumber(); } else { // get values directly from form $first_name = $req->request->get('first_name'); $last_name = $req->request->get('last_name'); $contact_num = $req->request->get('contact_num'); } // get ticket type //$ticket_type = $req->request->get('ticket_type'); //$other_ticket_type = ''; //if ($ticket_type == TicketType::OTHER) { // $other_ticket_type = $req->request->get('other_ticket_type'); //} // get the "new" ticket type $ttype_id = $req->request->get('new_ticket_type'); $sub_ttype_id = $req->request->get('sub_ticket_type'); // get other description if any $other_desc = $req->request->get('other_desc'); // get source of awareness if any $soa_type = $req->request->get('source_of_awareness'); // get remarks $remarks = $req->request->get('remarks', ''); // set and save values $obj->setFirstName($first_name) ->setLastName($last_name) ->setContactNumber($contact_num) ->setStatus($req->request->get('status')) //->setTicketType($ticket_type) //->setOtherTicketType($other_ticket_type) ->setDetails($req->request->get('details')) ->setPlateNumber($req->request->get('plate_number')) ->setSourceOfAwareness($soa_type) ->setRemarks($remarks) ->setOtherDescription($other_desc); // initialize error list $error_array = []; // validate $errors = $validator->validate($obj); // custom validation for other ticket type //if ($ticket_type == TicketType::OTHER && empty($other_ticket_type)) { // $error_array['other_ticket_type'] = 'Ticket type not specified.'; //} // get ticket and sub ticket type objects $ttype = $em->getRepository(NewTicketType::class)->find($ttype_id); if (empty($ttype)) $error_array['new_ticket_type'] = 'Ticket type not specified.'; $sub_ttype = $em->getRepository(SubTicketType::class)->find($sub_ttype_id); if (empty($sub_ttype)) $error_array['sub_ticket_type'] = 'Sub ticket type not specified.'; // set the ticket type and sub ticket type for ticket $obj->setNewTicketType($ttype) ->setSubTicketType($sub_ttype); // 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); } else { // validated! save the entity $em->flush(); // return successful response return $this->json([ 'success' => 'Changes have been saved!' ]); } } public function destroy($id) { $this->denyAccessUnlessGranted('ticket.delete', null, 'No access.'); // get row data $em = $this->getDoctrine()->getManager(); $obj = $em->getRepository(Ticket::class)->find($id); if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); // delete this row $em->remove($obj); $em->flush(); // response $response = new Response(); $response->setStatusCode(Response::HTTP_OK); $response->send(); } protected function generateFormSets(EntityManagerInterface $em) { // get ticket types $ttypes = $em->getRepository(NewTicketType::class)->findBy([], ['name' => 'asc']); $ttypes_set = []; foreach ($ttypes as $ttype) { $ttypes_set[$ttype->getID()] = $ttype->getName(); } // get sub ticket types $sub_ttypes = $em->getRepository(SubTicketType::class)->findBy([], ['name' => 'asc']); $sub_ttypes_set = []; foreach ($sub_ttypes as $sub_ttype) { $sub_ttypes_set[] = [ 'id' => $sub_ttype->getID(), 'name' => $sub_ttype->getName(), 'ticket_type_id' => $sub_ttype->getTicketType()->getID(), ]; } return [ 'new_ticket_types' => $ttypes_set, 'sub_ticket_types' => $sub_ttypes_set, ]; } // check if datatable filter is present and append to query protected function setQueryFilters($datatable, &$query, $qb) { if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) { $query->where('q.status LIKE :filter') ->orWhere('q.ticket_type LIKE :filter') ->orWhere('q.other_ticket_type LIKE :filter') ->orWhere('q.first_name LIKE :filter') ->orWhere('q.last_name LIKE :filter') ->orWhere('q.contact_num LIKE :filter') ->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%'); } } }