Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 43
CRAP
0.00% covered (danger)
0.00%
0 / 868
NotificationService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 43
25760.00
0.00% covered (danger)
0.00%
0 / 868
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 __clone
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 7
 sendNotification
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 sendNotificationsAsynchronously
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 30
 processAndStoreNotificationToDatabase
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 23
 sendSingleNotification
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 13
 sendSingleEmail
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 65
 sendSinglePushNotification
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 19
 sendSingleSms
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 4
 sendPushNotification
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 35
 sendSms
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 28
 sendEmail
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 32
 getNotificationById
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 47
 getAllNotifications
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 77
 markNotificationsAsRead
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 markNotificationAsRead
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 markSmsAsSent
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getAllUnreadNotificationCount
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 20
 getHourDetailsOfADate
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 broadcastNotificationToAllStaffs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 broadcastNotificationToAllStudents
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 broadcastNotificationToSubjectStudents
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 sendBroadcastNotificationToAllStudents
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 44
 sendBroadcastNotificationToSubjectStudents
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 64
 sendBroadcastNotificationToAllStaffs
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 43
 addBirthdayWishSettings
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getBirthdayWishDetailsByUserType
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 updateBirthdayWishSettings
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 updateBirthdayWishAdditionalSettings
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 getNotificationByRequest
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 24
 changeVisibilityOfNotification
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 28
 sendBroadcastNotificationToStaffs
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 28
 clearNotifications
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 checkTemplateForSmsNotification
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getTemplatesForSmsNotification
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getSmsNotificationTemplateById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getSmsNotificationTemplateByName
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 updateSmsNotificationTemplatePropertiesById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 createCustomTemplate
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getCustomSmsTemplates
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 deleteSmsNotificationById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 selectSmsNotificationTemplateByTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
<?php
namespace com\linways\core\ams\professional\service\notification;
use com\linways\base\dto\Email;
use com\linways\base\dto\EmailTo;
use com\linways\base\dto\EmailFrom;
use com\linways\base\exception\TaskQueueException;
use com\linways\base\hooks\LinwaysHooks;
use com\linways\base\service\EmailService;
use com\linways\core\ams\professional\constant\notification\FCMNotificationCategories;
use com\linways\core\ams\professional\constant\notification\FCMNotificationGroupKeys;
use com\linways\core\ams\professional\constant\notification\NotificationContextConstant;
use com\linways\nucleus\core\service\SchedulerService;
use com\linways\core\ams\professional\constant\UserType;
use com\linways\core\ams\professional\queue\AMSTaskQueue;
use com\linways\core\ams\professional\service\BaseService;
use com\linways\core\ams\professional\service\AdminService;
use com\linways\core\ams\professional\service\StaffService;
use com\linways\core\ams\professional\service\StudentService;
use com\linways\core\ams\professional\dto\mobile\MobileLoginUser;
use com\linways\core\ams\professional\queue\OutBoundMessageQueue;
use com\linways\core\ams\professional\request\SearchStaffRequest;
use com\linways\core\ams\professional\request\SearchStudentRequest;
use com\linways\core\ams\professional\dto\notification\Notification;
use com\linways\core\ams\professional\constant\SchedulerCodesConstant;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\dto\notification\FCMNotification;
use com\linways\core\ams\professional\dto\notification\NotificationRecipient;
use com\linways\core\ams\professional\dto\notification\SendSingleNotification;
use com\linways\core\ams\professional\exception\notification\NotificationException;
use com\linways\core\ams\professional\mapper\notification\NotificationServiceMapper;
use com\linways\core\ams\professional\request\notification\GetGlobalSettingsRequest;
use com\linways\core\ams\professional\request\notification\GetAllNotificationsRequest;
use com\linways\core\ams\professional\constant\notification\NotificationFeatureConstant;
use com\linways\core\ams\professional\response\notification\GetAllNotificationsResponse;
use com\linways\core\ams\professional\constant\notification\SingleNotificationTypeConstant;
use com\linways\core\ams\professional\dto\notification\BirthdayWishSettings;
use com\linways\core\ams\professional\dto\notification\DeleteNotifications;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\core\ams\professional\service\PseudoSubjectService;
use stdClass;
class NotificationService extends BaseService
{
    // /Condition 1 - Presence of a static member variable
    private static $_instance = null;
    private $mapper = [];
    // /Condition 2 - Locked down the constructor
    private function __construct()
    {
        $this->mapper = NotificationServiceMapper::getInstance()->getMapper();
    }
    // Prevent any oustide instantiation of this class
    // /Condition 3 - Prevent any object or instance of that class to be cloned
    private function __clone()
    {
    }
    // Prevent any copy of this object
    // /Condition 4 - Have a single globally accessible static method
    public static function getInstance()
    {
        if (!is_object(self::$_instance))// or if( is_null(self::$_instance) ) or if( self::$_instance == null )
        {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
    /**
     *
     * @param Notification $notification
     * @return null
     * @throws ProfessionalException
     * @throws TaskQueueException
     * @author gadheyan
     */
    public function sendNotification($notification)
    {
        $params = [];
        $taskQueue = new AMSTaskQueue();
        try {
            $notification = $this->realEscapeObject($notification);
        } catch (\Exception $e) {
        }
        if (empty($notification->recipient)) {
            return null;
        }
        $params = ['className' => 'com\linways\core\ams\professional\service\notification\NotificationService', 'methodName' => 'sendNotificationsAsynchronously', 'methodParams' => [$notification]];
        try {
            $taskQueue->enqueue('EXECUTE SERVICE', $params);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     *
     * @param Notification $notification
     * @throws ProfessionalException
     * @throws \ReflectionException
     * @throws TaskQueueException
     * @author gadheyan
     */
    public function sendNotificationsAsynchronously($notification)
    {
        $getGlobalSettingsRequest = new GetGlobalSettingsRequest();
        try {
            $notification->notificationTypeId = NotificationUtilityService::getInstance()->getNotificationTypeIdFromNotificationTypeCode($notification->context, $notification->feature);
        } catch (\Exception $e) {
            throw new ProfessionalException(NotificationException::NOTIFICATION_TYPE_ID_NOT_FOUND_FOR_THE_GIVEN_CONTEXT_AND_FEATURE, $e->getMessage());
        }
        if (empty($notification->notificationTypeId)) {
            throw new ProfessionalException(NotificationException::NOTIFICATION_TYPE_ID_NOT_FOUND_FOR_THE_GIVEN_CONTEXT_AND_FEATURE, NotificationException::NOTIFICATION_TYPE_ID_NOT_FOUND_FOR_THE_GIVEN_CONTEXT_AND_FEATURE);
        }
        $getGlobalSettingsRequest->notificationTypeId = $notification->notificationTypeId;
        try {
            $globalSettings = NotificationSettingsService::getInstance()->getSingleGlobalSettings($getGlobalSettingsRequest);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if (empty($globalSettings)) {
            throw new ProfessionalException(NotificationException::INVALID_NOTIFICATION_TYPE, "There are no settings associated with this notfication type!");
        }
        $notification = $this->processAndStoreNotificationToDatabase($notification);
        if ($globalSettings->pushNotificationEnabled) {
            $this->sendPushNotification($notification->id);
        }
        if ($globalSettings->smsEnabled) {
            $this->sendSms($notification->id, $notification->smsDeferred);
        }
        if ($globalSettings->emailEnabled) {
            $this->sendEmail($notification->id, $notification->emailDeferred);
        }
    }
    /**
     *
     * @param Notification $notification
     * @return Notification
     * @throws ProfessionalException
     * @author gadheyan
     */
    public function processAndStoreNotificationToDatabase($notification)
    {
        $sqlNotification = "";
        $sqlRecipient = "";
        $notificationId = null;
        // $notification    = $this->realEscapeObject($notification);
        $sqlNotification = "INSERT INTO `notification` (`notification_type_id`, `created_by`, `created_date`, `creator_type`) VALUES ('$notification->notificationTypeId',  '$notification->createdBy', NOW(), '$notification->creatorType')";
        try {
            $notification->id = $this->executeQueryForObject($sqlNotification, TRUE);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        $sqlRecipient = "INSERT INTO `notification_recipient` (`recipient_id`, `recipient_type`, `notification_id`, `template_parameters` ) VALUES ";
        foreach ($notification->recipient as $recipient) {
            $recipient->templateParametersEncoded = addslashes(json_encode($recipient->templateParameters));
            $sqlRecipient .= "('" . $recipient->recipientId . "', '" . $recipient->recipientType . "', '$notification->id', '$recipient->templateParametersEncoded'),";
        }
        $sqlRecipient = rtrim($sqlRecipient, ',');
        // print("\n \n \n \n \n \n \n \n \n \n \n \n \n");
        // print_r($sqlRecipient);die();
        try {
            $this->executeQuery($sqlRecipient);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $notification;
    }
    public function sendSingleNotification($sendSingleNotification)
    {
        switch ($sendSingleNotification->type) {
            case SingleNotificationTypeConstant::PUSH_NOTIFICATION:
                $this->sendSinglePushNotification($sendSingleNotification->data);
                break;
            case SingleNotificationTypeConstant::SMS:
                $this->sendSingleSms($sendSingleNotification->data);
                break;
            case SingleNotificationTypeConstant::EMAIL:
                return $this->sendSingleEmail($sendSingleNotification->data);
                break;
        }
    }
    /**
     * @param $data
     * @return |null
     * @throws ProfessionalException
     */
    private function sendSingleEmail($data)
    {
        // global $college_mailID,$MailFromName;
        //receipientType will be present only if notification object,if email object no need for creating another email object
        try {
            if ($data->recipientType) {
                if ($data->recipientType == UserType::STAFF) {
                    $userDetails = StaffService::getInstance()->getStaffDetailsByIdForApi($data->recipientId);
                } elseif ($data->recipientType == UserType::STUDENT) {
                    $userDetails = StudentService::getInstance()->getStudentDetailsByIdForApi($data->recipientId);
                } elseif ($data->recipientType == UserType::ADMIN) {
                    $userDetails = AdminService::getInstance()->getAdminDetailsById($data->recipientId);
                }
                elseif ($data->recipientType == UserType::MANAGER) {
                    $userDetails = new stdClass();
                    $userDetails->email = $data->toList;
                }
                if (empty($userDetails)) {
                    return null;
                }
            }
            $emailCred='';
            if($data->module)
            {
                $emailCred = CommonService::getInstance()->getEmailConfByModule($data->module);
            }
            require getenv("AMS_CONFIG");
            @$GLOBALS['SMTPHost'] = $SMTPHost;
            @$GLOBALS['SMTPPort'] = $SMTPPort;
            @$GLOBALS['mailID'] = $mailID;
            @$GLOBALS['mailpassword'] = $mailpassword;
            //If notification object
            if ($data->recipientType) {
                $emailObj = new Email();
                $emailFrom = new EmailFrom();
                if(!empty($emailCred))
                {
                    $emailFrom->email = $emailCred->email;
                    $emailFrom->name = $emailCred->emailName;
                    $emailObj->emailCofiguration=$emailCred;
                }
                else
                {
                    $emailFrom->email = $college_mailID;
                    $emailFrom->name = $MailFromName;
                }
                $emailTo = new EmailTo();
                $emailTo->email = $userDetails->email;
                $emailTo->name = '';
                $emailObj->subject = $data->title;
                $emailObj->body = $data->body;
                $emailObj->from = $emailFrom;
                $emailObj->to = $emailTo;
            } else {
                //if email object
                $emailObj = $data;
                if(!empty($emailCred))
                {
                    $emailObj->from->email = $emailCred->email;
                    $emailObj->from->name = $emailObj->from->name??$emailCred->emailName;
                    $emailCred->emailName = $emailObj->from->name??$emailCred->emailName;
                    $emailObj->emailCofiguration=$emailCred;
                }
            }
            $result = EmailService::getInstance()->sendEmail($emailObj);
            return $result;
        } catch (\Exception $e) {
            return false;
        }
    }
    /**
     * @param $data
     * @throws ProfessionalException
     */
    private function sendSinglePushNotification($data)
    {
        $mobileUser = new MobileLoginUser();
        $mobileUser->userId = $data->recipientId;
        $mobileUser->userType = $data->recipientType;
        $fcmNotification = new FCMNotification();
        //do urlencode
        $fcmNotification->url = $data->url;
        //             print_r($fcmNotification->url);die();
        $fcmNotification->title = $data->title;
        //TODO: Create separate group for mailbox and change body content and message title for mail box notifications
//        $fcmNotification->groupKey = strtolower($data->notificationTypeContext);
//        switch ($data->notificationTypeContext) {
//            case NotificationContextConstant::MAILBOX:
//                $fcmNotification->category = FCMNotificationCategories::CATEGORY_MESSAGE;
//                break;
//            default:
//                $fcmNotification->category = FCMNotificationCategories::CATEGORY_EMAIL;
//                break;
//        }
        $fcmNotification->groupKey = FCMNotificationGroupKeys::GROUP_GENERAL_NOTIFICATIONS;
        $fcmNotification->category = FCMNotificationCategories::CATEGORY_MESSAGE;
        $fcmNotification->id = $data->notificationId;
        $fcmNotification->body = $data->body;
        $fcmNotification->mobileUser = $mobileUser;
        try {
            FCMNotificationService::getInstance()->sendFCMNotificationToSingleUser($fcmNotification);
            error_log("push notification sent to id:$data->recipientId, type:$data->recipientType");
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    private function sendSingleSms($data)
    {
        $hooks = LinwaysHooks::getInstance();
        $hooks->apply_filters('send_single_sms_hook', $data);
    }
    /**
     * @param integer $notificationId
     * @return null
     * @throws ProfessionalException
     * @throws \ReflectionException
     * @throws TaskQueueException
     * @author gadheyan
     */
    public function sendPushNotification($notificationId)
    {
        /**
         * @var Notification
         */
        $notification = NotificationService::getInstance()->getNotificationById($notificationId);
        $getGlobalSettingsRequest = new GetGlobalSettingsRequest();
        $getGlobalSettingsRequest->notificationTypeId = $notification->notificationTypeId;
        $globalSettings = NotificationSettingsService::getInstance()->getSingleGlobalSettings($getGlobalSettingsRequest);
        if (!$globalSettings->pushNotificationEnabled) {
            return null;
        }
        foreach ($notification->recipient as $recipient) {
            $refClass = new \ReflectionClass('com\linways\core\ams\professional\constant\notification\NotificationTemplateConstant');
            $template = json_decode($refClass->getConstant($notification->notificationType->templateName));
            $parameterReplacedTemplate = NotificationUtilityService::getInstance()->getMessageForNotification($template, $recipient->templateParameters);
            $sendSingleNotification = new SendSingleNotification();
            $sendSingleNotification->type = SingleNotificationTypeConstant::PUSH_NOTIFICATION;
            $sendSingleNotification->data = new \stdClass();
            $sendSingleNotification->data->recipientId = $recipient->recipientId;
            $sendSingleNotification->data->notificationTypeContext = $notification->notificationType->context;
            $sendSingleNotification->data->notificationId = $notificationId;
            $sendSingleNotification->data->recipientType = $recipient->recipientType;
            $sendSingleNotification->data->url = "rdir.php?recipientId=" . $recipient->id . "&next=" . urlencode($parameterReplacedTemplate->url_template);
            $sendSingleNotification->data->title = $parameterReplacedTemplate->message_template->push->title;
            $sendSingleNotification->data->body = $parameterReplacedTemplate->message_template->push->body;
            if (empty($sendSingleNotification->data->title) && empty($sendSingleNotification->data->body)) {
                continue;
            }
            $outboundQueue = new OutBoundMessageQueue();
            $params = [];
            $params = ['methodParams' => [$sendSingleNotification]];
            try {
                $outboundQueue->enqueue($params);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     *
     * @param integer $notificationId
     * @param boolean $smsDeferred
     * @throws ProfessionalException
     * @throws TaskQueueException
     * @author gadheyan
     */
    public function sendSms($notificationId, $smsDeferred)
    {
        $hookParams = new \stdClass();
        $hookParams->notificationId = $notificationId;
        //sms should be sent after some time or right now.
        if (!isset($smsDeferred) || !$smsDeferred) {
            $params = [];
            $taskQueue = new AMSTaskQueue();
            $params = ['hookName' => 'send_sms_hook', 'hookParams' => $hookParams];
            try {
                $taskQueue->enqueue('EXECUTE HOOK', $params);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        } else {
            //Schedule sms sending after 10 mins
            $schedule = new \stdClass();
            $schedule->params = [];
            $schedule->params["command"] = 'EXECUTE HOOK';
            $schedule->params["taskParams"] = [];
            $schedule->params["taskParams"]["hookName"] = "send_sms_hook";
            $schedule->params["taskParams"]["hookParams"] = $hookParams;
            $schedule->frequency = null;
            $schedule->nextExecutionAt = date('Y-m-d H:i:s', strtotime('+10 minutes', time()));
            try {
                $schedule->id = SchedulerService::getInstance()->addTask($schedule);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * @param $notificationId
     * @param null $emailDeffered
     * @return null |null
     * @throws ProfessionalException
     * @throws TaskQueueException
     * @throws \ReflectionException
     */
    public function sendEmail($notificationId, $emailDeffered = null)
    {
        $notification = NotificationService::getInstance()->getNotificationById($notificationId);
        $getGlobalSettingsRequest = new GetGlobalSettingsRequest();
        $getGlobalSettingsRequest->notificationTypeId = $notification->notificationTypeId;
        $globalSettings = NotificationSettingsService::getInstance()->getSingleGlobalSettings($getGlobalSettingsRequest);
        if (!$globalSettings->emailEnabled) {
            return null;
        }
        foreach ($notification->recipient as $recipient) {
            $refClass = new \ReflectionClass('com\linways\core\ams\professional\constant\notification\NotificationTemplateConstant');
            $template = json_decode($refClass->getConstant($notification->notificationType->templateName));
            $parameterReplacedTemplate = NotificationUtilityService::getInstance()->getMessageForNotification($template, $recipient->templateParameters, 1);
            $sendSingleNotification = new SendSingleNotification();
            $sendSingleNotification->type = SingleNotificationTypeConstant::EMAIL;
            $sendSingleNotification->data = new \stdClass();
            $sendSingleNotification->data->recipientId = $recipient->recipientId;
            $sendSingleNotification->data->recipientType = $recipient->recipientType;
            $sendSingleNotification->data->title = $parameterReplacedTemplate->message_template->email->title;
            $sendSingleNotification->data->body = $parameterReplacedTemplate->message_template->email->body;
            if (empty($sendSingleNotification->data->title) && empty($sendSingleNotification->data->body)) {
                continue;
            }
            $outboundQueue = new OutBoundMessageQueue();
            $params = [];
            $params = ['methodParams' => [$sendSingleNotification]];
            try {
                $outboundQueue->enqueue($params);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     *
     * @param integer $notificationId
     * @return Notification|Object
     * @throws ProfessionalException
     * @author gadheyan
     */
    public function getNotificationById($notificationId)
    {
        $sql = "";
        $sqlCount = "";
        $sqlCountForUnreadNotifications = "";
        $notificationId = $this->realEscapeString($notificationId);
        $sql = "SELECT
                nt.id as notification_id,
                nt.notification_type_id as notification_notification_type_id,
                nt.creator_type as notification_creator_type,
                nt.recipient_type as notification_recipient_type,
                nt.created_by as notification_created_by,
                nt.created_date as notification_created_date,
                ntr.id as notification_recipient_id,
                ntr.recipient_id as notification_recipient_recipient_id,
                ntr.recipient_type as notification_recipient_recipient_type,
                ntr.notification_id as notification_recipient_notification_id,
                ntr.is_read as notification_recipient_is_read,
                ntr.read_at as notification_recipient_read_at,
                ntr.template_parameters as notification_recipient_template_parameters,
                ntr.sms_sent_at as notification_recipient_sms_sent_at,
                ntr.sms_status as notification_recipient_sms_status,
                ntr.email_sent_at as notification_recipient_email_sent_at,
                ntr.email_status as notification_recipient_email_status,
                ntt.id as notification_type_id,
                ntt.name as notification_type_name,
                ntt.context as notification_type_context,
                ntt.feature as notification_type_feature,
                ntt.template_name as notification_type_template_name,
                ntt.custom_template as notification_type_custom_template,
                ntt.created_by as notification_type_created_by,
                ntt.created_date as notification_type_created_date,
                ntt.updated_by as notification_type_updated_by,
                ntt.updated_date as notification_type_updated_date
                FROM notification nt
                INNER JOIN notification_recipient ntr ON ntr.notification_id = nt.id AND nt.id = '$notificationId'
                INNER JOIN notification_type ntt ON nt.notification_type_id = ntt.id
                ORDER BY nt.created_date DESC";
        try {
            $notification = $this->executeQueryForObject($sql, FALSE, $this->mapper[NotificationServiceMapper::GETNOTIFICATIONBYID]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if ($notification->recipient) {
            $notification->recipientType = $notification->recipient[0]->recipientType;
        }
        return $notification;
    }
    /**
     * Method to get all unread notifications of a person.
     * @param GetAllNotificationsRequest $notificationRequest
     * @return \com\linways\core\ams\professional\response\notification\getAllNotificationsResponse
     * @throws NotificationException
     * @throws ProfessionalException
     * @author gadheyan
     */
    public function getAllNotifications(GetAllNotificationsRequest $notificationRequest)
    {
        $sql = "";
        $sqlCount = "";
        $sqlCountForUnreadNotifications = "";
        $notificationRequest = $this->realEscapeObject($notificationRequest);
        $conditionStatement = "";
        $notificationResponse = new GetAllNotificationsResponse();
        if(!empty($notificationRequest->context)) {
            $conditionStatement .= " AND ntt.context='".$notificationRequest->context."' ";
        }
        if(!empty($notificationRequest->feature)) {
            $conditionStatement .= " AND ntt.feature='".$notificationRequest->feature."' ";
        }
        $sql = "SELECT
                nt.id as notification_id,
                nt.notification_type_id as notification_notification_type_id,
                nt.created_by as notification_created_by,
                nt.created_date as notification_created_date,
                nt.creator_type as notification_creator_type,
                nt.recipient_type as notification_recipient_type,
                ntr.id as notification_recipient_id,
                ntr.recipient_id as notification_recipient_recipient_id,
                ntr.recipient_type as notification_recipient_recipient_type,
                ntr.notification_id as notification_recipient_notification_id,
                ntr.is_read as notification_recipient_is_read,
                ntr.read_at as notification_recipient_read_at,
                ntr.template_parameters as notification_recipient_template_parameters,
                ntr.sms_sent_at as notification_recipient_sms_sent_at,
                ntr.sms_status as notification_recipient_sms_status,
                ntr.email_sent_at as notification_recipient_email_sent_at,
                ntr.email_status as notification_recipient_email_status,
                ntt.id as notification_type_id,
                ntt.name as notification_type_name,
                ntt.context as notification_type_context,
                ntt.feature as notification_type_feature,
                ntt.template_name as notification_type_template_name,
                ntt.custom_template as notification_type_custom_template,
                ntt.created_by as notification_type_created_by,
                ntt.created_date as notification_type_created_date,
                ntt.updated_by as notification_type_updated_by,
                ntt.updated_date as notification_type_updated_date
                FROM notification nt
                INNER JOIN notification_recipient ntr ON ntr.notification_id = nt.id AND ntr.recipient_id = '$notificationRequest->requesterId' AND ntr.recipient_type = '$notificationRequest->requesterType' AND nt.is_visible = 1
                INNER JOIN notification_type ntt ON nt.notification_type_id = ntt.id
                WHERE 1=1 AND ntt.id in(select notification_type_id from notification_settings_global where native_enabled = 1) $conditionStatement
                ORDER BY nt.created_date DESC";
        $sqlCount = "SELECT
                count(nt.id) as totalRecords
                FROM notification nt
                INNER JOIN notification_recipient ntr ON ntr.notification_id = nt.id AND ntr.recipient_id = '$notificationRequest->requesterId' AND ntr.recipient_type = '$notificationRequest->requesterType'
                INNER JOIN notification_type ntt ON nt.notification_type_id = ntt.id
                WHERE nt.is_visible = 1 AND ntt.id in(select notification_type_id from notification_settings_global where native_enabled = 1) $conditionStatement ";
        $sqlCountForUnreadNotifications = "SELECT
                count(nt.id) as totalRecords
                FROM notification nt
                INNER JOIN notification_recipient ntr ON ntr.notification_id = nt.id AND ntr.recipient_id = '$notificationRequest->requesterId' AND ntr.recipient_type = '$notificationRequest->requesterType' AND ntr.is_read = 0
                INNER JOIN notification_type ntt ON nt.notification_type_id = ntt.id
                WHERE nt.is_visible = 1 AND ntt.id in(select notification_type_id from notification_settings_global where native_enabled = 1) $conditionStatement ";
        if ($notificationRequest->startIndex != null && $notificationRequest->pageSize != null) {
            $sql .= " LIMIT $notificationRequest->startIndex$notificationRequest->pageSize";
        }
        try {
            $notificationResponse->notificationsList = $this->executeQueryForList($sql, $this->mapper[NotificationServiceMapper::GETALLNOTIFICATIONS]);
            $notificationResponse->totalRecords = $this->executeQueryForObject($sqlCount)->totalRecords;
            $notificationResponse->totalUnreadNotifications = $this->executeQueryForObject($sqlCountForUnreadNotifications)->totalRecords;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if ($notificationResponse->notificationsList) {
            try {
                $notificationResponse->notificationsList = NotificationUtilityService::getInstance()->replaceNotificationTemplatesWithParameters($notificationResponse->notificationsList);
            } catch (\Exception $e) {
                $notificationResponse->notificationsList = [];
            }
        }
        return $notificationResponse;
    }
    /**
     *
     * @param Array $notificationRecipientIds
     * @throws ProfessionalException
     * @author gadheyan
     */
    public function markNotificationsAsRead($notificationRecipientIds)
    {
        $sql = "";
        $notificationRecipientIds = $this->realEscapeObject($notificationRecipientIds);
        $sql = "UPDATE `notification_recipient` SET `is_read`='1', `read_at`= NOW() WHERE `id` IN('" . implode("','", $notificationRecipientIds) . "')";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /*
    * Mark a notification as read
    */
    public function markNotificationAsRead($id,$recipientId)
    {
        $sql = "";
        $id = $this->realEscapeString($id);
        $recipientId = $this->realEscapeString($recipientId);
        $sql = "UPDATE notification_recipient SET is_read='1',read_at=NOW() WHERE id='$id' AND recipient_id='$recipientId'";
        try{
            $this->executeQuery($sql);
        }catch(\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * [markSmsAsRead description]
     * @param $notificationRecipientId
     * @param $status
     * @return void [type]                          [description]
     * @throws ProfessionalException
     */
    public function markSmsAsSent($notificationRecipientId, $status)
    {
        $sql = "";
        $notificationRecipientId = $this->realEscapeString($notificationRecipientId);
        $sql = "UPDATE `notification_recipient` SET `sms_sent_at`=NOW(), `sms_status`='$status' WHERE `id`='$notificationRecipientId'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Returns count of unread notifications of particular user by user id and type
     * @param GetAllNotificationsRequest $notificationRequest
     * @return int
     * @throws NotificationException
     * @throws ProfessionalException
     */
    public function getAllUnreadNotificationCount($notificationRequest)
    {
        $count = 0;
        $notificationRequest = $this->realEscapeObject($notificationRequest);
        if (empty($notificationRequest->requesterId))
            throw new NotificationException(NotificationException::EMPTY_USER_ID, "Invalid user id");
        if (empty($notificationRequest->requesterType))
            throw new NotificationException(NotificationException::EMPTY_USER_TYPE, "Invalid user type");
        $sql = "SELECT
                count(nt.id) as totalRecords
                FROM notification nt
                INNER JOIN notification_recipient ntr ON ntr.notification_id = nt.id AND ntr.recipient_id = '$notificationRequest->requesterId' AND ntr.recipient_type = '$notificationRequest->requesterType' AND ntr.is_read = 0
                INNER JOIN notification_type ntt ON nt.notification_type_id = ntt.id
                INNER JOIN notification_settings_global nsg ON nsg.notification_type_id = ntt.id AND nsg.notification_type_id = nt.notification_type_id AND nsg.native_enabled = 1";
        try {
            $count = $this->executeQueryForObject($sql)->totalRecords;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $count;
    }
    /**
     * Method to get hourId,startTime,endTime for a particular timetable date.
     * @param Date $timeTableDate
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getHourDetailsOfADate($timeTableDate, $batchId, $semId)
    {
        $sql = "";
        $timeTableDate = $this->realEscapeString($timeTableDate);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT  hourID as hourId, stratTime as startTime, endTime FROM batch_timetable WHERE batchID = '$batchId' AND semID = '$semId' AND timetableDate = '$timeTableDate' group by hourID, stratTime, endTime";
        try {
            $hourList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $hourList;
    }
    /**
     * put broadcast notification request to queue
     *
     * @param [type] $notification
     * @return void
     * @throws ProfessionalException
     * @throws TaskQueueException
     */
    public function broadcastNotificationToAllStaffs($parameters)
    {
        // $parameters = $this->realEscapeObject($parameters);
        $taskQueue = new AMSTaskQueue();
        $params = ['className' => 'com\linways\core\ams\professional\service\notification\NotificationService', 'methodName' => 'sendBroadcastNotificationToAllStaffs', 'methodParams' => [$parameters]];
        try {
            $taskQueue->enqueue('EXECUTE SERVICE', $params);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * put broadcast notification request to queue
     *
     * @param [type] $notification
     * @return void
     * @throws ProfessionalException
     * @throws TaskQueueException
     */
    public function broadcastNotificationToAllStudents($parameters)
    {
        // $parameters = $this->realEscapeObject($parameters);
        $taskQueue = new AMSTaskQueue();
        $params = ['className' => 'com\linways\core\ams\professional\service\notification\NotificationService', 'methodName' => 'sendBroadcastNotificationToAllStudents', 'methodParams' => [$parameters]];
        try {
            $taskQueue->enqueue('EXECUTE SERVICE', $params);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * put broadcast notification request to queue
     *
     * @param [type] $notification
     * @return void
     * @throws ProfessionalException
     * @throws TaskQueueException
     */
    public function broadcastNotificationToSubjectStudents($parameters)
    {
        $taskQueue = new AMSTaskQueue();
        $params = ['className' => 'com\linways\core\ams\professional\service\notification\NotificationService', 'methodName' => 'sendBroadcastNotificationToSubjectStudents', 'methodParams' => [$parameters]];
        try {
            $taskQueue->enqueue('EXECUTE SERVICE', $params);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * send notification
     *
     * @param [type] $parameters
     * @return void
     */
    public function sendBroadcastNotificationToAllStudents($parameters)
    {
        //notification is sent as chunks so as to reduce memory consumpton
        $studentList = [];
        $staffList = [];
        $chunkSize = 50;//how many number of students/staffs shold you take
        $startIndex = 0;
        $request = new SearchStudentRequest();
        $request->startIndex = $startIndex;
        $request->endIndex = $chunkSize;
        $studentList = StudentService::getInstance()->searchStudent($request);
        $noOfLoops = ceil($studentList->totalRecords / $chunkSize);
        for ($i = 0; $i < $noOfLoops; $i++) {
            $request = null;
            $request = new SearchStudentRequest();
            $request->startIndex = $startIndex;
            $request->endIndex = $chunkSize;
            $studentList = StudentService::getInstance()->searchStudent($request);
            $notification = new Notification();
            $notification->context = $parameters->notificationContext;
            $notification->feature = $parameters->notificationFeature;
            $notification->recipientType = UserType::STUDENT;
            $notification->smsDeferred = $parameters->smsDeffered;
            $notification->createdBy = $parameters->createdBy;
            $notification->creatorType = $parameters->creatorType;
            foreach ($studentList->students as $student) {
                $recipient = null;
                $recipient = new NotificationRecipient();
                $recipient->recipientId = $student->studentID;
                $recipient->recipientType = UserType::STUDENT;
                $recipient->templateParameters = clone $parameters->templateParameters;
                $notification->recipient[] = $recipient;
                unset($recipient);
            }
            try {
                $this->sendNotification($notification);
            } catch (\Exception $e) {
                //log exception
                $errorMsg = "Error Code : '" . $e->getCode() . "' . Error Message : " . $e->getMessage();
                error_log($errorMsg);
            }
            $startIndex += $chunkSize;
            unset($request);
            unset($notification);
            unset($studentList);
        }
    }
    public function sendBroadcastNotificationToSubjectStudents($parameters)
    {
        //notification is sent as chunks so as to reduce memory consumpton
        $studentList = [];
        $staffList = [];
        $chunkSize = 50;//how many number of students/staffs should you take
        $startIndex = 0;
        $request = new SearchStudentRequest();
        $request->startIndex = $startIndex;
        $request->endIndex = $chunkSize;
        $studentList=[];
        if($parameters->notificationContext==NotificationContextConstant::QUIZ || $parameters->notificationContext==NotificationContextConstant::VIDEO_CONTENT || $parameters->notificationContext==NotificationContextConstant::ASSIGNMENT || $parameters->notificationContext==NotificationContextConstant::ONLINE_EXAM)
        {
            if($parameters->pseudoSubjectId){
                $studentList = PseudoSubjectService::getInstance()->getPseudoSubjectDetailsByRequest($parameters->psRequest);
            }
            elseif($parameters->subbatchIDs !=0)
            {
                $subbatchList = explode(',', $parameters->subbatchIDs);
                foreach ($subbatchList as $subbatchId)
                {
                    $studentListTemp=StudentService::getInstance()->getStudentDetailsByBatchSemIdAndSubbatchId($parameters->batchId, $parameters->semId, $subbatchId);
                    $studentList = array_merge($studentList, $studentListTemp);
                }
            }
            else
            {
                $studentList = StudentService::getInstance()->getStudentDetailsByBatchSemIdAndSubbatchId($parameters->batchId, $parameters->semId);
            }
        }
        else
        {
            $studentList = StudentService::getInstance()->getAllStudentsByBatchIdSemIdSubjectId($parameters->batchId, $parameters->semId, $parameters->subjectId);
        }
        $notification = new Notification();
        $notification->context = $parameters->notificationContext;
        $notification->feature = $parameters->notificationFeature;
        $notification->recipientType = UserType::STUDENT;
        $notification->smsDeferred = $parameters->smsDeffered;
        $notification->createdBy = $parameters->createdBy;
        $notification->creatorType = $parameters->creatorType;
        foreach ($studentList as $student) {
            $recipient = null;
            $recipient = new NotificationRecipient();
            $recipient->recipientId = $student->id;
            $recipient->recipientType = UserType::STUDENT;
            $parameterObject = (Object)$parameters->templateParameters;
            $recipient->templateParameters = clone $parameterObject;
            //in case of pseudo subject we create assignment for each sub batches, so we need to replace assignment ids of each students to their sub batch assignment ids
            if($parameters->pseudoSubjectId && $student->assignmentID &&
            $parameters->notificationContext==NotificationContextConstant::ASSIGNMENT){
                $recipient->templateParameters->assignmentId = $student->assignmentID;
            }
            $notification->recipient[] = $recipient;
            unset($recipient);
        }
        try {
            $this->sendNotification($notification);
        } catch (\Exception $e) {
            //log exception
            $errorMsg = "Error Code : '" . $e->getCode() . "' . Error Message : " . $e->getMessage();
            error_log($errorMsg);
        }
        $startIndex += $chunkSize;
        unset($request);
        unset($notification);
        unset($studentList);
    }
    /**
     * send notification
     *
     * @param [type] $parameters
     * @return void
     * @throws ProfessionalException
     */
    public function sendBroadcastNotificationToAllStaffs($parameters)
    {
        //notification is sent as chunks so as to reduce memory consumpton
        $staffList = [];
        $chunkSize = 50;//how many number of students/staffs shold you take
        $startIndex = 0;
        $request = new SearchStaffRequest();
        $request->startIndex = $startIndex;
        $request->endIndex = $chunkSize;
        $staffList = StaffService::getInstance()->searchStaffDetails($request);
        $noOfLoops = ceil($staffList->totalRecords / $chunkSize);
        for ($i = 0; $i < $noOfLoops; $i++) {
            $request = null;
            $request = new SearchStaffRequest();
            $request->startIndex = $startIndex;
            $request->endIndex = $chunkSize;
            $staffList = StaffService::getInstance()->searchStaffDetails($request);
            $notification = new Notification();
            $notification->context = $parameters->notificationContext;
            $notification->feature = $parameters->notificationFeature;
            $notification->recipientType = UserType::STAFF;
            $notification->smsDeferred = $parameters->smsDeffered;
            $notification->createdBy = $parameters->createdBy;
            $notification->creatorType = $parameters->creatorType;
            foreach ($staffList->staffdetails as $staff) {
                $recipient = null;
                $recipient = new NotificationRecipient();
                $recipient->recipientId = $staff->staffId;
                $recipient->recipientType = UserType::STAFF;
                $recipient->templateParameters = clone $parameters->templateParameters;
                $notification->recipient[] = $recipient;
                unset($recipient);
            }
            try {
                $this->sendNotification($notification);
            } catch (\Exception $e) {
                //log exception
                $errorMsg = "Error Code : '" . $e->getCode() . "' . Error Message : " . $e->getMessage();
                error_log($errorMsg);
            }
            $startIndex += $chunkSize;
            unset($request);
            unset($notification);
            unset($staffList);
        }
    }
    /**
     * Add birthday wish settings
     * @param BirthdayWishSettings|Object
     * @return Integer $id
     * @throws ProfessionalException
     */
    public function addBirthdayWishSettings(BirthdayWishSettings $wishSettings){
        $wishSettings = $this->realEscapeObject($wishSettings);
        $wishSettings->moreSettings = json_encode($wishSettings->moreSettings);
        $sql = "";
        $sql = "INSERT INTO birthday_wish_settings (sms_content,email_subject,email_content,greetings_path,userType,sms_enable,email_enable,more_settings,updated_by,created_date,updated_date) VALUES('$wishSettings->smsContent','$wishSettings->emailSubject','$wishSettings->emailContent','$wishSettings->greetingsPath','$wishSettings->userType',$wishSettings->smsEnable,
        $wishSettings->emailEnable,'$wishSettings->moreSettings',$wishSettings->updatedBy,UTC_DATE(),UTC_DATE())";
        try {
            return $this->executeQueryForObject($sql, TRUE);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * To get birthday wish details by userType
     * @param String $userType
     * @return BirthdayWishSettings|Object
     * @throws ProfessionalException
     */
    public function getBirthdayWishDetailsByUserType($userType){
        $userType = $this->realEscapeString($userType);
        $sql = "";
        $sql = "SELECT sms_content, email_subject, email_content, greetings_path, sms_enable, email_enable, more_settings FROM birthday_wish_settings WHERE userType= '$userType'";
        try {
            $wishDetails= $this->executeQueryForList($sql);
            return $wishDetails;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * update birthday wish details by userType
     * @param BirthdayWishSettings|Object
     * @return NULL
     * @throws ProfessionalException
    */
    public function updateBirthdayWishSettings(BirthdayWishSettings $wishSettings){
        $sql = "";
        $wishSettings = $this->realEscapeObject($wishSettings);
        $wishSettings->moreSettings = json_encode($wishSettings->moreSettings);
        $sql = "UPDATE birthday_wish_settings SET sms_content='$wishSettings->smsContent', email_subject='$wishSettings->emailSubject',email_content='$wishSettings->emailContent', greetings_path='$wishSettings->greetingsPath', sms_enable=$wishSettings->smsEnable, email_enable=$wishSettings->emailEnable,more_settings='$wishSettings->moreSettings',updated_by =$wishSettings->updatedBy,updated_date=UTC_DATE()  WHERE userType = '$wishSettings->userType'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * update birthday wish details by userType
     * @param BirthdayWishSettings|Object
     * @return NULL
     * @throws ProfessionalException
    */
    public function updateBirthdayWishAdditionalSettings(BirthdayWishSettings $wishSettings){
        $sqlMoreSettings = "select more_settings from birthday_wish_settings where userType = '$wishSettings->userType'";
        $moreSettings = $this->executeQueryForObject($sqlMoreSettings)->more_settings;
        if($moreSettings){
            $additionalSettings = json_decode($moreSettings,true);
            $wishSettings->moreSettings = array_merge($additionalSettings,json_decode($wishSettings->moreSettings,true));
            $wishSettings->moreSettings = json_encode($wishSettings->moreSettings,true);
        }
        $sql = "";
        $sql = "UPDATE birthday_wish_settings SET more_settings = '$wishSettings->moreSettings',updated_by =$wishSettings->updatedBy,updated_date=UTC_DATE() WHERE userType = '$wishSettings->userType'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get Notification By Request
     */
    public function getNotificationByRequest(DeleteNotifications $request)
    {
        $where = [];
        (int)$request->id?$where[] = "n.id = ".(int)$request->id:null;
        $request->creatorType?$where[] = "n.creator_type = '".$request->creatorType."'":null;
        (int)$request->creatorId?$where[] = "n.created_by = ".(int)$request->creatorId:null;
        $request->context?$where[] = "nt.context = '".$request->context."'":null;
        $request->feature?$where[] = "nt.feature = '".$request->feature."'":null;
        foreach ($request->templateParametersFilter as $filter) {
            $filter->name && $filter->value?$where[]="nr.template_parameters->\"$.".$filter->name."\" = \"".$filter->value."\"":null;
        }
        $sqlSelect = "SELECT n.id,n.creator_type,n.created_by,n.created_date,
            concat('[',group_concat('{ \"recipient_type\":\"',nr.recipient_type,
            '\",\"userId\":',nr.recipient_id,
            ',\"notification_id\":',nr.notification_id,
            ',\"is_read\":',nr.is_read,
            ',\"template_parameters\":',nr.template_parameters,'}'),']') as recipientData
            from notification n
            inner join notification_recipient nr on nr.notification_id = n.id
            inner join notification_type nt on nt.id = n.notification_type_id
            WHERE ".implode(' and ',$where)."
            group by n.id
            order by n.id;";
        return $this->executeQueryForList($sqlSelect);
    }
    /**
     * update visibility of notification using request
     */
    public function changeVisibilityOfNotification(DeleteNotifications $request){
        $sql = "";
        $where = [];
        $notifications = $this->getNotificationByRequest($request);
        if($notifications)
        {
            (int)$request->id?$where[] = "n.id = ".(int)$request->id:null;
            $request->creatorType?$where[] = "n.creator_type = '".$request->creatorType."'":null;
            (int)$request->creatorId?$where[] = "n.created_by = ".(int)$request->creatorId:null;
            $request->context?$where[] = "nt.context = '".$request->context."'":null;
            $request->feature?$where[] = "nt.feature = '".$request->feature."'":null;
            foreach ($request->templateParametersFilter as $filter) {
                $filter->name && $filter->value?$where[]="nr.template_parameters->\"$.".$filter->name."\" = \"".$filter->value."\"":null;
            }
            try {
                $sql = "UPDATE notification n
                INNER JOIN notification_recipient nr on nr.notification_id = n.id
                INNER join notification_type nt on nt.id = n.notification_type_id
                SET n.is_visible = $request->visibility
                WHERE ".implode(' and ',$where).";";
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        else {
            return false;
        }
    }
    /**
     * send notification to seleted staffs
     * @param [type] $parameters
     * @return void
     * @throws ProfessionalException
     */
    public function sendBroadcastNotificationToStaffs($parameters)
    {
            $staffList = $parameters->staffList;
            $notification = new Notification();
            $notification->context = $parameters->notificationContext;
            $notification->feature = $parameters->notificationFeature;
            $notification->recipientType = UserType::STAFF;
            $notification->smsDeferred = $parameters->smsDeffered;
            $notification->createdBy = $parameters->createdBy;
            $notification->creatorType = $parameters->creatorType;
            foreach ($staffList as $staff) {
                $recipient = null;
                $recipient = new NotificationRecipient();
                $recipient->recipientId = $staff->id? $staff->id :$staff['staffID'];
                $recipient->recipientType = UserType::STAFF;
                $recipient->templateParameters =  $parameters->templateParameters;
                $notification->recipient[] = $recipient;
                unset($recipient);
            }
            try {
                $this->sendNotification($notification);
            } catch (\Exception $e) {
                //log exception
                $errorMsg = "Error Code : '" . $e->getCode() . "' . Error Message : " . $e->getMessage();
                error_log($errorMsg);
            }
            unset($request);
            unset($notification);
            unset($staffList);
    }
    /**
    * Delete notification recepients till the current time
     * @param [type] $parameters
     * @return void
     * @throws ProfessionalException
    */
    public function clearNotifications()
    {
        try {
                $sql = "delete  ntr.* from notification nt
                INNER JOIN notification_recipient ntr ON ntr.notification_id = nt.id where nt.created_date <".date('Y-m-d H:i:s')."";
                $this->executeQuery($sql);
                return true;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
   /**
    * method to select smsNotificationTemplate details
    * @param name,type
    * @return Boolean
    * @throws professionalException
    */
    public function checkTemplateForSmsNotification($name,$type)
    {
        try {
                $sql = "SELECT id, name, type, properties,content FROM smsNotificationTemplate WHERE name = '$name' AND type = '$type";
                return $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to select all smsNotificationTemplate details
    *
    * @return Boolean
    * @throws professionalException
    */
    public function getTemplatesForSmsNotification()
    {
        try {
                $sql = "SELECT id, name, type, properties,content,template_type,description,tags FROM smsNotificationTemplate
                        where isHidden = '0' order by template_type DESC";
                $templates= $this->executeQueryForList($sql);
                foreach($templates as $temp){
                    $temp->properties = json_decode($temp->properties);
                    $temp->tags = json_decode($temp->tags);
                }
                return $templates;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to get smsNotificationTemplate details by id
    * @param Integer
    * @return Object
    * @throws professionalException
    */
    public function getSmsNotificationTemplateById($id)
    {
        try {
                $sql = "SELECT id, name, type, properties,content FROM smsNotificationTemplate where id='$id";
                $template= $this->executeQueryForObject($sql);
                $template->properties = json_decode($template->properties);
                return $template;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to get smsNotificationTemplate details by name
    * @param String
    * @return Object
    * @throws professionalException
    */
    public function getSmsNotificationTemplateByName($name)
    {
        try {
                $sql = "SELECT id, `name`, `type`, properties,content,tags FROM smsNotificationTemplate where `name`='$name";
                $template= $this->executeQueryForObject($sql);
                return $template;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
     /**
    * method to update smsNotificationTemplate  by id
    * @param Integer
    * @throws professionalException
    */
    public function updateSmsNotificationTemplatePropertiesById($id,$properties)
    {
        $properties = json_encode($properties);
        try {
                $sql = "UPDATE smsNotificationTemplate set properties = '$properties' where id='$id";
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to update create custom template
    * @param Object
    * @return Boolean
    * @throws professionalException
    */
    public function createCustomTemplate($request)
    {
        try {
                $sql = "INSERT INTO `smsNotificationTemplate` (`name`, `type`, `properties`, `template_type`,`isHidden`, `createdAt`)
                VALUES ('$request->name', '$request->type', '$request->properties', '$request->templateType','0', UTC_TIMESTAMP()) ";
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to update smsNotificationTemplate  by id
    * @param Integer
    * @return Array
    * @throws professionalException
    */
    public function getCustomSmsTemplates()
    {
        try {
                $sql = "SELECT id, name, type from smsNotificationTemplate where template_type = 'CUSTOM'";
                return $this->executeQueryForList($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to delte smsNotificationTemplate  by id
    * @param Integer
    * @throws professionalException
    */
    public function deleteSmsNotificationById($id)
    {
        try {
                $sql = "DELETE from smsNotificationTemplate where id = '$id'";
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
    /**
    * method to select sms notification Template by notification typeId
    * @param Integer
    * @throws professionalException
    */
    public function selectSmsNotificationTemplateByTypeId($id)
    {
        try {
                $sql = "SELECT snt.name, snt.type, snt.feature,snt.properties
                        from smsNotificationTemplate snt inner join notification_type nt on snt.feature = nt.feature
                        where nt.id = $id ";
                $result = $this->executeQueryForObject($sql);
                $result->properties = json_decode($result->properties);
                return $result;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
    }
}