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 / 36
CRAP
0.00% covered (danger)
0.00%
0 / 664
PseudoSubjectPlanService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 36
24806.00
0.00% covered (danger)
0.00%
0 / 664
 __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 / 5
 createPseudoSubjectPlan
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 36
 addPseudoSubjectActualPlanCourseMaterials
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 addPseudoSubjectActualPlanDocuments
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 21
 createPseudoSubjectProposedPlan
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 41
 updateActualPlanDayAndSession
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 addPseudoSubjectProposedPlanCourseMaterials
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 updateProposedSubjectPlan
0.00% covered (danger)
0.00%
0 / 1
600.00
0.00% covered (danger)
0.00%
0 / 70
 getProposedPlanId
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 24
 deletePseudoSubjectActualPlanCourseMaterials
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 deletePseudoSubjectActualPlanCourseMaterialsByMaterialId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 deletePseudoSubjectProposedPlanCourseMaterials
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 deletePseudoSubjectProposedPlanCourseMaterialsByMaterialId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 getProposedPlanCourseMaterials
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 21
 getActualPlanCourseMaterials
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 21
 getWeeKWiseSubjectPlanDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 57
 addNewActualPlanVideoMaterial
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 addNewProposedPlanVideoMaterial
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 getActualPlanVideoMaterials
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getProposedPlanVideoMaterials
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 deleteActualPlan
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 28
 deleteAllActualPlanCourseMaterialsRelation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 deleteAllActualPlanVideoMaterialsRelation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getAllActualPlanCourseMaterialIds
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getAllActualPlanVideoMaterials
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 deleteProposedPlan
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 29
 deleteAllProposedPlanCourseMaterialsRelation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 deleteAllProposedPlanVideoMaterialsRelation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getAllProposedPlanCourseMaterialIds
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 removeProposedPlanFromActualPlan
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getAllProposedPlanVideoMaterials
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getSubjectPlansByRequest
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 24
 getProposedSubjectPlanDetailsByPseudoSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getSubjectPlan
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
<?php
namespace com\linways\core\ams\professional\service;
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\mapper\PseudoSubjectPlanServiceMapper;
use com\linways\core\ams\professional\request\AddNewActualPlanMaterialRequest;
use com\linways\core\ams\professional\request\AddNewProposedPlanMaterialRequest;
use com\linways\core\ams\professional\request\CreatePseudoSubjectPlanRequest;
use com\linways\core\ams\professional\request\CreatePseudoSubjectProposedPlanRequest;
use com\linways\core\ams\professional\request\DeleteActualPlanRequest;
use com\linways\core\ams\professional\request\DeleteCourseMaterialRequest;
use com\linways\core\ams\professional\request\DeleteProposedPlanRequest;
use com\linways\core\ams\professional\request\GetPreSignedUrlRequest;
use com\linways\core\ams\professional\request\UpdateProposedPseudoSubjectPlanRequest;
/**
 *
 * @author jithinvijayan
 * @Date 26/03/20
 */
class PseudoSubjectPlanService extends BaseService
{
    /**
     * Presence of a static member variable
     *
     * @var null
     */
    private static $_instance = null;
    /**
     * Mapper variable
     * @var array
     */
    private $mapper = [];
    /**
     * Initialise mapper, logger, hooks here
     *
     * ReportGenderService constructor.
     */
    private function __construct()
    {
        $this->mapper = PseudoSubjectPlanServiceMapper::getInstance()->getMapper();
    }
    /**
     * Prevent any object or instance of that class to be cloned
     */
    private function __clone()
    {
    }
    /**
     * Have a single globally accessible static method
     *
     * @return PseudoSubjectPlanService|null
     */
    public static function getInstance()
    {
        if (!is_object(self::$_instance))
            self::$_instance = new self ();
        return self::$_instance;
    }
    /**
     * creating actual pseudo subject plan
     *
     * @param CreatePseudoSubjectPlanRequest $request
     * @return Object|integer
     * @throws ProfessionalException
     */
    public function createPseudoSubjectPlan(CreatePseudoSubjectPlanRequest $request)
    {
        $subjectPlanId = null;
        $request = $this->realEscapeObject($request);
        if (empty($request->topicName)) {
            throw new ProfessionalException(ProfessionalException::INVALID_TOPIC, "Invalid subject plan topic name given");
        }
        if (empty($request->pseudoSubjectId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PSEUDO_SUBJECT_ID, "Invalid pseudo subject details given");
        }
        if (empty($request->module)) {
            throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_MODULE, "Invalid module details given");
        }
        if (empty($request->hour)) {
            throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_HOUR, "Invalid hour details given");
        }
        $enabledDayOrder = CommonService::getInstance()->getSettings(SettingsConstents::SUBJECT_PLAN_SETTINGS, SettingsConstents::SUBJECT_PLAN_DAY_ORDER_INCLUDE);
        if (!empty($enabledDayOrder)) {
            if (empty($request->day)) {
                throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_DAY_ORDER, "Invalid day order details given");
            }
        }
        $sql = "INSERT INTO ps_subjectplan(date, pssId, topicName, topicDesc, isCovered, isImportant, hour, module, mode,
                           proposed_topicID,day,session,created_by,updated_by,created_date,updated_date,modeOfeLearning)
                VALUES ('$request->startUnixTime', $request->pseudoSubjectId, '$request->topicName', '$request->description',
                        $request->portionStatus$request->isImportant$request->hour ,$request->module, '$request->mode',
                        '$request->proposedPlanId','$request->day','$request->session',$request->createdBy,$request->updatedBy,
                        UTC_TIMESTAMP(), UTC_TIMESTAMP(),'$request->eLearning');";
        try {
            $subjectPlanId = $this->executeQueryForObject($sql, true);
            if (!empty($request->courseMaterialIds) && count($request->courseMaterialIds))
                $this->addPseudoSubjectActualPlanCourseMaterials($subjectPlanId, $request);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectPlanId;
    }
    /**
     * adding course materials to the actual pseudo subject plan
     *
     * @param $actualPlanId
     * @param CreatePseudoSubjectPlanRequest $request
     * @throws ProfessionalException
     */
    private function addPseudoSubjectActualPlanCourseMaterials($actualPlanId, CreatePseudoSubjectPlanRequest $request)
    {
        $sql = "INSERT INTO ps_actual_plan_course_materials (actual_plan_id, course_material_id, created_by, updated_by,
                 created_date, updated_date) VALUES ";
        foreach ($request->courseMaterialIds as $id) {
            $sql .= "($actualPlanId,'$id',$request->createdBy,$request->updatedBy,UTC_TIMESTAMP(),UTC_TIMESTAMP()),";
        }
        $sql = rtrim($sql, ",");
        try {
            $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * adding course materials to the actual pseudo subject plan
     *
     * @param $actualPlanId
     * @param CreatePseudoSubjectPlanRequest $request
     * @throws ProfessionalException
     */
    public function addPseudoSubjectActualPlanDocuments($actualPlanId, CreatePseudoSubjectPlanRequest $request)
    {
        $actualPlanId = (int)$this->realEscapeString($actualPlanId);
        $request = $this->realEscapeObject($request);
        if (empty($actualPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_ACTUAL_PLAN_ID, "Invalid actual plan details given");
        }
        if (empty($request->courseMaterialIds) || !count($request->courseMaterialIds)) {
            throw new ProfessionalException(ProfessionalException::INVALID_DOCUMENT_IDS, "Invalid document details given");
        }
        $sql = "INSERT INTO ps_actual_plan_course_materials (actual_plan_id, course_material_id, created_by, updated_by,
                 created_date, updated_date) VALUES ";
        foreach ($request->courseMaterialIds as $id) {
            $sql .= "($actualPlanId,'$id',$request->createdBy,$request->updatedBy,UTC_TIMESTAMP(),UTC_TIMESTAMP()),";
        }
        $sql = rtrim($sql, ",");
        try {
            $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Creating pseudo subject proposed plan
     *
     * @param CreatePseudoSubjectProposedPlanRequest $request
     * @return Object|integer
     * @throws ProfessionalException
     * @author Jithin Vijayan
     */
    public function createPseudoSubjectProposedPlan(CreatePseudoSubjectProposedPlanRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $proposedPlanId = "";
        if (empty($request->topicName)) {
            throw new ProfessionalException(ProfessionalException::INVALID_TOPIC, "Invalid subject plan topic name given");
        }
        if (empty($request->pseudoSubjectId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PSEUDO_SUBJECT_ID, "Invalid pseudo subject details given");
        }
        if (empty($request->module)) {
            throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_MODULE, "Invalid module details given");
        }
        if (empty($request->hour) && empty($request->session)) {
            throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_HOUR, "Invalid hour/session details given");
        }
        $request->content = html_entity_decode($request->content);
        
        if($request->content)
        {
            $sql = "INSERT INTO subjectplan_ps_proposed(date, pssId, topicName, topicDesc, isCovered, isImportant, hour, module,
                    day,session,mode,pedagogy,created_by,updated_by,created_date,updated_date,content,units)
                    VALUES ('$request->startUnixTime', $request->pseudoSubjectId, '$request->topicName', '$request->description',
                            '0', '0', $request->hour$request->module,'$request->day','$request->session','$request->mode',
                            '$request->pedagogy',$request->createdBy,$request->updatedBy,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'$request->content','$request->units'); ";
        }
        else
        {
            $sql = "INSERT INTO subjectplan_ps_proposed(date, pssId, topicName, topicDesc, isCovered, isImportant, hour, module,
                day,session,mode,pedagogy,created_by,updated_by,created_date,updated_date,units)
                VALUES ('$request->startUnixTime', $request->pseudoSubjectId, '$request->topicName', '$request->description',
                        '0', '0', $request->hour$request->module,'$request->day','$request->session','$request->mode',
                        '$request->pedagogy',$request->createdBy,$request->updatedBy,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'$request->units'); ";
        }
        try {
            $proposedPlanId = $this->executeQueryForObject($sql, true);
            /**
             * TODO: May be useful
             * I dont know the logic of the below commented function. If mysql triggers is present in the corresponding tables,
             * you can uncomment this function call else you can remove this function call
             */
//            $this->updateActualPlanDayAndSession($request);
            if (!empty($request->courseMaterialIds) && count($request->courseMaterialIds))
                $this->addPseudoSubjectProposedPlanCourseMaterials($proposedPlanId, $request);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $proposedPlanId;
    }
    /**
     * Updating actual plan mode and session
     *
     * @param CreatePseudoSubjectProposedPlanRequest $request
     * @throws ProfessionalException
     */
    public function updateActualPlanDayAndSession(CreatePseudoSubjectProposedPlanRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->proposedPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PROPOSED_PLAN_ID, "Invalid proposed plan details given");
        }
        $sql = "UPDATE subjectplan_ps_proposed SET  mode = '$request->mode', session='$request->session',
                updated_by=$request->updatedBy,updated_date =UTC_TIMESTAMP()";
        if (!empty($request->day)) {
            $sql .= " day='$request->day'";
        }
        $sql .= " WHERE topicID =$request->proposedPlanId ";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * adding course materials to the actual pseudo subject plan
     *
     * @param $proposedPlanId
     * @param CreatePseudoSubjectProposedPlanRequest $request
     * @throws ProfessionalException
     */
    private function addPseudoSubjectProposedPlanCourseMaterials($proposedPlanId, CreatePseudoSubjectProposedPlanRequest $request)
    {
        $sql = "INSERT INTO ps_proposed_plan_course_materials (proposed_plan_id, course_material_id, created_by, updated_by,
                 created_date, updated_date) VALUES ";
        foreach ($request->courseMaterialIds as $id) {
            $sql .= "($proposedPlanId,'$id',$request->createdBy,$request->updatedBy,UTC_TIMESTAMP(),UTC_TIMESTAMP()),";
        }
        $sql = rtrim($sql, ",");
        try {
            $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Updating proposed plan details
     *
     * @param UpdateProposedPseudoSubjectPlanRequest $request
     * @throws ProfessionalException
     */
    public function updateProposedSubjectPlan(UpdateProposedPseudoSubjectPlanRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->id)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PROPOSED_PLAN_ID, "Invalid proposed plan details given");
        }
        if (empty($request->topicName)) {
            throw new ProfessionalException(ProfessionalException::INVALID_TOPIC, "Invalid subject plan topic name given");
        }
        if (empty($request->pseudoSubjectId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PSEUDO_SUBJECT_ID, "Invalid pseudo subject details given");
        }
        if (empty($request->module)) {
            throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_MODULE, "Invalid module details given");
        }
        if (empty($request->hour) && empty($request->session)) {
            throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_HOUR, "Invalid hour details given");
        }
        $enabledDayOrder = CommonService::getInstance()->getSettings(SettingsConstents::SUBJECT_PLAN_SETTINGS, SettingsConstents::SUBJECT_PLAN_DAY_ORDER_INCLUDE);
        if (!empty($enabledDayOrder)) {
            if (empty($request->day)) {
                throw new ProfessionalException(ProfessionalException::INVALID_SUBJECT_PLAN_DAY_ORDER, "Invalid day order details given");
            }
        }
        if($request->portionStatus=='undefined' || $request->portionStatus=='null' || $request->portionStatus=='')
        {
            $request->portionStatus=0;
        }
        if($request->units=='undefined' || $request->units=='null' || $request->units=='')
        {
            $request->units=0;
        }
        if($request->day=='undefined' || $request->day=='null' ||  $request->day=='')
        {
            $request->day=0;
        }
        if($request->session=='undefined' || $request->session=='null' || $request->session=='')
        {
            $request->session=0;
        }
        $request->content =html_entity_decode($request->content);
        $sql = "UPDATE subjectplan_ps_proposed
                SET topicName='$request->topicName',
                    topicDesc='$request->description',
                    isCovered='$request->portionStatus',
                    isImportant=$request->isImportant,
                    units=$request->units,
                    hour='$request->hour',
                    module='$request->module',
                    pedagogy = '$request->pedagogy',
                    date='$request->startUnixTime',
                    mode='$request->mode',
                    day='$request->day',
                    session='$request->session',
                    updated_date = UTC_TIMESTAMP(),
                    updated_by =$request->updatedBy,
                    content='$request->content'
                    WHERE topicID=$request->id AND pssId=$request->pseudoSubjectId";
        try {
            $this->executeQuery($sql);
            if (!empty($request->courseMaterialIds) && count($request->courseMaterialIds)) {
                $courseMaterialRequest = new CreatePseudoSubjectProposedPlanRequest();
                $courseMaterialRequest->courseMaterialIds = $request->courseMaterialIds;
                $courseMaterialRequest->createdBy = $request->createdBy;
                $courseMaterialRequest->updatedBy = $request->updatedBy;
                $this->addPseudoSubjectProposedPlanCourseMaterials($request->id, $courseMaterialRequest);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param string $unixStartTime
     * @param integer $pseudoSubjectId
     * @param integer $hour
     * @param integer $module
     * @param string $topicName
     * @return mixed
     * @throws ProfessionalException
     */
    public function getProposedPlanId($unixStartTime, $pseudoSubjectId, $hour, $module, $topicName,$session=NULL)
    {
        if (empty($pseudoSubjectId) || (empty($hour) && empty($session)) || empty($module) || empty($topicName)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid request sent");
        }
        if($session){
            $sql = "SELECT topicID FROM subjectplan_ps_proposed
            WHERE date='$unixStartTime'
            AND pssId='$pseudoSubjectId' AND session='$session' AND module='$module' AND topicName='$topicName'";
        }
        else{
            if(empty($unixStartTime))
            {
                throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid request sent Eg: Invalid Date");
            }
            $sql = "SELECT topicID FROM subjectplan_ps_proposed
            WHERE date='$unixStartTime'
            AND pssId='$pseudoSubjectId' AND hour='$hour' AND module='$module' AND topicName='$topicName'";
        }
        try {
            return $this->executeQueryForObject($sql)->topicID;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting course materials from actual plan
     *
     * @param integer $actualPlanId
     * @param string $documentId
     * @throws ProfessionalException
     */
    public function deletePseudoSubjectActualPlanCourseMaterials($actualPlanId, $documentId)
    {
        $actualPlanId = (int)$this->realEscapeString($actualPlanId);
        $documentId = $this->realEscapeString($documentId);
        if (empty($actualPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_ACTUAL_PLAN_ID, "Invalid actual plan details given");
        }
        if (empty($documentId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_DOCUMENT_ID, "Invalid course material details given");
        }
        $sql = "DELETE FROM ps_actual_plan_course_materials
                WHERE actual_plan_id =$actualPlanId
                AND course_material_id ='$documentId'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting course materials from actual plan
     *
     * @param string $documentId
     * @throws ProfessionalException
     */
    public function deletePseudoSubjectActualPlanCourseMaterialsByMaterialId($documentId)
    {
        $documentId = $this->realEscapeString($documentId);
        if (empty($documentId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_DOCUMENT_ID, "Invalid course material details given");
        }
        $sql = "DELETE FROM ps_actual_plan_course_materials
                WHERE course_material_id ='$documentId'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting course materials from proposed plan
     *
     * @param integer $proposedPlanId
     * @param string $documentId
     * @throws ProfessionalException
     */
    public function deletePseudoSubjectProposedPlanCourseMaterials($proposedPlanId, $documentId)
    {
        $proposedPlanId = (int)$this->realEscapeString($proposedPlanId);
        $documentId = $this->realEscapeString($documentId);
        if (empty($proposedPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PROPOSED_PLAN_ID, "Invalid proposed plan details given");
        }
        if (empty($documentId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_DOCUMENT_ID, "Invalid course material details given");
        }
        $sql = "DELETE FROM ps_proposed_plan_course_materials
                WHERE proposed_plan_id =$proposedPlanId
                AND course_material_id ='$documentId'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting course materials from proposed plan
     *
     * @param string $documentId
     * @throws ProfessionalException
     */
    public function deletePseudoSubjectProposedPlanCourseMaterialsByMaterialId($documentId)
    {
        $documentId = $this->realEscapeString($documentId);
        if (empty($documentId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_DOCUMENT_ID, "Invalid course material details given");
        }
        $sql = "DELETE FROM ps_proposed_plan_course_materials
                WHERE course_material_id ='$documentId'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $proposedId
     * @return array|object
     * @throws ProfessionalException
     */
    public function getProposedPlanCourseMaterials($proposedId)
    {
        $courseMaterialDetails = [];
        $sql = "SELECT cm.id, cm.name, cm.topic,cm.description, cm.resource_id as resourceId
                FROM ps_proposed_plan_course_materials pppcm
                INNER JOIN course_materials cm ON cm.id = pppcm.course_material_id
                WHERE pppcm.proposed_plan_id = $proposedId";
        try {
            $courseMaterialDetails = $this->executeQueryForList($sql);
            foreach ($courseMaterialDetails as $materialDetail) {
                $request = new GetPreSignedUrlRequest();
                $request->resourceId = $materialDetail->resourceId;
                $request->secretKey = getenv("AWS_CLIENT_SECRET_KEY");
                $request->accessKey = getenv("AWS_ACCESS_KEY");
                $url = ResourceService::getInstance()->getPreSignedUrlByResourceId($request);
                $materialDetail->url = $url->url;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $courseMaterialDetails;
    }
    /**
     * Returns all course materials assigned to actual plans
     *
     * @param int $actualId
     * @return array|object $courseMatDetails
     * @throws ProfessionalException
     */
    public function getActualPlanCourseMaterials($actualId)
    {
        $courseMaterialDetails = [];
        $sql = "SELECT cm.id, cm.name, cm.topic,cm.description, cm.resource_id as resourceId
                FROM ps_actual_plan_course_materials papcm
                INNER JOIN course_materials cm ON cm.id = papcm.course_material_id
                WHERE papcm.actual_plan_id = $actualId";
        try {
            $courseMaterialDetails = $this->executeQueryForList($sql);
            foreach ($courseMaterialDetails as $materialDetail) {
                $request = new GetPreSignedUrlRequest();
                $request->resourceId = $materialDetail->resourceId;
                $request->secretKey = getenv("AWS_CLIENT_SECRET_KEY");
                $request->accessKey = getenv("AWS_ACCESS_KEY");
                $url = ResourceService::getInstance()->getPreSignedUrlByResourceId($request);
                $materialDetail->url = $url->url;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $courseMaterialDetails;
    }
    /**
     * @param $pseudoSubjectId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getWeeKWiseSubjectPlanDetails($pseudoSubjectId)
    {
        $pseudoSubjectId = $this->realEscapeObject($pseudoSubjectId);
        $subjectPlans = null;
        $sql = "SELECT DISTINCT sp.topicID, CONCAT(FROM_UNIXTIME(sp.date, '%Y'),WEEK(FROM_UNIXTIME(sp.date, '%Y-%m-%d'),1)) as yearWeek,
                FROM_UNIXTIME(sp.date, '%Y-%m-%d') as subjectPlanDate, sp.topicName, sp.topicDesc, sp.isImportant, sp.hour, sp.module,
                sp.pedagogy, subp.isCovered, sp.session, sp.content,
                cm.id as material_id, cm.resource_id, cm.name as material_name, cm.description as material_description,
                cm1.id as proposed_material_id, cm1.resource_id as proposed_resource_id, cm1.name as proposed_material_name,
                cm1.description as proposed_material_description,
                cvm.id as actual_video_material_id,cvm.title as actual_video_material_name,lr.path as actual_video_material_url,
                cvm1.id as proposed_video_material_id,cvm1.title as proposed_video_material_name,lr1.path as proposed_video_material_url,
                temp.finalStatus,sp.units
                FROM subjectplan_ps_proposed sp
                LEFT JOIN ps_subjectplan subp ON sp.topicID=subp.proposed_topicID
                LEFT JOIN ps_actual_plan_course_materials map ON map.actual_plan_id=subp.topicID
                LEFT JOIN course_materials cm ON cm.id=map.course_material_id AND cm.is_active=1
                LEFT JOIN ps_proposed_plan_course_materials mpp ON mpp.proposed_plan_id=sp.topicID
                LEFT JOIN course_materials cm1 ON  cm1.id=mpp.course_material_id AND cm.is_active=1
                LEFT JOIN ps_proposed_plan_video_materials pppvm on sp.topicID = pppvm.ps_proposed_plan_id
                LEFT JOIN course_video_materials cvm1 ON pppvm.video_repository_id = cvm1.id
                LEFT JOIN lin_resource lr1 ON lr1.id = cvm1.resource_id
                LEFT JOIN ps_actual_plan_video_materials papvm on subp.topicID = papvm.ps_actual_plan_id
                LEFT JOIN course_video_materials cvm on papvm.video_repository_id = cvm.id
                LEFT JOIN lin_resource lr ON lr.id = cvm.resource_id
                LEFT JOIN  (
                    SELECT MAX(isCovered) as finalStatus,proposed_topicID
                    FROM ps_subjectplan WHERE pssId = $pseudoSubjectId
                ) AS temp ON temp.proposed_topicID=sp.topicID
                WHERE sp.pssId=$pseudoSubjectId
                ORDER BY sp.date, WEEK(FROM_UNIXTIME(sp.date, '%Y-%m-%d'),1), sp.hour desc";
        try {
            $subjectPlans = $this->executeQueryForList($sql, $this->mapper[PseudoSubjectPlanServiceMapper::GET_WEEK_WISE_SUBJECT_PLAN_DETAILS]);
            foreach ($subjectPlans as $subjectPlan) {
                foreach ($subjectPlan->subjectPlan as $plan) {
                    foreach ($plan->actualPlanCourseMaterials as $material) {
                        $request = new GetPreSignedUrlRequest();
                        $request->resourceId = $material->resourceId;
                        $request->secretKey = getenv("AWS_CLIENT_SECRET_KEY");
                        $request->accessKey = getenv("AWS_ACCESS_KEY");
                        $url = ResourceService::getInstance()->getPreSignedUrlByResourceId($request);
                        $material->url = $url->url;
                    }
                    foreach ($plan->proposedPlanCourseMaterials as $material) {
                        $request = new GetPreSignedUrlRequest();
                        $request->resourceId = $material->resourceId;
                        $request->secretKey = getenv("AWS_CLIENT_SECRET_KEY");
                        $request->accessKey = getenv("AWS_ACCESS_KEY");
                        $url = ResourceService::getInstance()->getPreSignedUrlByResourceId($request);
                        $material->url = $url->url;
                    }
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectPlans;
    }
    /**
     * @param AddNewActualPlanMaterialRequest $request
     * @return Object|integer
     * @throws ProfessionalException
     */
    public function addNewActualPlanVideoMaterial(AddNewActualPlanMaterialRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->materialId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_BATCH_VIDEO_REPOSITORY_ID, "Invalid video repository details given");
        }
        if (empty($request->actualPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_ACTUAL_PLAN_ID, "Invalid actual plan details given");
        }
        $sql = "INSERT INTO ps_actual_plan_video_materials (ps_actual_plan_id, video_repository_id,
                created_by, created_date, updated_by, updated_date)
                VALUES ($request->actualPlanId,'$request->materialId',$request->createdBy,UTC_TIMESTAMP(),
                        $request->updatedBy,UTC_TIMESTAMP())";
        try {
            return $this->executeQueryForObject($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param AddNewProposedPlanMaterialRequest $request
     * @return Object|integer
     * @throws ProfessionalException
     */
    public function addNewProposedPlanVideoMaterial(AddNewProposedPlanMaterialRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->materialId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_BATCH_VIDEO_REPOSITORY_ID, "Invalid video repository details given");
        }
        if (empty($request->proposedPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PROPOSED_PLAN_ID, "Invalid proposed plan details given");
        }
        $sql = "INSERT INTO ps_proposed_plan_video_materials (ps_proposed_plan_id, video_repository_id,
                created_by, created_date, updated_by, updated_date)
                VALUES ($request->proposedPlanId,'$request->materialId',$request->createdBy,UTC_TIMESTAMP(),
                        $request->updatedBy,UTC_TIMESTAMP())";
        try {
            return $this->executeQueryForObject($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $actualPlanId
     * @return Object|array
     * @throws ProfessionalException
     */
    public function getActualPlanVideoMaterials($actualPlanId)
    {
        $actualPlanId = (int)$this->realEscapeString($actualPlanId);
        if (empty($actualPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_ACTUAL_PLAN_ID, "Invalid actual plan details given");
        }
        $sql = "SELECT cvm.id,cvm.title as name,lr.path as url,cvm.description
                FROM ps_actual_plan_video_materials papvm
                INNER JOIN course_video_materials cvm on papvm.video_repository_id = cvm.id
                INNER JOIN lin_resource lr ON lr.id = cvm.resource_id
                WHERE ps_actual_plan_id = $actualPlanId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $proposedPlanId
     * @return Object|arra
     * @throws ProfessionalException
     */
    public function getProposedPlanVideoMaterials($proposedPlanId)
    {
        $proposedPlanId = (int)$this->realEscapeString($proposedPlanId);
        if (empty($proposedPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PROPOSED_PLAN_ID, "Invalid proposed plan details given");
        }
        $sql = "SELECT cvm.id,cvm.title as name,lr.path as url,cvm.description
                FROM ps_proposed_plan_video_materials pppvm
                INNER JOIN course_video_materials cvm on pppvm.video_repository_id = cvm.id
                INNER JOIN lin_resource lr ON lr.id = cvm.resource_id
                WHERE ps_proposed_plan_id = $proposedPlanId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param DeleteActualPlanRequest $request
     * @throws ProfessionalException
     */
    public function deleteActualPlan(DeleteActualPlanRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->actualPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_ACTUAL_PLAN_ID, "Invalid actual plan details given");
        }
        try {
            if ($request->isDeleteCourseMaterials) {
                $courseMaterials = $this->getAllActualPlanCourseMaterialIds($request->actualPlanId);
                foreach ($courseMaterials as $material) {
                    $deleteRequest = new DeleteCourseMaterialRequest();
                    $deleteRequest->documentId = $material->id;
                    $deleteRequest->staffId = $request->staffId;
                    CourseMaterialService::getInstance()->deleteCourseMaterial($deleteRequest);
                }
                $videoMaterials = $this->getAllActualPlanVideoMaterials($request->actualPlanId);
                foreach ($videoMaterials as $material) {
                    VideoRepositoryService::getInstance()->deleteVideoMaterial($material->id);
                }
            } else {
                $this->deleteAllActualPlanCourseMaterialsRelation($request->actualPlanId);
                $this->deleteAllActualPlanVideoMaterialsRelation($request->actualPlanId);
            }
            $sql = "DELETE FROM ps_subjectplan WHERE topicID = $request->actualPlanId";
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting actual plan course material relation
     *
     * @param $actualPlanId
     * @throws ProfessionalException
     */
    private function deleteAllActualPlanCourseMaterialsRelation($actualPlanId)
    {
        $sql = "DELETE FROM ps_actual_plan_course_materials WHERE actual_plan_id = $actualPlanId";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting actual plan video material relation
     *
     * @param $actualPlanId
     * @throws ProfessionalException
     */
    private function deleteAllActualPlanVideoMaterialsRelation($actualPlanId)
    {
        $sql = "DELETE FROM ps_actual_plan_video_materials WHERE ps_actual_plan_id = $actualPlanId";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $actualPlanId
     * @return Object
     * @throws ProfessionalException
     */
    private function getAllActualPlanCourseMaterialIds($actualPlanId)
    {
        $sql = "SELECT course_material_id as id FROM ps_actual_plan_course_materials
                WHERE actual_plan_id =$actualPlanId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $actualPlanId
     * @return Object
     * @throws ProfessionalException
     */
    private function getAllActualPlanVideoMaterials($actualPlanId)
    {
        $sql = "SELECT video_repository_id as id
                FROM ps_actual_plan_video_materials
                WHERE ps_actual_plan_id  =$actualPlanId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param DeleteProposedPlanRequest $request
     * @throws ProfessionalException
     */
    public function deleteProposedPlan(DeleteProposedPlanRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->proposedPlanId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_PROPOSED_PLAN_ID, "Invalid proposed plan details given");
        }
        try {
            if ($request->isDeleteCourseMaterials) {
                $courseMaterials = $this->getAllProposedPlanCourseMaterialIds($request->proposedPlanId);
                foreach ($courseMaterials as $material) {
                    $deleteRequest = new DeleteCourseMaterialRequest();
                    $deleteRequest->documentId = $material->id;
                    $deleteRequest->staffId = $request->staffId;
                    CourseMaterialService::getInstance()->deleteCourseMaterial($deleteRequest);
                }
                $videoMaterials = $this->getAllProposedPlanVideoMaterials($request->proposedPlanId);
                foreach ($videoMaterials as $material) {
                    VideoRepositoryService::getInstance()->deleteVideoMaterial($material->id);
                }
            } else {
                $this->deleteAllProposedPlanCourseMaterialsRelation($request->proposedPlanId);
                $this->deleteAllProposedPlanVideoMaterialsRelation($request->proposedPlanId);
            }
            $this->removeProposedPlanFromActualPlan($request->proposedPlanId);
            $sql = "DELETE FROM subjectplan_ps_proposed WHERE topicID = $request->proposedPlanId";
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting all proposed plan course materials relation
     *
     * @param $proposedPlanId
     * @throws ProfessionalException
     */
    private function deleteAllProposedPlanCourseMaterialsRelation($proposedPlanId)
    {
        $sql = "DELETE FROM ps_proposed_plan_course_materials WHERE proposed_plan_id = $proposedPlanId";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Deleting proposed plan video material relation
     *
     * @param $proposedPlanId
     * @throws ProfessionalException
     */
    private function deleteAllProposedPlanVideoMaterialsRelation($proposedPlanId)
    {
        $sql = "DELETE FROM ps_proposed_plan_video_materials WHERE ps_proposed_plan_id = $proposedPlanId";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $actualPlanId
     * @return Object
     * @throws ProfessionalException
     */
    private function getAllProposedPlanCourseMaterialIds($actualPlanId)
    {
        $sql = "SELECT course_material_id as id FROM ps_proposed_plan_course_materials
                WHERE proposed_plan_id =$actualPlanId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $proposedPlanId
     * @throws ProfessionalException
     */
    private function removeProposedPlanFromActualPlan($proposedPlanId)
    {
        $sql = "UPDATE ps_subjectplan SET proposed_topicID = NULL
                WHERE proposed_topicID=$proposedPlanId";
        try {
            $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $proposedPlanId
     * @return Object
     * @throws ProfessionalException
     */
    private function getAllProposedPlanVideoMaterials($proposedPlanId)
    {
        $sql = "SELECT video_repository_id as id
                FROM ps_proposed_plan_video_materials
                WHERE ps_proposed_plan_id  =$proposedPlanId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getSubjectPlansByRequest($request){
        $where = [];
        if ($request->fromDate && $request->toDate) {
            $fromDate = date("Y-m-d", strtotime($request->fromDate));
            $toDate = date("Y-m-d", strtotime($request->toDate));
            $where[] = "spp.date between unix_timestamp('$fromDate') and unix_timestamp('$toDate')";
        } else if ($toDate) {
            $toDate = date("Y-m-d", strtotime($request->toDate));
            $where[] = "spp.date <= unix_timestamp('$toDate')";
        } else if ($request->fromDate) {
            $fromDate = date("Y-m-d", strtotime($request->fromDate));
            $where[] = "spp.date >= unix_timestamp('$fromDate')";
        }
        $request->pseudoSubjectId?$where[] = " spp.pssId = $request->pseudoSubjectId ":"";
        $sql = "SELECT FROM_UNIXTIME(spp.date, '%Y-%m-%d') AS sspDate,FROM_UNIXTIME(sp.date, '%Y-%m-%d') AS spDate,spp.topicID as proposedPlanTopicID,spp.topicName as proposedPlanTopicName,spp.approve,spp.isImportant,spp.hour as proposedPlanHour,spp.module as proposedPlanModule,spp.content,sp.topicID,sp.topicName,sp.topicDesc,sp.isImportant,sp.isCovered,sp.hour,sp.module,spp.verify,spp.session,spp.oe_exam_id as onlineExamId,spp.mode as proposedPlanMode,spp.pedagogy as proposedPlanPedagogy
        FROM subjectplan_ps_proposed spp
        LEFT JOIN ps_subjectplan sp ON sp.pssId = spp.pssId AND sp.proposed_topicID = spp.topicID
        ".($where?" WHERE ".implode(' AND ',$where):"")." ORDER BY spp.date,spp.hour;";
        try {
            $result = $this->executeQueryForList($sql);
            return CommonService::getInstance()->htmlEntityDecodeArrayOfObjects($result);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get all proposed subject plans by pueudo subject id
     * @param Integer $sbsId
     * @return Array $subjectplanProposed
     */
    public function getProposedSubjectPlanDetailsByPseudoSubjectId($psudeoSubjectId)
    {
        $psudeoSubjectId = (int)$this->realEscapeString($psudeoSubjectId);
        $subjectplanProposed = [];
        $sql = "SELECT topicID, date,FROM_UNIXTIME(date, '%Y-%m-%d') as planDate,pssId, topicName, topicDesc, isCovered, isImportant, hour, module, pedagogy, mode, day, session,content
            FROM subjectplan_ps_proposed
            where pssId = '".$psudeoSubjectId."'
            ORDER BY date ASC;";
        try {
            $subjectplanProposed = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectplanProposed;
    }
    /**
     *  get actual and proposed plan by subject
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSubjectPlan($subjectPlanRequest)
    {
        $subjectPlanRequest = $this->realEscapeObject($subjectPlanRequest);
        $subjectPlanList = [];
        $sql = "SELECT DISTINCT sp.topicID, sp.topicName, sp.module, sub.isCovered, sub.hour as actualHour, sp.hour as proposedHour, FROM_UNIXTIME(sp.date, '%Y-%m-%d') as proposedDate, sp.session,sp.content".($subjectPlanRequest->needActualPlanId?',sub.topicID as actual_plan_topic_id':',null as actual_plan_topic_id')." FROM subjectplan_ps_proposed sp 
        LEFT JOIN ps_subjectplan sub ON sp.topicID = sub.proposed_topicID AND sub.pssId = sp.pssId AND FROM_UNIXTIME(sub.date, '%Y-%m-%d') = '" . date('Y-m-d', strtotime($subjectPlanRequest->date)) . "' 
        WHERE sp.pssId = '".$subjectPlanRequest->pseudoSubjectId."' AND sp.topicID NOT IN (SELECT proposed_topicID FROM ps_subjectplan WHERE pssId = '".$subjectPlanRequest->pseudoSubjectId."' AND FROM_UNIXTIME(date, '%Y-%m-%d') != '" . date('Y-m-d', strtotime($subjectPlanRequest->date)) . "' AND isCovered = 2) GROUP BY sp.topicID ";
        if ($subjectPlanRequest->sortBy) {
            $sql .= " ORDER BY $subjectPlanRequest->sortBy $subjectPlanRequest->sortOrder ";
        }
        try {
            $subjectPlanList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectPlanList;
    }
}