denyAccessUnlessGranted('vehicle.list', null, 'No access.'); $params = $this->initParameters('vehicle_list'); // response return $this->render('vehicle/list.html.twig', $params); } public function rows(Request $req) { $this->denyAccessUnlessGranted('vehicle.list', null, 'No access.'); // build query $qb = $this->getDoctrine() ->getRepository(Vehicle::class) ->createQueryBuilder('q'); // get datatable params $datatable = $req->request->get('datatable'); // count total records $tquery = $qb->select('COUNT(q)') ->join('q.manufacturer', 'mfg'); // add filters to count query $this->setQueryFilters($datatable, $tquery); $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') ->addSelect('mfg.name as mfg_name'); // add filters to query $this->setQueryFilters($datatable, $query); // check if sorting is present, otherwise use default if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) { $prefix = ''; if (!in_array($datatable['sort']['field'], ['mfg_name'])) $prefix = 'q.'; $order = $datatable['sort']['sort'] ?? 'asc'; $query->orderBy($prefix . $datatable['sort']['field'], $order); } else { $query->orderBy('mfg_name', '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[0]->getID(); $row['mfg_name'] = $orow['mfg_name']; $row['make'] = $orow[0]->getMake(); $row['model_year_from'] = $orow[0]->getModelYearFrom(); $row['model_year_to'] = $orow[0]->getModelYearTo(); $row['model_year_formatted'] = $orow[0]->getModelYearFormatted(); // add row metadata $row['meta'] = [ 'update_url' => '', 'delete_url' => '' ]; // add crud urls if ($this->isGranted('user.update')) $row['meta']['update_url'] = $this->generateUrl('vehicle_update', ['id' => $row['id']]); if ($this->isGranted('user.delete')) $row['meta']['delete_url'] = $this->generateUrl('vehicle_delete', ['id' => $row['id']]); $rows[] = $row; } // response return $this->json([ 'meta' => $meta, 'data' => $rows ]); } public function addForm() { $this->denyAccessUnlessGranted('vehicle.add', null, 'No access.'); $params = $this->initParameters('vehicle_list'); $params['obj'] = new Vehicle(); $params['mode'] = 'create'; $em = $this->getDoctrine()->getManager(); // get parent associations $params['manufacturers'] = $em->getRepository(VehicleManufacturer::class)->findAll(); $params['years'] = $this->generateYearOptions(); // response return $this->render('vehicle/form.html.twig', $params); } public function addSubmit(Request $req, ValidatorInterface $validator) { $this->denyAccessUnlessGranted('vehicle.add', null, 'No access.'); // create new row $em = $this->getDoctrine()->getManager(); $row = new Vehicle(); // set and save values $row->setMake($req->request->get('make')) ->setModelYearFrom($req->request->get('model_year_from')) ->setModelYearTo($req->request->get('model_year_to')); $flag_mobile = $req->request->get('flag_mobile'); if ($flag_mobile) $row->setDisplayMobile(true); else $row->setDisplayMobile(false); // initialize error list $error_array = []; // custom validation for associations $manufacturer = $em->getRepository(VehicleManufacturer::class) ->find($req->request->get('manufacturer')); if (empty($manufacturer)) $error_array['manufacturer'] = 'Invalid manufacturer selected.'; else $row->setManufacturer($manufacturer); // validate $errors = $validator->validate($row); // 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($row); $em->flush(); // return successful response return $this->json([ 'success' => 'Changes have been saved!' ]); } } public function updateForm($id) { $this->denyAccessUnlessGranted('vehicle.update', null, 'No access.'); $params = $this->initParameters('vehicle_list'); $params['mode'] = 'update'; // get row data $em = $this->getDoctrine()->getManager(); $row = $em->getRepository(Vehicle::class)->find($id); // make sure this row exists if (empty($row)) throw $this->createNotFoundException('The item does not exist'); // get parent associations $params['manufacturers'] = $em->getRepository(VehicleManufacturer::class)->findAll(); $params['years'] = $this->generateYearOptions(); $params['obj'] = $row; // response return $this->render('vehicle/form.html.twig', $params); } public function updateSubmit(Request $req, ValidatorInterface $validator, $id) { $this->denyAccessUnlessGranted('vehicle.update', null, 'No access.'); // get row data $em = $this->getDoctrine()->getManager(); $row = $em->getRepository(Vehicle::class)->find($id); // make sure this row exists if (empty($row)) throw $this->createNotFoundException('The item does not exist'); // set and save values $row->setMake($req->request->get('make')) ->setModelYearFrom($req->request->get('model_year_from')) ->setModelYearTo($req->request->get('model_year_to')); $flag_mobile = $req->request->get('flag_mobile'); if ($flag_mobile) $row->setDisplayMobile(true); else $row->setDisplayMobile(false); // validate $errors = $validator->validate($row); // initialize error list $error_array = []; // add errors to list foreach ($errors as $error) { $error_array[$error->getPropertyPath()] = $error->getMessage(); } // custom validation for associations $manufacturer = $em->getRepository(VehicleManufacturer::class) ->find($req->request->get('manufacturer')); if (empty($manufacturer)) $error_array['manufacturer'] = 'Invalid manufacturer selected.'; else $row->setManufacturer($manufacturer); // 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('vehicle.delete', null, 'No access.'); $params = $this->initParameters('vehicle_list'); // get row data $em = $this->getDoctrine()->getManager(); $row = $em->getRepository(Vehicle::class)->find($id); if (empty($row)) throw $this->createNotFoundException('The item does not exist'); // delete this row $em->remove($row); $em->flush(); // response $response = new Response(); $response->setStatusCode(Response::HTTP_OK); $response->send(); } protected function generateYearOptions() { $start_year = 1950; return range($start_year, date("Y") + 1); } // check if datatable filter is present and append to query protected function setQueryFilters($datatable, &$query) { if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) { $query->where('mfg.name LIKE :filter') ->orWhere('q.make LIKE :filter') ->orWhere('q.model_year_from LIKE :filter') ->orWhere('q.model_year_to LIKE :filter') ->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%'); } } public function getBatteries(Request $req) { /* if (!$this->isGranted('customer.add') && !$this->isGranted('customer.update')) { $exception = $this->createAccessDeniedException('No access.'); throw $exception; } */ // get row data $em = $this->getDoctrine()->getManager(); $vobj = $em->getRepository(Vehicle::class)->find($req->request->get('vehicle_id')); $all_batts = $em->getRepository(Battery::class)->findAll(); if (empty($vobj)) throw $this->createNotFoundException('The item does not exist'); // build batteries array $batteries = []; $battery_index = []; // get compatible batteries from selected manufacturer foreach ($vobj->getBatteries() as $battery) { $batteries[] = [ 'id' => $battery->getID(), 'mfg_name' => $battery->getManufacturer()->getName(), 'model_name' => $battery->getModel()->getName(), 'size_name' => $battery->getSize()->getName(), 'prod_code' => $battery->getProductCode(), 'sell_price' => $battery->getSellingPrice(), 'warr_private' => $battery->getWarrantyPrivate(), 'warr_commercial' => $battery->getWarrantyCommercial(), ]; $battery_index[$battery->getID()] = 1; } // add all other batteries, because they want options foreach ($all_batts as $battery) { // if we already listed it if (isset($battery_index[$battery->getID()])) continue; $batteries[] = [ 'id' => $battery->getID(), 'mfg_name' => $battery->getManufacturer()->getName(), 'model_name' => $battery->getModel()->getName(), 'size_name' => $battery->getSize()->getName(), 'prod_code' => $battery->getProductCode(), 'sell_price' => $battery->getSellingPrice(), 'warr_private' => $battery->getWarrantyPrivate(), 'warr_commercial' => $battery->getWarrantyCommercial(), ]; } /* // NOTE: no need to order by price for control center / only for app // order by price usort($batteries, function ($a, $b) { return -($a['sell_price'] <=> $b['sell_price']); }); */ // response return $this->json([ 'data' => $batteries ]); } }