From 180a2d4bf95a5debd5a8a49704f4e965ee94a58a Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Sat, 13 Jan 2018 00:28:12 +0800 Subject: [PATCH] Add initial outlet screens and other menu and acl entries --- config/acl.yaml | 47 ++++ config/menu.yaml | 26 +- config/routes/outlet.yaml | 36 +++ src/Controller/OutletController.php | 353 ++++++++++++++++++++++++++++ src/Entity/JobOrder.php | 4 +- src/Entity/Outlet.php | 35 +++ templates/outlet/form.html.twig | 219 +++++++++++++++++ templates/outlet/list.html.twig | 180 ++++++++++++++ 8 files changed, 893 insertions(+), 7 deletions(-) create mode 100644 config/routes/outlet.yaml create mode 100644 src/Controller/OutletController.php create mode 100644 templates/outlet/form.html.twig create mode 100644 templates/outlet/list.html.twig diff --git a/config/acl.yaml b/config/acl.yaml index 19543bfb..a76ab42e 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -128,3 +128,50 @@ access_keys: label: Update - id: customer.delete label: Delete + + + - id: location + label: Location Access + acls: + - id: location.menu + label: Menu + - id: outlet + label: Outlet Access + acls: + - id: outlet.menu + label: Menu + - id: outlet.list + label: List + - id: outlet.add + label: Add + - id: outlet.update + label: Update + - id: outlet.delete + label: Delete + - id: hub + label: Hub Access + acls: + - id: hub.menu + label: Menu + - id: hub.list + label: List + - id: hub.add + label: Add + - id: hub.update + label: Update + - id: hub.delete + label: Delete + + - id: rider + label: Rider Access + acls: + - id: rider.menu + label: Menu + - id: rider.list + label: List + - id: rider.add + label: Add + - id: rider.update + label: Update + - id: rider.delete + label: Delete diff --git a/config/menu.yaml b/config/menu.yaml index e1ebd03c..e62574ed 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -19,7 +19,15 @@ main_menu: - id: database acl: database.menu label: Database - icon: flaticon-tabs + icon: fa fa-database + - id: customer_list + acl: customer.list + label: Customers + parent: database + - id: rider_list + acl: rider.list + label: Riders + parent: database - id: battery acl: battery.menu @@ -55,7 +63,15 @@ main_menu: label: Manufacturers parent: vehicle - - id: customer_list - acl: customer.list - label: Customers - parent: database + - id: location + acl: location.menu + label: Location + icon: fa fa-home + - id: outlet_list + acl: outlet.menu + label: Outlet + parent: location + - id: hub_list + acl: hub.menu + label: Hub + parent: location diff --git a/config/routes/outlet.yaml b/config/routes/outlet.yaml new file mode 100644 index 00000000..72125245 --- /dev/null +++ b/config/routes/outlet.yaml @@ -0,0 +1,36 @@ +# outlet + +outlet_list: + path: /outlets + controller: App\Controller\OutletController::index + +outlet_rows: + path: /outlets/rows + controller: App\Controller\OutletController::rows + methods: [POST] + +outlet_create: + path: /outlets/create + controller: App\Controller\OutletController::create + methods: [GET] + +outlet_create_submit: + path: /outlets/create + controller: App\Controller\OutletController::createSubmit + methods: [POST] + +outlet_update: + path: /outlets/{id} + controller: App\Controller\OutletController::update + methods: [GET] + +outlet_update_submit: + path: /outlets/{id} + controller: App\Controller\OutletController::updateSubmit + methods: [POST] + +outlet_delete: + path: /outlets/{id} + controller: App\Controller\OutletController::destroy + methods: [DELETE] + diff --git a/src/Controller/OutletController.php b/src/Controller/OutletController.php new file mode 100644 index 00000000..0e95dd7e --- /dev/null +++ b/src/Controller/OutletController.php @@ -0,0 +1,353 @@ +denyAccessUnlessGranted('outlet.list', null, 'No access.'); + + $params = $this->initParameters('outlet_list'); + + return $this->render('outlet/list.html.twig', $params); + } + + public function rows(Request $req) + { + $this->denyAccessUnlessGranted('outlet.list', null, 'No access.'); + + // get query builder + $qb = $this->getDoctrine() + ->getRepository(Outlet::class) + ->createQueryBuilder('q'); + + // count total records + $total = $qb->select('COUNT(q)') + ->getQuery() + ->getSingleScalarResult(); + + // get datatable params + $datatable = $req->request->get('datatable'); + + // 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'); + + // check if filter is present + if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) { + $query->where('q.outletname LIKE :filter') + ->orWhere('q.first_name LIKE :filter') + ->orWhere('q.last_name LIKE :filter') + ->orWhere('q.email LIKE :filter') + ->orWhere('q.contact_num LIKE :filter') + ->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%'); + } + + // 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(); + // Query::HYDRATE_ARRAY); + + // process rows + $rows = []; + foreach ($obj_rows as $orow) { + // add row data + $row['id'] = $orow->getID(); + $row['outletname'] = $orow->getOutletname(); + $row['first_name'] = $orow->getFirstName(); + $row['last_name'] = $orow->getLastName(); + $row['email'] = $orow->getEmail(); + $row['contact_num'] = $orow->getContactNumber(); + $row['enabled'] = $orow->isEnabled(); + + + // add row metadata + $row['meta'] = [ + 'update_url' => '', + 'delete_url' => '' + ]; + + // check if they have access to super admin outlets + if (!$this->isGranted('outlet.role.sadmin') && $orow->isSuperAdmin()) + { + $rows[] = $row; + continue; + } + + // add crud urls + if ($this->isGranted('outlet.update')) + $row['meta']['update_url'] = $this->generateUrl('outlet_update', ['id' => $row['id']]); + if ($this->isGranted('outlet.delete')) + $row['meta']['delete_url'] = $this->generateUrl('outlet_delete', ['id' => $row['id']]); + + $rows[] = $row; + } + + // response + return $this->json([ + 'meta' => $meta, + 'data' => $rows + ]); + } + + public function create() + { + $this->denyAccessUnlessGranted('outlet.add', null, 'No access.'); + + $params = $this->initParameters('outlet_list'); + + // get roles + $em = $this->getDoctrine()->getManager(); + $params['roles'] = $em->getRepository(Role::class)->findAll(); + + // response + return $this->render('outlet/form.html.twig', $params); + } + + public function createSubmit(Request $req, EncoderFactoryInterface $ef, ValidatorInterface $validator) + { + $this->denyAccessUnlessGranted('outlet.add', null, 'No access.'); + + // create new row + $em = $this->getDoctrine()->getManager(); + $row = new Outlet(); + + // set and save values + $row->setOutletname($req->request->get('outletname')) + ->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email')) + ->setContactNumber($req->request->get('contact_no')) + ->setEnabled($req->request->get('enabled') ? true : false) + ->clearRoles(); + + // set roles + $roles = $req->request->get('roles'); + + if (!empty($roles)) { + foreach ($roles as $role_id) { + // check if role exists + $role = $em->getRepository(Role::class)->find($role_id); + if (!empty($role)) + { + // check access to super outlet roles + if ($role->isSuperAdmin() && !$this->isGranted('outlet.role.sadmin')) + continue; + + $row->addRole($role); + } + } + } + + // validate + $errors = $validator->validate($row); + + // initialize error list + $error_array = []; + + // add errors to list + foreach ($errors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } + + // get password inputs + $password = $req->request->get('password'); + $confirm_password = $req->request->get('confirm_password'); + + // custom validation for password fields + if (!$password) { + $error_array['password'] = 'This value should not be blank.'; + } else if ($password != $confirm_password) { + $error_array['confirm_password'] = 'Passwords do not match.'; + } else { + // encode password + $enc = $ef->getEncoder($row); + $encoded_password = $enc->encodePassword($req->request->get('password'), $row->getSalt()); + + // set password + $row->setPassword($encoded_password); + } + + // 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 update($id) + { + $this->denyAccessUnlessGranted('outlet.update', null, 'No access.'); + + $params = $this->initParameters('outlet_list'); + + // get row data + $em = $this->getDoctrine()->getManager(); + $row = $em->getRepository(Outlet::class)->find($id); + + // make sure this row exists + if (empty($row)) + throw $this->createNotFoundException('The item does not exist'); + + // get roles + $em = $this->getDoctrine()->getManager(); + $params['roles'] = $em->getRepository(Role::class)->findAll(); + + $params['row'] = $row; + $params['values'] = []; + + // response + return $this->render('outlet/form.html.twig', $params); + } + + public function updateSubmit(Request $req, EncoderFactoryInterface $ef, ValidatorInterface $validator, $id) + { + $this->denyAccessUnlessGranted('outlet.update', null, 'No access.'); + + // get row data + $em = $this->getDoctrine()->getManager(); + $row = $em->getRepository(Outlet::class)->find($id); + + // make sure this row exists + if (empty($row)) + throw $this->createNotFoundException('The item does not exist'); + + // set and save values + $row->setOutletname($req->request->get('outletname')) + ->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email')) + ->setContactNumber($req->request->get('contact_no')) + ->setEnabled($req->request->get('enabled') ? true : false) + ->clearRoles(); + + // set roles + $roles = $req->request->get('roles'); + + if (!empty($roles)) { + foreach ($roles as $role_id) { + // check if role exists + $role = $em->getRepository(Role::class)->find($role_id); + + if (!empty($role)) + $row->addRole($role); + } + } + + // validate + $errors = $validator->validate($row); + + // initialize error list + $error_array = []; + + // add errors to list + foreach ($errors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } + + // get password inputs + $password = $req->request->get('password'); + $confirm_password = $req->request->get('confirm_password'); + + // custom validation for password fields + if ($password || $confirm_password) { + if ($password != $confirm_password) { + $error_array['confirm_password'] = 'Passwords do not match.'; + } else { + // encode password + $enc = $ef->getEncoder($row); + $encoded_password = $enc->encodePassword($req->request->get('password'), $row->getSalt()); + + // set password + $row->setPassword($encoded_password); + } + } + + // 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('outlet.delete', null, 'No access.'); + + $params = $this->initParameters('outlet_list'); + + // get row data + $em = $this->getDoctrine()->getManager(); + $row = $em->getRepository(Outlet::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(); + } +} diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 22193d2a..43204acf 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -8,9 +8,9 @@ use Symfony\Component\Validator\Constraints as Assert; /** * @ORM\Entity - * @ORM\Table(name="hub") + * @ORM\Table(name="job_order") */ -class Hub +class JobOrder { // unique id /** diff --git a/src/Entity/Outlet.php b/src/Entity/Outlet.php index 37d885d1..c21b23a4 100644 --- a/src/Entity/Outlet.php +++ b/src/Entity/Outlet.php @@ -20,6 +20,41 @@ class Outlet */ protected $id; + // name of enrollee + /** + * @ORM\Column(type="string", length=80) + */ + protected $name; + // address + /** + * @ORM\Column(type="string", length=80) + */ + protected $address; + + // address coordinates + /** + * @ORM\Column(type="point") + */ + protected $coordinates; + + // contact numbers + // this is displayed in a textarea + /** + * @ORM\Column(type="string", length=200) + */ + protected $contact_numbers; + + // opening time + /** + * @ORM\Column(type="time") + */ + protected $time_open; + + // closing time + /** + * @ORM\Column(type="time") + */ + protected $time_close; } diff --git a/templates/outlet/form.html.twig b/templates/outlet/form.html.twig new file mode 100644 index 00000000..759f4137 --- /dev/null +++ b/templates/outlet/form.html.twig @@ -0,0 +1,219 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+

Users

+
+
+
+ +
+ +
+
+
+
+
+
+ + + +

+ {% if row is defined %} + Edit User + {{ row.getUsername() }} + {% else %} + New User + {% endif %} +

+
+
+
+
+ +
+
+ +
+ + + Unique alias for this user +
+
+
+ +
+ + + {% if row is defined %} + Leave both fields blank for unchanged + {% endif %} +
+ +
+ + +
+
+
+ +
+ + +
+ +
+ + +
+
+
+ +
+ + +
+ +
+ + +
+
+
+ +
+
+ {% for role in roles %} + {% if role.isSuperAdmin and not is_granted('user.role.sadmin') %} + {% else %} + + {% endif %} + {% endfor %} +
+ + Check all roles that apply +
+
+
+ +
+ + + + +
+
+
+
+
+
+
+ + Cancel +
+
+
+
+
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/templates/outlet/list.html.twig b/templates/outlet/list.html.twig new file mode 100644 index 00000000..15dc7950 --- /dev/null +++ b/templates/outlet/list.html.twig @@ -0,0 +1,180 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+

+ Outlets +

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