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 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 309
V4IntimationService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 9
1980.00
0.00% covered (danger)
0.00%
0 / 309
 __clone
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 setSchedulerForIntimation
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 74
 fetchAllNotificationContents
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 15
 sendBulkIntimationRecursive
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 61
 sendEmailIntimationBulk
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 71
 sendSmsIntimationBulk
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 9
 sendIntimationRecursive
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 69
<?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\core\ams\professional\dto\V4IntimationLog;
use com\linways\base\util\StringUtil;
use com\linways\base\constant\UserType;
use com\linways\core\ams\professional\constant\academic\StatusConstants;
use com\linways\core\ams\professional\logging\Events;
use com\linways\core\ams\professional\constant\Modules;
use com\linways\core\ams\professional\logging\AMSLogger;
use com\linways\core\ams\professional\service\BaseService;
use com\linways\core\ams\professional\dto\v4\IntimationData;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\core\ams\professional\logging\entities\Staff;
use com\linways\core\ams\professional\util\V4\AcademicIntimationUtil;
use com\linways\core\ams\professional\dto\v4\IntimationDataProperties;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\service\v4Attendance\V4AttendanceService;
use com\linways\core\ams\professional\service\SMSService;
use com\linways\core\ams\professional\service\V4IntimationLogService;
use com\linways\core\ams\professional\dto\notification\SendSingleNotification;
use com\linways\core\ams\professional\constant\notification\SingleNotificationTypeConstant;
use com\linways\core\ams\professional\service\notification\NotificationService;
use com\linways\base\dto\sms\SMS;
use com\linways\core\ams\professional\constant\V4IntimationLogModuleConstants;
use com\linways\core\ams\professional\constant\V4IntimationLogReceiverTypeContext;
use com\linways\core\ams\professional\constant\V4IntimationLogStatusConstants;
use com\linways\core\ams\professional\constant\V4IntimationTypeConstants;
use com\linways\core\ams\professional\dto\V4IntimationLogExtraDetails;
class V4IntimationService  extends BaseService
{
    private static $_instance = null;
    private $mapper = [];
    private $logger = null;
    //  Prevent any object or instance of that class to be cloned
    private function __clone()
    {
    }
    private function __construct()
    {
        $this->logger = AMSLogger::getLogger();
    }
    //  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;
    }
    /**
     * set scheduler for intimation
     *
     * @param Object $request
     * @return void
     */
    public function setSchedulerForIntimation($request)
    {
        try {
            $identifyingConstant = $request->identifyingConstant;
            $intimationModule = V4IntimationLogModuleConstants::ACADEMICS;
            $intimationReceiverTypeContext = "";
            switch ($identifyingConstant) {
                case "V4_ATTENDANCE_AUTOMATIC_INTIMATION_FOR_ABSENTEES";
                    $intimationReceiverTypeContext = V4IntimationLogReceiverTypeContext::STUDENT;
                    // fetch absentees student details of current date
                    $req = new \stdClass();
                    $date = date("Y-m-d");
                    $req->date = $date;
                    $studentList = V4AttendanceService::getInstance()->intimationNonSendStudentsForMarkedAttendance($req);
                    $supportingTags = new \stdClass();
                    $supportingTags->studentName = 'name';
                    $supportingTags->emailId = 'emailId';
                    $supportingTags->draftedStaffName = 'draftedStaffName';
                    $supportingTags->batchName = 'batchName';
                    $supportingTags->absentHour = 'absentHour';
                    $supportingTags->mobileNo = 'mobileNo';
                    $supportingTags = (array) $supportingTags;
                    break;
                case "V4_ATTENDANCE_REMINDER_FOR_FACULTIES";
                    $intimationReceiverTypeContext = V4IntimationLogReceiverTypeContext::STAFF;
                    // fetch unmarked faculty details of current date
                    $req = new \stdClass();
                    $date = date("Y-m-d");
                    $req->date = $date;
                    $studentList = V4AttendanceService::getInstance()->intimationForUnmarkedFaculty($req);
                    $supportingTags = new \stdClass();
                    $supportingTags->staffName = 'name';
                    $supportingTags->emailId = 'emailId';
                    $supportingTags->attendanceStartTime = 'attendanceStartTime';
                    $supportingTags->attendanceEndTime = 'attendanceEndTime';
                    $supportingTags->draftedStaffName = 'draftedStaffName';
                    $supportingTags->batchName = 'batchName';
                    $supportingTags->unmarkedHour = 'hours';
                    $supportingTags->mobileNo = 'mobileNo';
                    $supportingTags = (array) $supportingTags;
                    break;
            }
            $notificationContent = $this->fetchAllNotificationContents($request->intimationTemplate);
            // call intimation service
            $intimationData = new \stdClass();
            $intimationData->intimationData = new \stdClass();
            $request->enabledNotifications = json_decode(stripslashes($request->enabledNotifications));
            $intimationData->intimationData->intimationTypes = array_keys((array)$request->enabledNotifications, function ($obj) {
                return $obj;
            });
            // supporting tags
            $intimationData->intimationData->supportingTags = $supportingTags;
            // $intimationData->intimationData->recipients ;
            $intimationData->intimationData->emailAttachments = [];
            $intimationData->intimationData->emailSubject = $notificationContent->emailSubject;
            $intimationData->intimationData->emailHeader = $notificationContent->emailHeader;
            $intimationData->intimationData->smsContent = $notificationContent->smsContent;
            $intimationData->intimationData->emailContent = $notificationContent->emailBody;
            $intimationData->intimationData->context = $notificationContent->context;
            $intimationData->intimationData->module = empty($notificationContent->module) ? Modules::ACADEMICS : $notificationContent->module;
            $intimationData->intimationData->dltId = $notificationContent->dltId;
            $intimationData->intimationData->intimationContext = $identifyingConstant;
            $intimationData->intimationData->addIntimationLog = true;
            $intimationData->intimationData->loggedInUserId = '0';
            $intimationData->intimationData->loggedInUserType = UserType::STAFF;
            $intimationData->intimationData->receiverTypeContext = $intimationReceiverTypeContext;
            $intimationData->intimationData->intimationModule = $intimationModule;
            $intimationData->intimationData->isScheduledIntimation = true;
            $this->sendBulkIntimationRecursive($intimationData, $studentList);
            // update intimation send status
            switch ($identifyingConstant) {
                case "V4_ATTENDANCE_AUTOMATIC_INTIMATION_FOR_ABSENTEES";
                    // fetch absentees student details of current date
                    $req = new \stdClass();
                    $date = date("Y-m-d");
                    $req->date = $date;
                    V4AttendanceService::getInstance()->updateIntimationSendStatus($req);
                    break;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * fetch all v4 notification contents
     *
     * @param String $id
     * @return Object || Array
     */
    private function fetchAllNotificationContents($id)
    {
        $cond = "";
        if (!empty($id)) {
            $cond = " AND id = '$id";
        }
        $sql = "SELECT id, label, description, context, email_subject as emailSubject, email_body as emailBody, dlt_id dltId, sms_content as smsContent, supported_tags as supportedTags, created_by FROM v4_notification_contents WHERE 1=1  $cond order by created_date desc";
        try {
            if ($id) {
                return $this->executeQueryForObject($sql);
            }
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * v4 send intimation recursively
     *
     * @param Object $intimationData
     * @param Array $allStudentList
     * @return void
     */
    private function sendBulkIntimationRecursive($intimationData, $allStudentList)
    {
        try {
            $studentDataList = array_slice($allStudentList, 0, 10);
            $req = new IntimationData();
            $req->intimationContext = $intimationData->intimationData->intimationContext;
            $req->addIntimationLog = $intimationData->intimationData->addIntimationLog;
            $req->loggedInUserId = $intimationData->intimationData->loggedInUserId;
            $req->loggedInUserType = $intimationData->intimationData->loggedInUserType;
            $req->receiverTypeContext = $intimationData->intimationData->receiverTypeContext;
            $req->intimationModule = $intimationData->intimationData->intimationModule;
            $req->isScheduledIntimation = $intimationData->intimationData->isScheduledIntimation == true;
            $req->recipientList = $studentDataList;
            $req->intimationProperties = new IntimationDataProperties();
            $req->intimationProperties->intimationTypes = $intimationData->intimationData->intimationTypes;
            $req->intimationProperties->recipients = $intimationData->intimationData->recipients;
            $req->intimationProperties->emailAttachments = $intimationData->intimationData->emailAttachments;
            $req->intimationProperties->emailSubject = $intimationData->intimationData->emailSubject;
            $req->intimationProperties->emailHeader = $intimationData->intimationData->emailHeader;
            $req->intimationProperties->smsContent = $intimationData->intimationData->smsContent;
            $req->intimationProperties->emailContent = $intimationData->intimationData->emailContent;
            $req->intimationProperties->context = $intimationData->intimationData->context;
            $req->intimationProperties->module = $intimationData->intimationData->module;
            $req->intimationProperties->dltId = $intimationData->intimationData->dltId;
            $emailContent = $intimationData->intimationData->emailContent;
            $smsContent = $intimationData->intimationData->smsContent;
            if (!str_contains($emailContent, "{{")) {
                // string contains does not contain any tag replaceable data
                $this->sendEmailIntimationBulk($req);
            }
            if (!str_contains($smsContent, "{{")) {
                // string contains does not contain any tag replaceable data
                $this->sendSmsIntimationBulk($req);
            }
            if (str_contains($emailContent, "{{") || str_contains($smsContent, "{{")) {
                foreach ($studentDataList as $studentDetails) {
                    $supportTags = new \stdClass();
                    array_walk($intimationData->intimationData->supportingTags,function($key,$value) use($studentDetails,$supportTags){
                        $supportTags->{$value} = $studentDetails->{$key};
                    });
                    $supportTags->currentDate =  date('d-m-Y');
                    $supportTags = (array) $supportTags;
                    $req->recipientList = [$studentDetails];
                    if (str_contains($emailContent, "{{")) {
                        $emailMessage = StringUtil::replace_tags($emailContent, $supportTags);
                        $req->intimationProperties->emailContent = $emailMessage;
                        $this->sendEmailIntimationBulk($req);
                    }
                    if (str_contains($smsContent, "{{")) {
                        $smsMessage = StringUtil::replace_tags($smsContent, $supportTags);
                        $req->intimationProperties->smsContent = $smsMessage;
                        $this->sendSmsIntimationBulk($req);
                    }
                }
            }
        } catch (\Exception $e) {
        }
        try {
            $allStudentList = array_slice($allStudentList, 10);
            if (!empty($allStudentList)) {
                $this->sendBulkIntimationRecursive($intimationData, $allStudentList);
            }
        } catch (\Exception $e) {
        }
    }
    /**
     * Send eMAIL intimation bulk
     *
     * @param IntimationData $intimationData
     * @return void
     */
    private function sendEmailIntimationBulk(IntimationData $intimationData)
    {
        try {
            /**
             * Send Email notifications
             */
            $emailCred = CommonService::getInstance()->getEmailConfByModule($intimationData->intimationProperties->module);
            if (in_array("EMAIL", $intimationData->intimationProperties->intimationTypes)) {
                foreach ($intimationData->recipientList as $recipient) {
                    $emailObj         = new Email();
                    $emailFrom        = new EmailFrom();
                    $emailFrom->email = $emailCred->email;
                    $emailFrom->name  = $intimationData->intimationProperties->emailHeader;
                    $emailTo        = new EmailTo();
                    $emailTo->email = $recipient->emailId;
                    $emailTo->name  = $recipient->name;
                    $emailObj->module = $intimationData->intimationProperties->module;
                    $emailObj->subject = $intimationData->intimationProperties->emailSubject;
                    $emailObj->body    = $intimationData->intimationProperties->emailContent;
                    $emailObj->from    = $emailFrom;
                    $emailObj->to      = $emailTo;
                    // $emailObj->ccList      = $COLLEGE_CC_LIST?json_decode($COLLEGE_CC_LIST):[];
                    try {
                        $emailObj->attachments = $intimationData->intimationProperties->emailAttachments;
                        AMSLogger::log_info($this->logger, Events::SEND_EMAIL_ASYNC, [
                            "emailObj" => $emailObj,
                            "IntimationData" => $intimationData,
                            "markedStaff" => new Staff(["id" => $GLOBALS['userId']]),
                            "status" => StatusConstants::SUCCESS
                        ]);
                        // CREATING INTIMATION LOG DTO
                        $isEmailAttachmentIncluded = count($emailObj->attachments) > 0 ? '1' : '0';
                        $v4IntimationLog = new V4IntimationLog();
                        $v4IntimationLog->userId = $recipient->intimationRecipientId;
                        $v4IntimationLog->userType = $recipient->intimationRecipientUserType;
                        $v4IntimationLog->receiverTypeContext = $intimationData->receiverTypeContext;
                        $v4IntimationLog->type = V4IntimationTypeConstants::EMAIL;
                        $v4IntimationLog->content = $emailObj->body;
                        $v4IntimationLog->status = V4IntimationLogStatusConstants::FAILED;
                        $v4IntimationLog->module = $intimationData->intimationModule;
                        $v4IntimationLog->context = $intimationData->intimationContext;
                        $v4IntimationLog->senderUserId = $intimationData->loggedInUserId;
                        $v4IntimationLog->senderUserType = $intimationData->loggedInUserType;
                        $v4IntimationLog->sendTime = date('Y-m-d H:i:s');
                        $v4IntimationLog->isScheduledIntimation = $intimationData->isScheduledIntimation;
                        $v4IntimationLog->createdBy = $intimationData->loggedInUserId;
                        $v4IntimationLog->extraDetails = new V4IntimationLogExtraDetails();
                        $v4IntimationLog->extraDetails->userEmailAtSendingTime = $emailTo->email;
                        $v4IntimationLog->extraDetails->isAttachmentIncluded = $isEmailAttachmentIncluded;
                        $sendSingleNotification = new SendSingleNotification();
                        $sendSingleNotification->type = SingleNotificationTypeConstant::EMAIL;
                        $sendSingleNotification->data = $emailObj;
                        NotificationService::getInstance()->sendSingleNotification($sendSingleNotification);
                        // AcademicIntimationUtil::sendEmailAsync($emailObj);
                        // SAVING INTIMATION LOG AFTER SENDING
                        if ($intimationData->addIntimationLog == true) {
                            $v4IntimationLog->status = V4IntimationLogStatusConstants::SUCCESS;
                            V4IntimationLogService::getInstance()->saveV4IntimationLog($v4IntimationLog);
                        }
                    } catch (\Exception $e) {
                        // SAVING INTIMATION LOG AFTER SENDING ON ERROR
                        if ($intimationData->addIntimationLog == true) {
                            $v4IntimationLog->extraDetails->errorCode = $e->getCode();
                            $v4IntimationLog->extraDetails->errorMessage = $e->getMessage();
                            V4IntimationLogService::getInstance()->saveV4IntimationLog($v4IntimationLog);
                        }
                        AMSLogger::log_error($this->logger, Events::SEND_EMAIL_ASYNC, [
                            "emailObj" => $emailObj,
                            "IntimationData" => $intimationData,
                            "markedStaff" => new Staff(["id" => $GLOBALS['userId']]),
                            "errorCode" => $e->getCode(),
                            "errorMessage" => $e->getMessage(),
                            "status" => StatusConstants::FAILURE
                        ]);
                    }
                }
            }
        } catch (\Exception $e) {
            // throw new AcademicException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Send SMS intimation for bulk students
     * 
     * THIS METHOD SHOULD ONLY BE CALLED WITH $intimationData->recientList CONTAINING LESS THAN 10 STUDENTS. SINCE INTIMATION LOGS ARE SAVED FOR THE STUDENTS IN THE $intimationData->recipientList INSIDE sendIntimationRecursive
     * 
     * sendIntimationRecursive METHOD SHOULD BE CHANGED TO RECURSIVELY SEND USING THE $intimationData->recientList RATHER THAN MOBILE NUMBER ARRAY
     * @param IntimationData $intimationData
     * @return void
     */
    private function sendSmsIntimationBulk(IntimationData $intimationData)
    {
        /**
         * Send SMS to array of recipients
         */
        $recipientMobileNo = array_filter(array_column($intimationData->recipientList, 'mobileNo'));
        try {
            if (in_array("SMS", $intimationData->intimationProperties->intimationTypes)) {
                $this->sendIntimationRecursive($recipientMobileNo, $intimationData);
            }
        } catch (\Exception $e) {
        }
    }
    /**
     * Recursive function to send SMS intimation
     * THIS METHOD SHOULD ONLY BE CALLED WITH $intimationData->recientList CONTAINING LESS THAN 10 STUDENTS. SINCE INTIMATION LOGS ARE SAVED FOR THE STUDENTS IN THE $intimationData->recipientList INSIDE sendIntimationRecursive
     * 
     * sendIntimationRecursive METHOD SHOULD BE CHANGED TO RECURSIVELY SEND USING THE $intimationData->recientList RATHER THAN MOBILE NUMBER ARRAY
     * @param Array $recipientMobileNo
     * @param IntimationData $intimationData
     * @return void
     */
    private function sendIntimationRecursive(array $recipientMobileNo, IntimationData $intimationData)
    {
        try {
            $phoneNumberList = array_slice($recipientMobileNo, 0, 10);
            
            // CREATING INTIMATION LOG DTO
            $v4IntimationLog = new V4IntimationLog();
            $v4IntimationLog->userId = '';
            $v4IntimationLog->userType = '';
            $v4IntimationLog->receiverTypeContext = $intimationData->receiverTypeContext;
            $v4IntimationLog->type = V4IntimationTypeConstants::SMS;
            $v4IntimationLog->status = V4IntimationLogStatusConstants::FAILED;
            $v4IntimationLog->module = $intimationData->intimationModule;
            $v4IntimationLog->context = $intimationData->intimationContext;
            $v4IntimationLog->senderUserId = $intimationData->loggedInUserId;
            $v4IntimationLog->senderUserType = $intimationData->loggedInUserType;
            $v4IntimationLog->sendTime = date('Y-m-d H:i:s');
            $v4IntimationLog->createdBy = $intimationData->loggedInUserId;
            $v4IntimationLog->isScheduledIntimation = $intimationData->isScheduledIntimation;
            $v4IntimationLog->extraDetails = new V4IntimationLogExtraDetails();
            $sms = new \stdClass();
            $sms->module = 'ALL';
            $sms->context = "ACADEMICS_INTIMATION";
            $sms->route = SMS::ROUTE_TRANSACTIONAL;
            $sms->message = $intimationData->intimationProperties->smsContent;
            $sms->mobileNos = $phoneNumberList;
            if (count($phoneNumberList) > 0) {
                SMSService::getInstance()->sendSMS($sms,$intimationData->intimationProperties->dltId);
                // AcademicIntimationUtil::sendSmsAsync($phoneNumberList, $intimationData->intimationProperties->smsContent, $intimationData->intimationProperties->dltId);
                AMSLogger::log_info($this->logger, Events::SEND_SMS_INTIMATION_BULK, [
                    "phoneNumberList" => $phoneNumberList,
                    "IntimationData" => $intimationData,
                    "markedStaff" => new Staff(["id" => $GLOBALS['userId']]),
                    "status" => StatusConstants::SUCCESS
                ]);
            }
            // SAVING INTIMATION LOG AFTER SENDING
            if ($intimationData->addIntimationLog == true) {
                foreach ($intimationData->recipientList as $recipient) {
                    $v4IntimationLog->userId = $recipient->intimationRecipientId;
                    $v4IntimationLog->userType = $recipient->intimationRecipientUserType;
                    $v4IntimationLog->content = $intimationData->intimationProperties->smsContent;
                    $v4IntimationLog->extraDetails->userMobileNoAtSendingTime = $recipient->mobileNo;
                    // SAVING INTIMATION LOG
                    $v4IntimationLog->status = V4IntimationLogStatusConstants::SUCCESS;
                    V4IntimationLogService::getInstance()->saveV4IntimationLog($v4IntimationLog);
                }
            }
            $recipientMobileNo = array_slice($recipientMobileNo, 10);
            if (!empty($recipientMobileNo)) {
                $this->sendIntimationRecursive($recipientMobileNo, $intimationData);
            }
        } catch (\Exception $e) {
            // SAVING INTIMATION LOG AFTER SENDING ERROR
            if ($intimationData->addIntimationLog == true) {
                foreach ($intimationData->recipientList as $recipient) {
                    $v4IntimationLog->status = V4IntimationLogStatusConstants::FAILED;
                    $v4IntimationLog->userId = $recipient->intimationRecipientId;
                    $v4IntimationLog->userType = $recipient->intimationRecipientUserType;
                    $v4IntimationLog->content = $intimationData->intimationProperties->smsContent;
                    $v4IntimationLog->extraDetails->userMobileNoAtSendingTime = $recipient->mobileNo;
                    $v4IntimationLog->extraDetails->errorCode = $e->getCode();
                    $v4IntimationLog->extraDetails->errorMessage = $e->getMessage();
                    V4IntimationLogService::getInstance()->saveV4IntimationLog($v4IntimationLog);
                }
            }
            AMSLogger::log_error($this->logger, Events::SEND_SMS_INTIMATION_BULK, [
                "phoneNumberList" => $phoneNumberList,
                "IntimationData" => $intimationData,
                "markedStaff" => new Staff(["id" => $GLOBALS['userId']]),
                "errorCode" => $e->getCode(),
                "errorMessage" => $e->getMessage(),
                "status" => StatusConstants::FAILURE
            ]);
            // throw new AcademicException($e->getCode(), $e->getMessage());
        }
    }
}