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 / 28
CRAP
0.00% covered (danger)
0.00%
0 / 671
OpenCourseService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 28
16256.00
0.00% covered (danger)
0.00%
0 / 671
 __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
 getAllOpenCourses
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentAllotedOpenCourse
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 checkPublishEnableOrNot
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getOpenCourseDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 31
 getAllOpenCoursesForAStudent
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 30
 getOpencourseSubjectSeats
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 26
 checkIfStudentAlreadyAppliedForOpenCourse
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 addStudentToOpenCourseForFirstComeFirstServe
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 56
 addOpenCourseSubjectSeatsToSubjectList
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 getStudentAllocationMethod
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getDepartmentWiseOpenCourseStudentList
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 22
 getDepartmentListOfAnOpenCourseApplication
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 28
 checkStudentAppliedOpenCourse
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 generateRankListByJSON
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 58
 getAppliedStudentsRankWise
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 38
 allocateStudentToSubject
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 25
 evaluateRulesAndStoreValues
0.00% covered (danger)
0.00%
0 / 1
600.00
0.00% covered (danger)
0.00%
0 / 103
 getOpenCourseApplicationDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 createTempTable
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 getOpenCourseAppliedStudents
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getOpenCourseSubjectsAndSeats
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 20
 getStudentsOptedSubjects
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 15
 getOpenCourseRankList
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 41
 assignStudentsToPseudoSubject
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 19
 isStudentsTransferred
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
<?php
namespace com\linways\core\ams\professional\service;
use com\linways\core\ams\professional\constant\OpenCourseStudentAllocationMethod;
use com\linways\core\ams\professional\constant\PseudoSubjectType;
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\core\ams\professional\dto\Student;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\mapper\OpenCourseServiceMapper;
use com\linways\core\ams\professional\request\AllocateStudentsRequest;
use com\linways\core\ams\professional\request\GenerateRankListByJSONRequest;
use com\linways\core\ams\professional\request\GetAppliedStudentsRankWiseRequest;
use com\linways\core\ams\professional\request\GetOpenCourseRankListRequest;
use com\linways\core\ams\professional\request\opencourse\AddStudentToOpenCourseForFirstComeFirstServeRequest;
use com\linways\core\ams\professional\response\GetRankListResponse;
class OpenCourseService extends BaseService
{
    /**
     * @var null
     */
    private static $_instance = null;
    /**
     * Mapper variable
     * @var array
     */
    private $mapper = [];
    // /Condition 2 - Locked down the constructor
    private function __construct()
    {
        $this->mapper = OpenCourseServiceMapper::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;
    }
    /**
     * Method for getting all open courses
     * @return Object|array
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getAllOpenCourses()
    {
        $getAllOpenCourses = [];
        try {
            $sql = "SELECT id AS openCourseId, opencourseName AS openCourseName 
                    FROM opencourse_appln_initiate";
            $getAllOpenCourses = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $getAllOpenCourses;
    }
    /**
     * Method for getting student alloted open course
     * @param unknown $studentId
     * @param unknown $openCourseApplnId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getStudentAllotedOpenCourse($studentId, $openCourseApplnId)
    {
        $sql = '';
        $studentId = $this->realEscapeString($studentId);
        $openCourseApplnId = $this->realEscapeString($openCourseApplnId);
        $studentAllotedOpenCourseDetails = null;
        try {
            $sql = "SELECT DISTINCT  p.subjectName AS pseudoSubjectName, p.pseudosubjectID AS pseudoSubjectId FROM pseudosubjects p 
                    INNER JOIN pseudosubjects_students ps ON p.pseudosubjectID = ps.pseudosubjectID 
                    INNER JOIN opencourse_student_appln osa ON p.pseudosubjectID = osa.pseudosubjects_id 
                   AND ps.studentID = osa.studentaccounts_id AND ps.pseudosubjectID = osa.pseudosubjects_id 
                    WHERE osa.studentaccounts_id = $studentId and osa.opencourse_appln_initiate_id = $openCourseApplnId";
            $studentAllotedOpenCourseDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentAllotedOpenCourseDetails;
    }
    /**
     * Method for checking publish flag enabled or not for an open course
     * @param integer $openCourseId
     * @return boolean
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function checkPublishEnableOrNot($openCourseId)
    {
        $sql = '';
        $openCourseId = $this->realEscapeString($openCourseId);
        $publishFlagEnabled = null;
        try {
            $sql = "SELECT oci.publish AS publish FROM opencourse_appln_initiate oci WHERE oci.id = $openCourseId";
            $publishFlagEnabled = $this->executeQueryForObject($sql)->publish;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $publishFlagEnabled;
    }
    /**
     * Undocumented function
     *
     * @param $studentId
     * @param $openCourseInitiateId
     * @param $semId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getOpenCourseDetails($studentId, $openCourseInitiateId, $semId)
    {
        $sql = "";
        $studentId = $this->realEscapeString($studentId);
        $openCourseInitiateId = $this->realEscapeString($openCourseInitiateId);
        $semId = $this->realEscapeString($semId);
        $openCourseList = null;
        $sql = "SELECT 
                    t3.id as applicationInitiateId,
                    t3.opencourseName as openCourseName,
                    t1.semID as semId,
                    t2.plustwo as plusTwoPercentage,
                    t3.applnStartDate,
                    t3.applnEndDate,
                    t3.considerPlusTwoMarks,
                    t3.maximum_selections as maximumSelection,
                    t3.is_grouped_subjects_enabled as isSubjectGroupingAdded,
                    pst.code as cbsTypeCode
                FROM
                    batches t1 INNER JOIN 
                    studentaccount t2 ON t1.batchID = t2.batchID AND t2.studentID = $studentId
                    INNER JOIN 
                    opencourse_appln_initiate t3 ON t1.courseTypeID = t3.course_type_id AND t3.id = $openCourseInitiateId
                    LEFT JOIN pseudo_subject_type pst ON pst.id = t3.cbs_type_id
                    AND FIND_IN_SET($semId, t3.semesters_id)";
        try {
            $openCourseList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $openCourseList;
    }
    public function getAllOpenCoursesForAStudent($studentId, $openCourseApplicationInitiateId, $applicationType)
    {
        $sql = "";
        $studentId = $this->realEscapeString($studentId);
        $openCourseList = null;
        //this query takes all pseudo subjects even if id is present in pseudosubject_students
        $condition = "";
        if ($applicationType === PseudoSubjectType::OPEN_COURSE) {
            $condition .= " AND ps.hdl_deptID!=d.deptID ";
        }
        $sql = "SELECT DISTINCT  ps.pseudosubjectID,ps.subjectName,handlingDept.deptID,handlingDept.deptName, 
                oai.is_grouped_subjects_enabled as isSubjectGroupingEnabled,psg.id as groupId,
                psg.name as groupName
                FROM opencourse_appln_initiate oai
                INNER JOIN opencourse_subject_seats oss ON oss.opencourse_appln_initiate_id =oai.id
                INNER JOIN cbs_application_batches cab on oai.id = cab.application_id
                INNER JOIN batches b on cab.batchId = b.batchID
                INNER JOIN department d ON d.deptID = b.deptID
                INNER JOIN studentaccount sa ON sa.batchID = b.batchID
                LEFT JOIN pseudosubjects ps ON ps.pseudosubjectID = oss.pseudosubjects_id
                LEFT JOIN  department handlingDept ON ps.hdl_deptID = handlingDept.deptID
                LEFT JOIN  pseudosubjects_sbs psbs ON ps.pseudosubjectID = psbs.pseudosubjectID
                LEFT JOIN pseudo_subject_groups psg ON psg.id = ps.pseudosubjectID
                LEFT JOIN pseudo_subject_type pst ON pst.id =ps.pseudo_subject_type_id
                WHERE oai.id = $openCourseApplicationInitiateId $condition AND studentID = $studentId ";
        try {
            $openCourseList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $openCourseList;
    }
    /**
     * Undocumented function
     *
     * @param [type] $openCourseApplicationInitiateId
     * @param [type] $pseudoSubjectId
     * @return void
     * @throws ProfessionalException
     */
    public function getOpencourseSubjectSeats($openCourseApplicationInitiateId = null, $pseudoSubjectId = null)
    {
        $openCourseApplicationInitiateId = $this->realEscapeString($openCourseApplicationInitiateId);
        $pseudoSubjectId = $this->realEscapeString($pseudoSubjectId);
        $subjectSeats = [];
        $sql = "SELECT os.id,os.opencourse_appln_initiate_id AS openCourseApplicationInitiateId,
                os.pseudosubjects_id AS pseudoSubjectId,os.seats,
                COUNT( osa.studentaccounts_id) AS numberOfStudents, 
                seats - COUNT(osa.studentaccounts_id) AS numberOfSeatsRemaining 
                FROM opencourse_subject_seats os 
                LEFT JOIN opencourse_student_appln osa ON os . pseudosubjects_id = osa . pseudosubjects_id  
                AND osa.opencourse_appln_initiate_id = os.opencourse_appln_initiate_id
                WHERE os.id IS NOT NULL ";
//        $sql = "SELECT
//        id,
//        opencourse_appln_initiate_id AS openCourseApplicationInitiateId,
//        pseudosubjects_id AS pseudoSubjectId,
//        seats,
//        COUNT(ps.studentID) AS numberOfStudents,
//        seats - COUNT(ps.studentID) AS numberOfSeatsRemaining
//    FROM
//        opencourse_subject_seats os
//            LEFT JOIN
//        pseudosubjects_students ps ON os . pseudosubjects_id = ps . pseudosubjectID  where id IS NOT NULL ";
        if (!empty($openCourseApplicationInitiateId)) {
            $sql .= " AND os . opencourse_appln_initiate_id = '$openCourseApplicationInitiateId'";
        }
        if (!empty($pseudoSubjectId)) {
            $sql .= " AND os . pseudosubjects_id = '$pseudoSubjectId'";
        }
        $sql .= " GROUP BY os . pseudosubjects_id";
        try {
            $subjectSeats = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectSeats;
    }
    /**
     * Return true if student already applied, else false
     * @param $openCourseApplicationInitiateId
     * @param $studentId
     * @return bool
     * @throws ProfessionalException
     */
    public function checkIfStudentAlreadyAppliedForOpenCourse($openCourseApplicationInitiateId, $studentId)
    {
        $studentApplication = [];
        $sqlCheck = "";
        $sqlCheck = "SELECT id FROM opencourse_student_appln 
                    WHERE opencourse_appln_initiate_id = $openCourseApplicationInitiateId 
                  AND studentaccounts_id = $studentId";
        try {
            $studentApplication = $this->executeQueryForObject($sqlCheck);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if (!empty($studentApplication)) {
            return true;
        }
        return false;
    }
    /**
     * Undocumented function
     *
     * @param AddStudentToOpenCourseForFirstComeFirstServeRequest $request
     * @return bool
     * @throws ProfessionalException
     */
    public function addStudentToOpenCourseForFirstComeFirstServe(AddStudentToOpenCourseForFirstComeFirstServeRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $seatDetails = $this->getOpencourseSubjectSeats($request->openCourseApplicationInitiateId, $request->pseudoSubjectId);
//        $numberOfSeats = $seatDetails[0]->seats;
//        $numberOfStudentsInPseudoSubject = $seatDetails[0]->numberOfSeatsRemaining;
        $numberOfSeatsRemaining = $seatDetails[0]->numberOfSeatsRemaining;
//        $numberOfStudentsInPseudoSubject = SubjectService::getInstance()->getNumberOfStudentsInAPseudoSubjectByPseudoSubjectId($request->pseudoSubjectId);
        if (empty($numberOfSeatsRemaining)) {
            throw new ProfessionalException(ProfessionalException::SEATS_ALREADY_FILLED, 'Seats for this elective is already filled');
        }
        $openCourseDetails = CBSService::getInstance()->getOpenCourseDetailsById($request->openCourseApplicationInitiateId);
        if (empty($openCourseDetails)) {
            throw new ProfessionalException(ProfessionalException::CBS_APPLICATION_DETAILS_NOT_FOUND, "CBS application details not found");
        }
        /**
         * Admin can set maximum number of selections in admin side, so checking user selected maximum number of options
         */
        $openCourseDetails->maximumSelections = (int)$openCourseDetails->maximumSelections;
        if (!$openCourseDetails->isSubjectGroupingEnabled) {
            $appliedSelections = CBSService::getInstance()->getCountOfAppliedCBSSubjects($request->openCourseApplicationInitiateId, $request->studentId);
            $appliedSelections = (int)$appliedSelections;
        } else {
            $appliedGroups = CBSService::getInstance()->getStudentAppliedCBSGroups($request->openCourseApplicationInitiateId, $request->studentId);
            $groupId = PseudoSubjectService::getInstance()->getPseudoSubjectGroupIdByPseudoSubjectId($request->pseudoSubjectId);
            $isFound = 0;
            foreach ($appliedGroups as $appliedGroup) {
                if ($appliedGroup->groupId == $groupId) {
                    $isFound = 1;
                }
            }
            if ($isFound) {
                $appliedSelections = count($appliedGroups);
            } else {
                $appliedSelections = count($appliedGroups) + 1;
            }
        }
        if (!empty($openCourseDetails->maximumSelections) && $openCourseDetails->maximumSelections < $appliedSelections) {
            throw new ProfessionalException(ProfessionalException::ALREADY_APPLIED_MAXIMUM_NUMBER_OF_SELECTIONS, "You are already applied maximum number of options");
        } else if (empty($openCourseDetails->maximumSelections)) {
            $studentAlreadyAppliedForOpenCourse = true;
            $studentAlreadyAppliedForOpenCourse = $this->checkIfStudentAlreadyAppliedForOpenCourse($request->openCourseApplicationInitiateId, $request->studentId);
            if ($studentAlreadyAppliedForOpenCourse) {
                throw new ProfessionalException(ProfessionalException::DUPLICATE_ENTRY, ProfessionalException::DUPLICATE_ENTRY);
            }
        }
        $sql = "INSERT INTO opencourse_student_appln(opencourse_appln_initiate_id, studentaccounts_id, 
                 pseudosubjects_priority, pseudosubjects_id, created_by, created_date, updated_by, updated_date) 
                VALUES($request->openCourseApplicationInitiateId$request->studentId, 1, $request->pseudoSubjectId
               $request->studentId, UTC_TIMESTAMP(), $request->studentId, UTC_TIMESTAMP())";
        try {
            $this->executeQueryForObject($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        $sql = "INSERT INTO pseudosubjects_students(pseudosubjectID, studentID) VALUES($request->pseudoSubjectId$request->studentId)";
        try {
            $this->executeQueryForObject($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    public function addOpenCourseSubjectSeatsToSubjectList($subjectList, $openCourseApplicationInitiateId)
    {
        $pseudoSubjectSeatList = $this->getOpencourseSubjectSeats($openCourseApplicationInitiateId);
        foreach ($subjectList as $subject) {
            $subject->seats = 0;
            $subject->noOfStudents = 0;
            $subject->numberOfSeatsRemaining = 0;
            foreach ($pseudoSubjectSeatList as $subjectSeatDetails) {
                if ($subjectSeatDetails->pseudoSubjectId == $subject->id) {
                    $subject->seats = $subjectSeatDetails->seats;
                    $subject->noOfStudents = $subjectSeatDetails->numberOfStudents;
                    $subject->numberOfSeatsRemaining = $subjectSeatDetails->numberOfSeatsRemaining;
                }
            }
        }
        return $subjectList;
    }
    /**
     * @return string
     * @throws ProfessionalException
     */
    public function getStudentAllocationMethod()
    {
        $studentAllocationMethod = "";
        $studentAllocationMethod = CommonService::getInstance()->getSettings(SettingsConstents::OPENCOURSE_SETTINGS, SettingsConstents::OPEN_COURSE_STUDENT_ALLOCATION_METHOD);
        if (empty(trim($studentAllocationMethod))) {
            $studentAllocationMethod = OpenCourseStudentAllocationMethod::RANK_LIST_METHOD;
        }
        return $studentAllocationMethod;
    }
    public function getDepartmentWiseOpenCourseStudentList($openCourseInitiateId)
    {
        $openCourseInitiateId = $this->realEscapeString($openCourseInitiateId);
        $subjectList = [];
        $sql = "SELECT 
                    ps . pseudosubjectID as pseudoSubjectId, ps . subjectName, dept . deptID as deptId, dept . deptName, dept . departmentDesc, sta . studentID as studentId, sta . studentName
                FROM
                    opencourse_subject_seats oss
                        LEFT JOIN
                    opencourse_student_appln osa ON osa . opencourse_appln_initiate_id = '$openCourseInitiateId' AND osa . opencourse_appln_initiate_id = oss . opencourse_appln_initiate_id
                        LEFT JOIN
                    pseudosubjects_students pss ON pss . studentID = osa . studentaccounts_id AND oss . pseudosubjects_id = pss . pseudosubjectID AND pss . pseudosubjectID = osa . pseudosubjects_id
                        LEFT JOIN
                    studentaccount sta ON sta . studentID = pss . studentID
                        LEFT JOIN department dept ON dept . deptID = sta . deptID
                        LEFT JOIN pseudosubjects ps ON ps . pseudosubjectID = oss . pseudosubjects_id";
        try {
            $subjectList = $this->executeQueryForList($sql, $this->mapper[OpenCourseServiceMapper::GET_DEPARTMENT_WISE_REPORT]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectList;
    }
    /**
     * Undocumented function
     *
     * @param [type] $openCourseInitiateId
     * @return void
     * @throws ProfessionalException
     */
    public function getDepartmentListOfAnOpenCourseApplication($openCourseInitiateId)
    {
        $openCourseInitiateId = $this->realEscapeString($openCourseInitiateId);
        $sql = "";
        $sql = "SELECT departments_id as departmentIdList FROM opencourse_appln_initiate WHERE id = '$openCourseInitiateId'";
        try {
            $departmentIdString = $this->executeQueryForObject($sql)->departmentIdList;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        $departmentList = explode(',', $departmentIdString);
        if (in_array('all', $departmentList) || empty($departmentList)) {
            $departmentList = DepartmentService::getInstance()->getDepartments(false);
        } else {
            $sql = "";
            $sql = "SELECT deptID as id,
                        deptName as name,
                        departmentDesc as description,
                        deptShow,
                        admissionShow
                    from department WHERE deptID IN($departmentIdString)";
            try {
                $departmentList = $this->executeQueryForList($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        return $departmentList;
    }
    /**
     * Return true if student already applied, else false
     * @param $openCourseApplicationInitiateId
     * @param $studentId
     * @return bool
     * @throws ProfessionalException
     */
    public function checkStudentAppliedOpenCourse($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        $studentApplication = null;
        $sqlCheck = "";
        $sqlCheck = "SELECT studentaccounts_id FROM opencourse_student_appln WHERE studentaccounts_id = $studentId";
        try {
            $studentApplication = $this->executeQueryForObject($sqlCheck);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if (!empty($studentApplication)) {
            return true;
        }
        return false;
    }
    /**
     * @param GenerateRankListByJSONRequest $request
     * @throws ProfessionalException
     */
    public function generateRankListByJSON(GenerateRankListByJSONRequest $request)
    {
        if (empty($request->openCourseId)) {
            throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "Invalid open course details given");
        }
        $rankingRuleTable = "";
        try {
            $openCourse = $this->getOpenCourseApplicationDetails($request->openCourseId);
            if (empty($openCourse)) {
                throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "This open course doesn't exist!");
            }
            $semesterRules = CommonService::getInstance()->getSettings("CBE_MODULE", "RANK_LIST_GENERATING_RULE");
            if (empty($semesterRules)) {
                throw new ProfessionalException("RANKING_RULES_NOT_CONFIGURED", "Rank list generating rules not configured");
            }
            $semesterRules = json_decode($semesterRules);
            $rules = null;
            foreach ($semesterRules as $rule) {
                if ($rule->semester === (int)$openCourse->semesterId) {
                    $rules = $rule->rankingRules;
                    break;
                }
            }
            if (empty($rules)) {
                throw new ProfessionalException("RULES_NOT_CONFIGURED", "Rank generating rules not configured");
            }
            $this->executeQuery("DELETE FROM opencourse_rank_list_temp WHERE open_course_id =$openCourse->id;");
            $this->executeQuery("UPDATE opencourse_appln_initiate SET is_rank_list_generated=0 WHERE id = $openCourse->id");
            $subjectsAndSeats = $this->getOpenCourseSubjectsAndSeats($request->openCourseId);
            $rankingRuleTable = "open_course_ranking_rules_table_" . $openCourse->id;
            $this->createTempTable($rankingRuleTable, $rules);
            try{
                $this->evaluateRulesAndStoreValues($openCourse->id, $rankingRuleTable, $rules);
            }catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            $getRequest = new GetAppliedStudentsRankWiseRequest();
            $getRequest->openCourseId = $openCourse->id;
            $getRequest->rules = $rules;
            $getRequest->rankingRuleTable = $rankingRuleTable;
            $appliedStudents = $this->getAppliedStudentsRankWise($getRequest);
            foreach ($appliedStudents as $student) {
                $allocateRequest = new AllocateStudentsRequest();
                $allocateRequest->openCourseId = $openCourse->id;
                $allocateRequest->studentId = $student->id;
                $allocateRequest->subjectAndSeats = $subjectsAndSeats;
                $allocateRequest->studentSubjects = $student->pseudoSubjects;
                $allocateRequest->createdBy = $request->createdBy;
                $allocateRequest->updatedBy = $request->updatedBy;
                $subjectsAndSeats = $this->allocateStudentToSubject($allocateRequest);
            }
            $this->executeQuery("UPDATE opencourse_appln_initiate SET is_rank_list_generated=1 WHERE id = $openCourse->id");
            /**
             * Removing temporary table after generating rank list
             */
            $this->executeQuery("DROP TABLE IF EXISTS $rankingRuleTable;");
        } catch (\Exception $e) {
            if ($rankingRuleTable)
                $this->executeQuery("DROP TABLE IF EXISTS $rankingRuleTable;");
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param GetAppliedStudentsRankWiseRequest $request
     * @return Object|Student
     * @throws ProfessionalException
     */
    private function getAppliedStudentsRankWise(GetAppliedStudentsRankWiseRequest $request)
    {
        $sql = "SELECT osal.studentaccounts_id,osal.id,osal.pseudosubjects_id,osal.pseudosubjects_priority
                FROM opencourse_appln_initiate oai 
                INNER JOIN opencourse_student_appln osal ON oai.id = osal.opencourse_appln_initiate_id
                LEFT JOIN $request->rankingRuleTable temp ON temp.student_id = osal.studentaccounts_id 
                WHERE oai.id =" . $request->openCourseId . "
                ORDER BY ";
        $orderQuery = "";
        usort($request->rules, function ($item1, $item2) {
            return $item1->priority <=> $item2->priority;
        });
        try {
            foreach ($request->rules as $rule) {
                if($rule->operand == 'AVERAGE_SGPA') {
                    foreach ($request->rules as $rule) {
                    $orderQuery .= " temp." . $rule->name . " " . $rule->order . ",";
                    }
                    break;
                }
                if($rule->operand == 'PLUS_TWO_MARK') {
                    foreach ($request->rules as $rule) {
                    $orderQuery .= " temp." . $rule->name . " " . $rule->order . ",";
                    }
                    break;
                }
                else{
                    if ($rule->considerFailedStudents) {
                        $orderQuery .= " temp." . $rule->name . "_status DESC,";
                    }
                    $orderQuery .= " temp." . $rule->name . " " . $rule->order . ",";
                }
            }
            $orderQuery .= " osal.pseudosubjects_priority ASC ";
            $sql .= $orderQuery;
            return $this->executeQueryForList($sql, $this->mapper[OpenCourseServiceMapper::GET_RANK_WISE_STUDENT_LIST]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param AllocateStudentsRequest $request
     * @return object
     * @throws ProfessionalException
     */
    private function allocateStudentToSubject(AllocateStudentsRequest $request)
    {
        try {
            $isSubjectAllotted = false;
            foreach ($request->studentSubjects as $subject) {
                foreach ($request->subjectAndSeats as $subjectAndSeat) {
                    $subjectAndSeat->availableSeats = (int)$subjectAndSeat->availableSeats;
                    if ($subjectAndSeat->availableSeats && $subject->pseudoSubjectId === (int)$subjectAndSeat->pseudoSubjectId) {
                        $sql = "INSERT INTO opencourse_rank_list_temp (open_course_id, student_id, pseudo_subject_id, created_by, 
                            created_date, updated_by, updated_date) 
                            VALUES($request->openCourseId,$request->studentId,$subjectAndSeat->pseudoSubjectId,
                                   $request->createdBy,UTC_TIMESTAMP(),$request->updatedBy,UTC_TIMESTAMP())";
                        $this->executeQuery($sql);
                        --$subjectAndSeat->availableSeats;
                        $isSubjectAllotted = true;
                        break;
                    }
                }
                if ($isSubjectAllotted)
                    break;
            }
            /**
             * For avoiding available seats checking database hit
             */
            return $request->subjectAndSeats;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $openCourseId
     * @param $table
     * @param $rules
     * @throws ProfessionalException
     */
    private function evaluateRulesAndStoreValues($openCourseId, $table, $rules)
    {
        $sql = "INSERT INTO $table (student_id,open_course_id,";
        $selectQuery = "SELECT DISTINCT studentID, $openCourseId,";
        $index = 0;
        $joinQuery = "";
        $orderQuery = "";
        $total_sgpa = "";
        $isAvgSgpa = 0;
        usort($rules, function ($item1, $item2) {
            return $item1->priority <=> $item2->priority;
        });
        foreach ($rules as $rule) {
            ++$index;
            switch ($rule->operand) {
                case "SEMESTER_SGPA":
                    $sql .= $rule->name . "_status,$rule->name,";
                    if ($rule->considerFailedStudents) {
                        $selectQuery .= "IF(esc" . $index . ".status='PASSED',1,0),";
                    }
                    $selectQuery .= "esc" . $index . ".sgpa,";
                    $joinQuery .= " LEFT JOIN ec_semster_consolidated_mark_details esc" . $index . " ON esc" . $index . ".student_id = osa.studentaccounts_id AND ";
                    switch ($rule->operator) {
                        case "EQ":
                            $joinQuery .= " esc" . $index . ".sem_id=$rule->value ";
                    }
                    if ($rule->order === "ASC") {
                        $orderQuery .= " esc" . $index . ".sgpa ASC,";
                    } elseif ($rule->order === "DESC") {
                        $orderQuery .= " esc" . $index . ".sgpa DESC,";
                    }
                break;
                case "AVERAGE_SGPA":
                    $isAvgSgpa = 1;
                    
                    switch ($rule->operator) {
                        case "IN":
                            foreach($rule->value as $value){
                                $query = "SELECT esc" . $value. ".sgpa FROM ec_semster_consolidated_mark_details esc" . $value. " INNER JOIN opencourse_student_appln osa ON esc" . $value. ".student_id = osa.studentaccounts_id WHERE esc" . $value. ".sgpa=NULL AND esc" . $value. ".sem_id=$value ";
                                $result = $this->executeQueryForList($query);
                                if(!empty($result)){
                                    throw new ProfessionalException("INVALID_STUDENT_MARK", "SGPA of students cannot be empty!");
                                    break;
                                }
                                $total_sgpa .= "esc" . $value. ".sgpa+";
                                $joinQuery .= " LEFT JOIN ec_semster_consolidated_mark_details esc" . $value . " ON esc" . $value . ".student_id = osa.studentaccounts_id AND esc" . $value. ".sem_id=$value ";
                            }
                            $total_sgpa = rtrim($total_sgpa, "+");
                            $num = count($rule->value);
                            $selectQuery .= "(( $total_sgpa)/$num) as avg_sgpa,";
                            if ($rule->order === "ASC") {
                                $orderQuery .= " avg_sgpa ASC,";
                            } elseif ($rule->order === "DESC") {
                                $orderQuery .= " avg_sgpa DESC,";
                            }
                            foreach ($rules as $rule) {
                                if($rule->operand != 'AVERAGE_SGPA'){
                                    continue;
                                }
                                $sql .= "$rule->name,";
                                if($rule->operand!='AVERAGE_SGPA'){
                                    $selectQuery .= "esc" . $rule->value. ".sgpa,";
                                    if ($rule->order === "ASC") {
                                        $orderQuery .= " esc" . $rule->value . ".sgpa ASC,";
                                    } elseif ($rule->order === "DESC") {
                                        $orderQuery .= " esc" . $rule->value . ".sgpa DESC,";
                                    }
                                }
                            }
                        break;
                    }
                break;
                case "PLUS_TWO_MARK":
                    //check all student having plustwo marks
                    $query = "SELECT plustwo FROM studentaccount sa inner join opencourse_student_appln osa ON osa.studentaccounts_id =sa.studentID WHERE sa.plustwo ='0' AND  osa.opencourse_appln_initiate_id= '$openCourseId";
                    $result = $this->executeQueryForList($query);
                    if(!empty($result)){
                        throw new ProfessionalException("INVALID_STUDENT_MARK", "Plus Two Marks are Invalid!");
                        break;
                    }
                    $sql .= "$rule->name,";
                    $selectQuery .= " sa.plustwo as plusTwoMark,";
                    if ($rule->order === "ASC") {
                        $orderQuery .= "sa.plustwo ASC, ";
                    } elseif ($rule->order === "DESC") {
                        $orderQuery .= " sa.plustwo DESC,";
                    }
                break;
            }
            if($isAvgSgpa){
                 break;
            }
        }
        $orderQuery = rtrim($orderQuery, ",");
        $selectQuery = rtrim($selectQuery, ",");
        $selectQuery .= " FROM studentaccount sa 
                        INNER JOIN opencourse_student_appln osa ON osa.studentaccounts_id =sa.studentID ";
        $selectQuery .= $joinQuery;
        $selectQuery .= " WHERE osa.opencourse_appln_initiate_id = $openCourseId ORDER BY $orderQuery";
        $sql = rtrim($sql, ",");
        $sql .= ") " . $selectQuery;
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $openCourseId
     * @return Object
     * @throws ProfessionalException
     */
    public function getOpenCourseApplicationDetails($openCourseId)
    {
        $openCourseId = (int)$this->realEscapeString($openCourseId);
        if (empty($openCourseId)) {
            throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "Invalid open course details given");
        }
        $sql = "SELECT id,opencourseName as name,semesters_id as semesterId 
                FROM opencourse_appln_initiate WHERE id = $openCourseId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $tableName
     * @param $fields
     * @throws ProfessionalException
     */
    private function createTempTable($tableName, $fields)
    {
        $sql = "CREATE TEMPORARY TABLE $tableName (`id` INT NOT NULL AUTO_INCREMENT, `student_id` INT NOT NULL, 
                                        `open_course_id` INT NOT NULL, ";
        foreach ($fields as $field) {
            if ($field->considerFailedStudents) {
                $sql .= $field->name . "_status INT DEFAULT NULL  ,";
            }
            $sql .= $field->name . " " . $field->valueType . " DEFAULT NULL  ,";
        }
        $sql .= " PRIMARY KEY(id))";
        try {
            $this->executeQuery("DROP TABLE IF EXISTS $tableName;");
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $openCourseId
     * @return Object
     * @throws ProfessionalException
     */
    private function getOpenCourseAppliedStudents($openCourseId)
    {
        $sql = "SELECT studentaccounts_id as studentID 
                FROM opencourse_appln_initiate oai 
                INNER JOIN opencourse_student_appln osal on oai . id = osal . opencourse_appln_initiate_id
                WHERE oai . id = $openCourseId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $openCourseId
     * @return Object|array
     * @throws ProfessionalException
     */
    public function getOpenCourseSubjectsAndSeats($openCourseId)
    {
        if (empty($openCourseId)) {
            throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "Invalid open course details given");
        }
        $sql = "SELECT oss.pseudosubjects_id AS pseudoSubjectId,oss.seats as totalSeats, 
                IF(temp.assignedSeats IS NOT NULL,oss.seats-temp.assignedSeats,oss.seats) as availableSeats  
                FROM opencourse_appln_initiate oai 
                INNER JOIN opencourse_subject_seats oss ON oai.id = oss.opencourse_appln_initiate_id    
                 LEFT JOIN (
                    SELECT pseudo_subject_id,COUNT(student_id) AS assignedSeats 
                    FROM opencourse_rank_list_temp  
                    WHERE open_course_id = $openCourseId GROUP BY pseudo_subject_id
                ) as temp ON temp.pseudo_subject_id = oss.pseudosubjects_id
                WHERE opencourse_appln_initiate_id = $openCourseId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $openCourseId
     * @return Object
     * @throws ProfessionalException
     */
    private function getStudentsOptedSubjects($openCourseId)
    {
        $sql = "SELECT sa . studentID,sa . regNo,sa . studentName,b . batchID,b . batchName,ps . pseudosubjectID,ps . subjectName,
                osal . pseudosubjects_priority,osal . id as registration_id
                FROM opencourse_appln_initiate oai 
                INNER JOIN opencourse_student_appln osal on oai . id = osal . opencourse_appln_initiate_id
                INNER JOIN pseudosubjects ps ON ps . pseudosubjectID = osal . pseudosubjects_id
                INNER JOIN studentaccount sa ON sa . studentID = osal . studentaccounts_id
                INNER JOIN batches b ON b . batchID = sa . batchID
                WHERE oai . id = $openCourseId ORDER BY osal . studentaccounts_id,osal . pseudosubjects_priority";
        try {
            return $this->executeQueryForList($sql, $this->mapper[OpenCourseServiceMapper::GET_STUDENTS_OPTED_SUBJECTS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param GetOpenCourseRankListRequest $request
     * @return GetRankListResponse
     * @throws ProfessionalException
     */
    public function getOpenCourseRankList(GetOpenCourseRankListRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->openCourseId)) {
            throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "Open course details not found");
        }
        $response = new GetRankListResponse();
        $limitQuery = "";
        if ($request->isExport) {
            $limitQuery = " INNER JOIN (SELECT DISTINCT studentaccounts_id as student_id 
                            FROM opencourse_student_appln osal 
                            INNER JOIN studentaccount sa ON sa.studentID = osal.studentaccounts_id
                            INNER JOIN batches b ON b.batchID = sa.batchID
                            WHERE osal.opencourse_appln_initiate_id = $request->openCourseId
                            ORDER BY b.batchStartYear,b.batchName,sa.regNo
                            LIMIT $request->startIndex,$request->endIndex ) as temp 
                            ON temp.student_id= osal.studentaccounts_id";
        }
        $sql = "SELECT sa.studentID,oai.id,oai.opencourseName as name,sa.studentName,sa.regNo,sa.rollNo,
                b.batchName,ps.subjectName,oai.studentsTransferedFlag as is_published
                FROM opencourse_appln_initiate oai 
                INNER JOIN opencourse_student_appln osal on oai.id = osal.opencourse_appln_initiate_id
                $limitQuery
                LEFT JOIN studentaccount sa ON sa.studentID = osal.studentaccounts_id
                LEFT JOIN opencourse_rank_list_temp orlt ON orlt.open_course_id = oai.id 
                AND osal.studentaccounts_id = orlt.student_id 
                LEFT JOIN batches b ON b.batchID = sa.batchID
                LEFT JOIN pseudosubjects ps ON ps.pseudosubjectID = orlt.pseudo_subject_id 
                WHERE oai.id = $request->openCourseId AND oai.is_rank_list_generated=1 
                ORDER BY b.batchStartYear,b.batchName,sa.regNo";
        try {
            if ($request->isExport) {
                $totalSql = "SELECT COUNT(DISTINCT studentaccounts_id) as totalRecords 
                        FROM opencourse_student_appln WHERE opencourse_appln_initiate_id = $request->openCourseId ";
                $response->totalRecords = (int)$this->executeQueryForObject($totalSql)->totalRecords;
            }
            $response->rankList = $this->executeQueryForObject($sql, false, $this->mapper[OpenCourseServiceMapper::GET_STUDENTS_RANK_LIST]);
            return $response;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param AssignStudentsToPseudoSubjectRequest $request
     * @throws ProfessionalException
     */
    public function assignStudentsToPseudoSubject(AssignStudentsToPseudoSubjectRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->openCourseId)) {
            throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "Open course not found");
        }
        if ($this->isStudentsTransferred($request->openCourseId)) {
            throw new ProfessionalException("STUDENTS_ALREADY_TRANSFERRED", "Rank list details already saved and students already transferred to corresponding pseudo subjects");
        }
        $sql = "INSERT INTO pseudosubjects_students (pseudosubjectID, studentID, created_by, created_date, 
                updated_by, updated_date) 
                SELECT pseudo_subject_id,student_id,$request->createdBy,UTC_TIMESTAMP(), $request->updatedBy,UTC_TIMESTAMP()
                FROM opencourse_rank_list_temp WHERE open_course_id = $request->openCourseId";
        try {
            $this->executeQueryForList($sql);
            $this->executeQuery("UPDATE opencourse_appln_initiate SET studentsTransferedFlag=1 WHERE id = $request->openCourseId");
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Checking students transferred
     *
     * @param $openCourseId
     * @return int
     * @throws ProfessionalException
     */
    public function isStudentsTransferred($openCourseId)
    {
        $openCourseId = (int)$this->realEscapeString($openCourseId);
        if (empty($openCourseId)) {
            throw new ProfessionalException("INVALID_OPEN_COURSE_ID", "Open course not found");
        }
        $sql = "SELECT studentsTransferedFlag as isTransferred 
                FROM opencourse_appln_initiate WHERE id = $openCourseId";
        try {
            return (int)$this->executeQueryForObject($sql)->isTransferred;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
}