Add notification controller and entity. #433
This commit is contained in:
parent
101565a251
commit
fc6cf1883b
10 changed files with 241 additions and 6 deletions
|
|
@ -429,3 +429,11 @@ access_keys:
|
||||||
- id: analytics.forecast
|
- id: analytics.forecast
|
||||||
label: Forecasting
|
label: Forecasting
|
||||||
|
|
||||||
|
- id: notifications
|
||||||
|
label: Notifications
|
||||||
|
acls:
|
||||||
|
- id: notification.menu
|
||||||
|
label: Menu
|
||||||
|
- id: notification.list
|
||||||
|
label: List
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,3 +177,12 @@ main_menu:
|
||||||
acl: review.list
|
acl: review.list
|
||||||
label: Reviews
|
label: Reviews
|
||||||
parent: partner
|
parent: partner
|
||||||
|
|
||||||
|
- id: notification
|
||||||
|
acl: notification.menu
|
||||||
|
label: Notifications
|
||||||
|
icon: flaticon-bell
|
||||||
|
- id: notification_list
|
||||||
|
acl: notification.list
|
||||||
|
label: Notifications
|
||||||
|
parent: notification
|
||||||
|
|
|
||||||
8
config/routes/notification.yaml
Normal file
8
config/routes/notification.yaml
Normal file
|
|
@ -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]
|
||||||
100
src/Controller/NotificationController.php
Normal file
100
src/Controller/NotificationController.php
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\Notification;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
|
||||||
|
use Catalyst\MenuBundle\Annotation\Menu;
|
||||||
|
|
||||||
|
class NotificationController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Menu(selected="notification_list")
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->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
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -82,6 +82,17 @@ class Notification
|
||||||
return $this->date_create;
|
return $this->date_create;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setMessage($message)
|
||||||
|
{
|
||||||
|
$this->message = $message;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessage()
|
||||||
|
{
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
public function isNotificationRead()
|
public function isNotificationRead()
|
||||||
{
|
{
|
||||||
return $this->flag_read;
|
return $this->flag_read;
|
||||||
|
|
@ -126,7 +137,7 @@ class Notification
|
||||||
return $this->notif_type;
|
return $this->notif_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNotficationTypeName()
|
public function getNotificationTypeName()
|
||||||
{
|
{
|
||||||
return NotificationType::getName($this->notif_type);
|
return NotificationType::getName($this->notif_type);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ namespace App\Ramcar;
|
||||||
|
|
||||||
class NotificationType extends NameValue
|
class NotificationType extends NameValue
|
||||||
{
|
{
|
||||||
const CANCELLED = 'cancelled';
|
const CANCELLATION = 'cancellation';
|
||||||
const REJECTED = 'rejected';
|
const REJECTION = 'rejection';
|
||||||
|
|
||||||
const COLLECTION = [
|
const COLLECTION = [
|
||||||
'cancelled' => 'Cancelled',
|
'cancellation' => 'Cancellation',
|
||||||
'rejected' => 'Rejected',
|
'rejection' => 'Rejection',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1500,6 +1500,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
// get images if any
|
// get images if any
|
||||||
$jo_extra = $obj->getJOExtra();
|
$jo_extra = $obj->getJOExtra();
|
||||||
$pic_array = [];
|
$pic_array = [];
|
||||||
|
$params['signature'] = null;
|
||||||
if ($jo_extra != null)
|
if ($jo_extra != null)
|
||||||
{
|
{
|
||||||
$b_speed_img = $jo_extra->getBeforeSpeedImageFilename();
|
$b_speed_img = $jo_extra->getBeforeSpeedImageFilename();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Service\RiderAPIHandler;
|
namespace App\Service\RiderAPIHandler;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
||||||
|
|
||||||
|
|
@ -14,6 +15,7 @@ use App\Ramcar\InvoiceStatus;
|
||||||
use App\Ramcar\CMBModeOfPayment;
|
use App\Ramcar\CMBModeOfPayment;
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
use App\Ramcar\CMBCancelReason;
|
use App\Ramcar\CMBCancelReason;
|
||||||
|
use App\Ramcar\NotificationType;
|
||||||
|
|
||||||
use App\Service\RiderAPIHandlerInterface;
|
use App\Service\RiderAPIHandlerInterface;
|
||||||
use App\Service\RedisClientProvider;
|
use App\Service\RedisClientProvider;
|
||||||
|
|
@ -33,6 +35,7 @@ use App\Entity\BatteryModel;
|
||||||
use App\Entity\BatterySize;
|
use App\Entity\BatterySize;
|
||||||
use App\Entity\JobOrder;
|
use App\Entity\JobOrder;
|
||||||
use App\Entity\JOExtra;
|
use App\Entity\JOExtra;
|
||||||
|
use App\Entity\Notification;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateInterval;
|
use DateInterval;
|
||||||
|
|
@ -886,6 +889,14 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
->setRider($rider);
|
->setRider($rider);
|
||||||
$this->em->persist($event);
|
$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();
|
$this->em->flush();
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|
@ -945,6 +956,14 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
->setRider($rider);
|
->setRider($rider);
|
||||||
$this->em->persist($event);
|
$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();
|
$this->em->flush();
|
||||||
|
|
||||||
// send mqtt event
|
// send mqtt event
|
||||||
|
|
|
||||||
|
|
@ -511,7 +511,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-3">
|
||||||
<label> Customer Signature </label>
|
<label> Customer Signature </label>
|
||||||
|
{% if signature %}
|
||||||
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ signature }}');" ></div>
|
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ signature }}');" ></div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group m-form__group row">
|
<div class="form-group m-form__group row">
|
||||||
|
|
|
||||||
77
templates/notification/list.html.twig
Normal file
77
templates/notification/list.html.twig
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<!-- BEGIN: Subheader -->
|
||||||
|
<div class="m-subheader">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="mr-auto">
|
||||||
|
<h3 class="m-subheader__title">
|
||||||
|
Notifications
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END: Subheader -->
|
||||||
|
<div class="m-content">
|
||||||
|
<!--Begin::Section-->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
<div class="m-portlet m-portlet--mobile">
|
||||||
|
<div class="m-portlet__body">
|
||||||
|
<div class="m-form m-form--label-align-right m--margin-top-20 m--margin-bottom-30">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="m-separator m-separator--dashed d-xl-none"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--begin: Datatable -->
|
||||||
|
<div id="data-rows"></div>
|
||||||
|
<!--end: Datatable -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
var options = {
|
||||||
|
data: {
|
||||||
|
type: 'remote',
|
||||||
|
source: {
|
||||||
|
read: {
|
||||||
|
url: '{{ url("notification_rows") }}',
|
||||||
|
method: 'POST',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveState: {
|
||||||
|
cookie: false,
|
||||||
|
webstorage: false
|
||||||
|
},
|
||||||
|
pageSize: 10,
|
||||||
|
serverPaging: true,
|
||||||
|
serverFiltering: true,
|
||||||
|
serverSorting: true
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
title: 'ID',
|
||||||
|
width: 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'message',
|
||||||
|
title: 'Message'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'notif_type',
|
||||||
|
title: 'Notification Type'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
var table = $("#data-rows").mDatatable(options);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
Loading…
Reference in a new issue