From 0b8b462f8f924e7fcfd47c5739feeb0e49576c41 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 30 Jun 2020 06:47:43 +0000 Subject: [PATCH 1/4] Add Notification entity. Modify User and JobOrder entities for notifications. #433 --- src/Entity/JobOrder.php | 13 ++++ src/Entity/Notification.php | 134 ++++++++++++++++++++++++++++++++++++ src/Entity/User.php | 32 +++++++++ 3 files changed, 179 insertions(+) create mode 100644 src/Entity/Notification.php diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 718c70ee..4bfcbcf5 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -346,6 +346,12 @@ class JobOrder */ protected $date_status_change; + // notifications for this job order + /** + * @ORM\OneToMany(targetEntity="Notification", mappedBy="job_order") + */ + protected $jo_notifications; + public function __construct() { $this->date_create = new DateTime(); @@ -368,6 +374,8 @@ class JobOrder $this->meta = []; $this->phone_mobile = ''; + + $this->jo_notifications = new ArrayCollection(); } public function getID() @@ -996,4 +1004,9 @@ class JobOrder return $this->jo_extra; } + public function getNotifications() + { + return $this->jo_notifications; + } + } diff --git a/src/Entity/Notification.php b/src/Entity/Notification.php new file mode 100644 index 00000000..f24f967c --- /dev/null +++ b/src/Entity/Notification.php @@ -0,0 +1,134 @@ +flag_read = false; + $this->date_create = new DateTime(); + } + + public function getID() + { + return $this->id; + } + + public function setDateCreate(DateTime $date_create) + { + $this->date_create = $date_create; + return $this; + } + + public function getDateCreate() + { + return $this->date_create; + } + + public function isNotificationRead() + { + return $this->flag_read; + } + + public function setReadNotification($bool = true) + { + $this->flag_read = $bool; + return $this; + } + + public function setUser(User $user) + { + $this->user = $user; + return $this; + } + + public function getUser() + { + return $this->user; + } + + public function setJobOrder(JobOrder $jo) + { + $this->job_order = $jo; + return $this; + } + + public function getJobOrder() + { + return $this->job_order; + } + + public function setNotificationType($notif_type) + { + $this->notif_type = $notif_type; + return $this; + } + + public function getNotificationType() + { + return $this->notif_type; + } + + public function getNotficationTypeName() + { + return NotificationType::getName($this->notif_type); + } + +} diff --git a/src/Entity/User.php b/src/Entity/User.php index a57afb97..be0d59f2 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -110,6 +110,18 @@ class User extends BaseUser implements Serializable */ protected $partners_created; + // notifications for this user + /** + * @ORM\OneToMany(targetEntity="Notification", mappedBy="user", indexBy="id") + */ + protected $user_notifications; + + // flag to check if user has read notifications + /** + * @ORM\Column(type="boolean") + */ + protected $flag_read_notifications; + public function __construct() { parent::__construct(); @@ -119,6 +131,9 @@ class User extends BaseUser implements Serializable $this->job_orders_assigned = new ArrayCollection(); $this->tickets = new ArrayCollection(); $this->partners_created = new ArrayCollection(); + $this->user_notifications = new ArrayCollection(); + + $this->flag_read_notifications = false; } public function getID() @@ -309,4 +324,21 @@ class User extends BaseUser implements Serializable { return $this->partners_created; } + + public function getNotifications() + { + return $this->user_notifications; + } + + public function isNotificationsRead() + { + return $this->flag_read_notifications; + } + + public function setReadNotifications($bool = true) + { + $this->flag_read_notifications = $bool; + return $this; + } + } -- 2.43.5 From 101565a251f7c3e28d5fd0f9cd1154f8188134c6 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 30 Jun 2020 06:48:39 +0000 Subject: [PATCH 2/4] Add NotificationType. #433 --- src/Ramcar/NotificationType.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Ramcar/NotificationType.php diff --git a/src/Ramcar/NotificationType.php b/src/Ramcar/NotificationType.php new file mode 100644 index 00000000..3591fe90 --- /dev/null +++ b/src/Ramcar/NotificationType.php @@ -0,0 +1,14 @@ + 'Cancelled', + 'rejected' => 'Rejected', + ]; +} -- 2.43.5 From fc6cf1883b5e3a6cada10f25ccaedf336723df65 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 30 Jun 2020 11:04:38 +0000 Subject: [PATCH 3/4] Add notification controller and entity. #433 --- config/acl.yaml | 8 ++ config/menu.yaml | 9 ++ config/routes/notification.yaml | 8 ++ src/Controller/NotificationController.php | 100 ++++++++++++++++++ src/Entity/Notification.php | 13 ++- src/Ramcar/NotificationType.php | 8 +- .../JobOrderHandler/CMBJobOrderHandler.php | 1 + .../RiderAPIHandler/CMBRiderAPIHandler.php | 19 ++++ .../job-order/cmb.form.onestep.html.twig | 4 +- templates/notification/list.html.twig | 77 ++++++++++++++ 10 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 config/routes/notification.yaml create mode 100644 src/Controller/NotificationController.php create mode 100644 templates/notification/list.html.twig diff --git a/config/acl.yaml b/config/acl.yaml index abd73118..e4fcc744 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -429,3 +429,11 @@ access_keys: - id: analytics.forecast label: Forecasting + - id: notifications + label: Notifications + acls: + - id: notification.menu + label: Menu + - id: notification.list + label: List + diff --git a/config/menu.yaml b/config/menu.yaml index 9f28b315..0310fc36 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -177,3 +177,12 @@ main_menu: acl: review.list label: Reviews parent: partner + + - id: notification + acl: notification.menu + label: Notifications + icon: flaticon-bell + - id: notification_list + acl: notification.list + label: Notifications + parent: notification diff --git a/config/routes/notification.yaml b/config/routes/notification.yaml new file mode 100644 index 00000000..b61f6a64 --- /dev/null +++ b/config/routes/notification.yaml @@ -0,0 +1,8 @@ +notification_list: + path: /notifications + controller: App\Controller\NotificationController::index + +notification_rows: + path: /notifications/rows + controller: App\Controller\NotificationController::rows + methods: [POST] diff --git a/src/Controller/NotificationController.php b/src/Controller/NotificationController.php new file mode 100644 index 00000000..4b55916b --- /dev/null +++ b/src/Controller/NotificationController.php @@ -0,0 +1,100 @@ +denyAccessUnlessGranted('notification.list', null, 'No access.'); + + return $this->render('notification/list.html.twig'); + } + + public function rows(Request $req) + { + $this->denyAccessUnlessGranted('notification.list', null, 'No access.'); + + // get current user + $user = $this->getUser(); + + // build query + $qb = $this->getDoctrine() + ->getRepository(Notification::class) + ->createQueryBuilder('q'); + + // get datatable params + $datatable = $req->request->get('datatable'); + + // count total records + $tquery = $qb->select('COUNT(q)'); + + // find by user + $tquery->andWhere('q.user = :user') + ->setParameter('user', $user); + + $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'); + + // find by user + $query->andWhere('q.user = :user') + ->setParameter('user', $user); + + // order by date_create desc + $query->orderBy('q.date_create', 'desc'); + + // 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['message'] = $orow->getMessage(); + $row['notif_type'] = $orow->getNotificationTypeName(); + + $rows[] = $row; + } + + // response + return $this->json([ + 'meta' => $meta, + 'data' => $rows + ]); + } +} diff --git a/src/Entity/Notification.php b/src/Entity/Notification.php index f24f967c..82a5d3a6 100644 --- a/src/Entity/Notification.php +++ b/src/Entity/Notification.php @@ -82,6 +82,17 @@ class Notification return $this->date_create; } + public function setMessage($message) + { + $this->message = $message; + return $this; + } + + public function getMessage() + { + return $this->message; + } + public function isNotificationRead() { return $this->flag_read; @@ -126,7 +137,7 @@ class Notification return $this->notif_type; } - public function getNotficationTypeName() + public function getNotificationTypeName() { return NotificationType::getName($this->notif_type); } diff --git a/src/Ramcar/NotificationType.php b/src/Ramcar/NotificationType.php index 3591fe90..630cda7b 100644 --- a/src/Ramcar/NotificationType.php +++ b/src/Ramcar/NotificationType.php @@ -4,11 +4,11 @@ namespace App\Ramcar; class NotificationType extends NameValue { - const CANCELLED = 'cancelled'; - const REJECTED = 'rejected'; + const CANCELLATION = 'cancellation'; + const REJECTION = 'rejection'; const COLLECTION = [ - 'cancelled' => 'Cancelled', - 'rejected' => 'Rejected', + 'cancellation' => 'Cancellation', + 'rejection' => 'Rejection', ]; } diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index 83188826..bad04db8 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -1500,6 +1500,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // get images if any $jo_extra = $obj->getJOExtra(); $pic_array = []; + $params['signature'] = null; if ($jo_extra != null) { $b_speed_img = $jo_extra->getBeforeSpeedImageFilename(); diff --git a/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php b/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php index d0bbcdb5..72e1d5ac 100644 --- a/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php +++ b/src/Service/RiderAPIHandler/CMBRiderAPIHandler.php @@ -3,6 +3,7 @@ namespace App\Service\RiderAPIHandler; use Doctrine\ORM\EntityManagerInterface; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; @@ -14,6 +15,7 @@ use App\Ramcar\InvoiceStatus; use App\Ramcar\CMBModeOfPayment; use App\Ramcar\InvoiceCriteria; use App\Ramcar\CMBCancelReason; +use App\Ramcar\NotificationType; use App\Service\RiderAPIHandlerInterface; use App\Service\RedisClientProvider; @@ -33,6 +35,7 @@ use App\Entity\BatteryModel; use App\Entity\BatterySize; use App\Entity\JobOrder; use App\Entity\JOExtra; +use App\Entity\Notification; use DateTime; use DateInterval; @@ -886,6 +889,14 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ->setRider($rider); $this->em->persist($event); + // add to notifications + $notif = new Notification(); + $notif->setJobOrder($jo) + ->setMessage($rider->getFullName() . ' cancelled Job Order# ' . $jo->getID()) + ->setNotificationType(NotificationType::CANCELLATION) + ->setUser($jo->getCreatedBy()); + $this->em->persist($notif); + $this->em->flush(); return $data; @@ -945,6 +956,14 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface ->setRider($rider); $this->em->persist($event); + // add to notifications + $notif = new Notification(); + $notif->setJobOrder($jo) + ->setMessage($rider->getFullName() . ' rejected Job Order# ' . $jo->getID()) + ->setNotificationType(NotificationType::REJECTION) + ->setUser($jo->getCreatedBy()); + $this->em->persist($notif); + $this->em->flush(); // send mqtt event diff --git a/templates/job-order/cmb.form.onestep.html.twig b/templates/job-order/cmb.form.onestep.html.twig index 3fb94720..a133e728 100644 --- a/templates/job-order/cmb.form.onestep.html.twig +++ b/templates/job-order/cmb.form.onestep.html.twig @@ -511,7 +511,9 @@
-
+ {% if signature %} +
+ {% endif %}
diff --git a/templates/notification/list.html.twig b/templates/notification/list.html.twig new file mode 100644 index 00000000..6c4d8455 --- /dev/null +++ b/templates/notification/list.html.twig @@ -0,0 +1,77 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+

+ Notifications +

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} -- 2.43.5 From 3a57c484a2ede160855a6ee48248a551df6b9411 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 10 Jul 2020 09:54:47 +0000 Subject: [PATCH 4/4] Mark notifications as read when user views the JO. User is redirected to the JO when clicking the View JO action. #433 --- config/routes/notification.yaml | 6 ++++ src/Controller/NotificationController.php | 29 ++++++++++++++++ templates/notification/list.html.twig | 41 +++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/config/routes/notification.yaml b/config/routes/notification.yaml index b61f6a64..86023d64 100644 --- a/config/routes/notification.yaml +++ b/config/routes/notification.yaml @@ -6,3 +6,9 @@ notification_rows: path: /notifications/rows controller: App\Controller\NotificationController::rows methods: [POST] + +# ajax call +notification_ajax_read: + path: /notifications/read + controller: App\Controller\NotificationController::markNotificationRead + methods: [POST] diff --git a/src/Controller/NotificationController.php b/src/Controller/NotificationController.php index 4b55916b..75ea2812 100644 --- a/src/Controller/NotificationController.php +++ b/src/Controller/NotificationController.php @@ -5,6 +5,8 @@ namespace App\Controller; use App\Entity\Notification; use Doctrine\ORM\Query; +use Doctrine\ORM\EntityManagerInterface; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -87,6 +89,11 @@ class NotificationController extends Controller $row['id'] = $orow->getID(); $row['message'] = $orow->getMessage(); $row['notif_type'] = $orow->getNotificationTypeName(); + $row['jo_id'] = $orow->getJobOrder()->getID(); + $row['flag_read'] = $orow->isNotificationRead(); + + // add row metadata + $row['meta']['view_jo_url'] = $this->generateUrl('jo_walkin_edit_form', ['id' => $row['jo_id']]); $rows[] = $row; } @@ -97,4 +104,26 @@ class NotificationController extends Controller 'data' => $rows ]); } + + public function markNotificationRead(EntityManagerInterface $em, Request $req) + { + $id = $req->request->get('id'); + + $notif = $em->getRepository(Notification::class)->find($id); + // make sure this notification exists + if (empty($notif)) { + return $this->json([ + 'success' => false, + 'errors' => 'No notification found.', + ], 422); + } + + $notif->setReadNotification(); + + $em->flush(); + + return $this->json([ + 'success' => 'Changes have been saved!' + ]); + } } diff --git a/templates/notification/list.html.twig b/templates/notification/list.html.twig index 6c4d8455..4840ec43 100644 --- a/templates/notification/list.html.twig +++ b/templates/notification/list.html.twig @@ -54,6 +54,17 @@ serverFiltering: true, serverSorting: true }, + rows: { + beforeTemplate: function(row, data, index) { + console.log(data.flag_read); + if (data.flag_read) { + $(row).addClass('m-table__row--primary'); + } + else { + $(row).addClass('m-table__row--danger'); + } + } + }, columns: [ { field: 'id', @@ -68,10 +79,40 @@ field: 'notif_type', title: 'Notification Type' }, + { + field: 'Actions', + width: 110, + title: 'Actions', + sortable: false, + overflow: 'visible', + template: function (row, index, datatable) { + var actions = ''; + + if (row.meta.view_jo_url != '') { + actions += ''; + } + return actions; + }, + } ] }; var table = $("#data-rows").mDatatable(options); + + $(document).on('click', '.btn-edit', function(e) { + var url = $(this).prop('href'); + var id = $(this).data('id'); + console.log(id); + $.ajax({ + method: 'POST', + url: "{{ url('notification_ajax_read') }}", + data: { id: id } + }).done(function(response) { + console.log(response); + }).error(function(err) { + console.log(err); + }); + }); }); {% endblock %} -- 2.43.5