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 / 96
CRAP
0.00% covered (danger)
0.00%
0 / 2547
ExamSupplementaryService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 96
166872.00
0.00% covered (danger)
0.00%
0 / 2547
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 __clone
n/a
0 / 0
1
n/a
0 / 0
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getExamSupplementaryById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 searchExamSupplementary
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 35
 getExamSupplementaryDetailsById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getSupplyImproveRegisteredStudentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getSupplyImproveRegisteredStudentSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getSupplyImproveExamCommonFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSupplyImproveExamFine
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getSupplyImproveExamFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 generateSupplyImproveChallanNo
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 addSupplyImproveStudentSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 getSupplyPublishDate
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 saveSupplementary
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 48
 deleteExamSupplementaryById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamSupplementaryBatchSubjectFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 49
 getExamSupplementaryBatchSubject
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 49
 saveExamSupplementaryBatchSubjectFees
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 28
 saveSupplyImproveBatches
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 saveSupplyImproveSubjectFees
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 25
 saveSupplyImproveExamFees
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 21
 deleteExamSupplementaryBatchSubjectFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 deleteSupplyImproveBatches
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 deleteSupplyImproveSubjectFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 saveExamSupplementaryRegistrationFeesFine
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 71
 enableDisableSupplementaryHallTicket
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSupplyImproveBatches
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 getSupplyImproveRegisteredStudentSubjectDetailswithSubjectCat
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 27
 getSupplyImproveMarksByStudent
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 81
 getStudentExamSupplyRegistrationsBySem
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getSupplyExamBySupplyRegIdAndBatchAndSem
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getSupplyExamRegisteredStudentsByBatchAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 19
 getExamMonthYearsOfBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 24
 getSupplyImproveRegisteredStudentByBatchSemRelation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 28
 getExamSupplementaryMonthYears
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getExamSupplementaryByMonthAndYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getExamSupplementaryStudentsBySupplyRegAndBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 16
 getExamSupplementaryPublishDateByBatchAndMonthYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 15
 getStudentExamSupplyRegistrationsByStudent
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 21
 getStudentSupplyExamSubjects
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 19
 getAllRegisteredSupplyExams
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 getExamSupplementaryRegSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getExamRegistrationDetailsByCourseTypeAndBatchStartYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 31
 getSupplyBatchesBySupplyIds
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 saveSupplyProgramResultMonthAndYear
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 31
 getSupplyProgramResultMonthAndYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getSupplyRegisteredStudentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 changeSupplyExamRegistration
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 30
 deleteExamsOfSimilarRegistrations
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 54
 enableDisableSupplementaryNominalRole
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getDistinctSupplyRegistratin
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamSupplyRegistrationsByAdmissionYear
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 23
 getSupplyExamRegistrationMonthYearDetailsByRequest
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 34
 changeSupplyImproveStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentSupplyRegistrationsBySemId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 22
 getSupplyRegistrationsBySemAndBatchId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getAllSupplyRegisteredStudentsForSubjects
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getSupplyStudentWiseReportBySupplyRegId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSupplyMarkDetailsByStudentAndRegularExamId
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 60
 getSupplyAbsentStatusDetailsByStudentAndRegularExamId
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 64
 getExamSubjectListByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getSupplyExamRegisteredPgStudentsWithMarksBySubject
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 29
 getSupplyExamRegisteredUgStudentsWithMarksBySubject
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 29
 getPublishedExamSupplyRegistrationSbyRequest
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 25
 getStudentAbsentStatusOfSupplyExamByRequest
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 74
 getSubjectListSupp
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 32
 getWithheldSupplyRegistrationsByStudent
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getSupplyExamRegistrationForBatch
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 29
 getDistinctExamRegistrationByRequest
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 25
 getDistinctSupplyExamRegBatchesByRequest
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 38
 getStudentCountDetailsSupp
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 20
 getSupplyPublishDetailsByRequest
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getStudentLatestSupplyRegistrationOfSubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 finalizeSupplyExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getSupplyExamFinalizeDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 setSupplyExamRegBatchPublishDates
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 24
 getExamSupplyRegistrationsByRequest
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 25
 updateSupplyApproveStatusOfRegisteredStudents
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 27
 getStudentSupplyExamSubjectRegisteredDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 addSupplyStudentSubjectForRegistrations
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 32
 getStudentSupplySubjectsForOfflineRegistration
0.00% covered (danger)
0.00%
0 / 1
1892.00
0.00% covered (danger)
0.00%
0 / 185
 getSupplyStudentSubjectsForConsolidated
0.00% covered (danger)
0.00%
0 / 1
1722.00
0.00% covered (danger)
0.00%
0 / 184
 getDistinctSupplyExamRegisteredSubjectsByRequest
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 37
 getExamRegistrationByStudentIdAndSemId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSupplySubjectsDetailsByStudentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 25
 getSpecialExamMarkDetailsByStudentAndRegularExamId
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 60
 getSupplyExamRegisteredStudentList
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 26
 getSupplyPublishDetailsByBatch
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 17
 getSupplyRegStudentsByDate
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 24
 getStudentSupplyInternalMark
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 39
 getExamSupplyRegistrationDetailsByRequest
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 20
 getRegularExamRegistrationByExamSupplyRegRequest
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 19
 getSupplyImproveRegisteredStudentFalseNumbers
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 34
 getStudentSupplyInternalMarks
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 mapSupplyIntMarks
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 6
 getRegularExamRegistrationByExamSupplyRegId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
<?php
namespace com\linways\core\ams\professional\service;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\mapper\ExamSupplementaryServiceMapper;
use com\linways\core\ams\professional\constant\examcontroller\CourseTypeConstants;
use com\linways\core\ams\professional\constant\examcontroller\ExamSubjectTypeConstants;
use com\linways\core\ams\professional\service\ExamService;
use com\linways\core\ams\professional\service\StudentService;
use com\linways\core\ams\professional\service\CourseTypeService;
use com\linways\core\ams\professional\dto\examcontroller\UniversityMarkListPassPercentConfig;
class ExamSupplementaryService extends BaseService
{
    // private $batchService = BatchService::getInstance();
    // /Condition 1 - Presence of a static member variable
    private static $_instance = null;
    
    private $mapper = [];
    // /Condition 2 - Locked down the constructor
    private function __construct() {
        $this->mapper = ExamSupplementaryServiceMapper::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;
    }
    
    public function getExamSupplementaryById ( $examSupplementaryId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $sql = null;
        $examSupplementary = null;
        $sql = "SELECT id, supplyDesc, examDate, startDate, endDate, subjectLimit, semID, valuation_startDate, valuation_endDate, patternID, enable_hlticket, publishFromDate, publishToDate, examMonth, examYear, pimage, simage, isSpecialExam, considerFlag FROM exam_supplementary WHERE id = '$examSupplementaryId";
        try {
            $examSupplementary = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examSupplementary;
    }
    public function searchExamSupplementary ( $supplementaryRequest ) {
        $supplementaryRequest = $this->realEscapeObject($supplementaryRequest);
        $conditions = null;
        $limitCondition = null;
        if ( $supplementaryRequest->id ) {
            $conditions .= " AND es.id = $supplementaryRequest->id ";
        }
        if ( $supplementaryRequest->semId ) {
            $conditions .= " AND es.semID = $supplementaryRequest->semId ";
        }
        if ( $supplementaryRequest->supplyName ) {
            $conditions .= " AND es.supplyDesc LIKE '%".$supplementaryRequest->supplyName."%' ";
        }
        $sortBy = "es.id";
        $sortOrder = "DESC";
        
        if ( $supplementaryRequest->sortBy ) {
            $sortBy = $supplementaryRequest->sortBy;
            $sortOrder = $supplementaryRequest->sortOrder;
        }
        if ( $supplementaryRequest->startIndex !== "" && $supplementaryRequest->startIndex !== null ) {
            if ( $supplementaryRequest->startIndex !== "" && $supplementaryRequest->recordsPerPage ) {
                $limitCondition = " LIMIT $supplementaryRequest->startIndex , $supplementaryRequest->recordsPerPage ";
            }
        }
        
        $sql = null;
        $response = null;
        $sql = "SELECT es.id, es.supplyDesc, IF(es.examDate = '0000-00-00', NULL, es.examDate) AS examDate, IF(es.startDate = '0000-00-00', NULL, es.startdate) as startDate, IF(es.endDate = '0000-00-00', NULL, es.enddate) as endDate, es.subjectLimit, es.semID, s.semName, es.valuation_startDate, es.valuation_endDate, es.patternID, es.enable_hlticket, es.publishFromDate, es.publishToDate, es.examMonth, es.examYear, es.pimage AS profileImage, es.simage AS signatureImage, es.isSpecialExam, es.considerFlag, es.allowNotification,es.enableNominalRole FROM exam_supplementary es INNER JOIN semesters s ON (es.semID = s.semID) WHERE es.id IS NOT NULL $conditions ORDER BY $sortBy $sortOrder $limitCondition";
        try {
            $sqlCount = "SELECT COUNT(es.id) as totalRecords FROM exam_supplementary es WHERE es.id IS NOT NULL $conditions ";
            $response->totalRecords = $this->executeQueryForObject($sqlCount)->totalRecords;
            $response->examSupplementary = $this->executeQueryForList($sql, $this->mapper[ExamSupplementaryServiceMapper::GET_EXAM_SUPPLEMENTARY_DETAILS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    /**
     * Get exam supplementary details by examSupplementaryId
     * @param Integer $examSupplementaryId
     * @return Array $examSupplementary
     * @throws ProfessionalException
     * @author Vishnu M 
     */
    public function getExamSupplementaryDetailsById ( $examSupplementaryId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $sql = null;
        $examSupplementary = null;
        $sql = "SELECT es.id, es.supplyDesc, es.startDate, es.endDate, es.subjectLimit, es.semID, es.valuation_startDate, es.valuation_endDate, es.patternID, es.enable_hlticket, es.publishFromDate, es.publishToDate, es.examMonth, es.examYear, ef.examfineID, ef.examfineName, sef.supply_fineAmount AS supplyFineAmount, sef.supply_startDate AS supplyFineStartDate, sef.supply_endDate AS supplyFineEndDate, sef.improve_fineAmount AS improveFineAmount, sef.improve_startDate AS improveFineStartDate, sef.improve_endDate AS improveFineEndDate FROM exam_supplementary es LEFT JOIN supply_improve_exam_fine sef ON (es.id = sef.exam_supplementary_id) LEFT JOIN exam_finetype ef ON (ef.examfineID = sef.examfineID) WHERE es.id = '$examSupplementaryId' ORDER BY sef.supply_startDate";
        try {
            $examSupplementary = $this->executeQueryForList($sql, $this->mapper[ExamSupplementaryServiceMapper::GET_EXAM_SUPPLEMENTARY_DETAILS]);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $examSupplementary;
    }
    /**
     * Get supply / improvement registered student details by examSupplementaryId and studentId
     * @param Integer $examSupplementaryId
     * @param Integer $studentId
     * @return Object $details
     * @throws ProfessionalException
     * @author Vishnu M 
     */
    public function getSupplyImproveRegisteredStudentDetails ( $examSupplementaryId, $studentId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $studentId = $this->realEscapeString($studentId);
        $sql = null;
        $details = null;
        $sql = "SELECT exam_supplementary_id, studentID, total_fees, challanNo, paid, appliedDate, fee_paidDate, isSupply, payment_method, approved FROM exam_supplementary_student_details WHERE exam_supplementary_id = '$examSupplementaryId' AND studentID = '$studentId";
        try {
            $details = $this->executeQueryForObject($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $details;
    }
    
    
    /**
     * Get supply / improvement registered student subject details by examSupplementaryId and studentId
     * @param Integer $examSupplementaryId
     * @param Integer $studentId
     * @return Array $details
     * @throws ProfessionalException
     * @author Vishnu M 
     */
    public function getSupplyImproveRegisteredStudentSubjectDetails ( $examSupplementaryId, $studentId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $studentId = $this->realEscapeString($studentId);
        $sql = null;
        $details = [];
        $sql = "SELECT esss.exam_supplementary_id, esss.studentID, esss.examID, esss.approveImprovementMarkStatus, s.subjectID, s.subjectName, s.subjectDesc, s.syllabusName,e.batchID ,e.semID as semId,esc.isInternal
                FROM exam_supplementary_student_subjects esss INNER JOIN exam e ON (e.examID = esss.examID) 
                INNER JOIN subjects s ON (e.subjectID = s.subjectID)  
                INNER JOIN exam_subjectcredit esc ON esc.subjectID = s.subjectID AND esc.batchID = e.batchID AND esc.semID = e.semID
                WHERE esss.exam_supplementary_id = '$examSupplementaryId' AND esss.studentID = '$studentId' order by esc.subjectOrder";
        try {
            $details = $this->executeQueryForList($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $details;
    }
    /**
     * @author Vishnu M
     */
    public function getSupplyImproveExamCommonFees ( $examSupplementaryId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $commonFeeAmount = 0;
        $sql = "SELECT SUM(siaf.improve_feesAmount) AS commonImproveFee, SUM(siaf.supply_feesAmount) AS commonSupplyFee FROM supply_improve_exam_fees siaf INNER JOIN exam_feestype eft ON ( eft.examfeesID = siaf.examfeesID AND eft.everySubject = 0 ) WHERE siaf.exam_supplementary_id = '$examSupplementaryId";
        try {
            $commonFeeAmount = $this->executeQueryForObject($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $commonFeeAmount;
    }
    /**
     * @author Vishnu M
     */
    public function getSupplyImproveExamFine ( $isSupply, $examSupplementaryId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $isSupply = $this->realEscapeString($isSupply);
        $fineAmount = 0;
        $currentDate = date("Y-m-d");
        if ( $isSupply ) {
            $sql = "SELECT supply_fineAmount as fineAmount FROM supply_improve_exam_fine WHERE supply_startDate <= '$currentDate' AND supply_endDate >= '$currentDate' AND exam_supplementary_id = '$examSupplementaryId";
        }
        else {
            $sql = "SELECT improve_fineAmount as fineAmount FROM supply_improve_exam_fine WHERE improve_startDate <= '$currentDate' AND improve_endDate >= '$currentDate' AND exam_supplementary_id = '$examSupplementaryId";
        }
        try {
            $fineAmount = $this->executeQueryForObject($sql)->fineAmount;
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $fineAmount;
    }
    /**
     * @author Vishnu M
     */
    public function getSupplyImproveExamFees ( $examSupplementaryId, $examIds ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $examIds = $this->realEscapeString($examIds);
        $supplyImproveFees = [];
        
        $sql = "SELECT siaf.supply_feesAmount AS supplyFeeAmount, siaf.improve_feesAmount AS improveFeeAmount FROM supply_improve_exam_fees siaf INNER JOIN exam_feestype eft ON (siaf.examfeesID = eft.examfeesID) INNER JOIN subjects s ON (s.isTheory = eft.isTheory) INNER JOIN exam e ON (s.subjectID = e.subjectID) WHERE siaf.exam_supplementary_id = '$examSupplementaryId' AND e.examID IN ($examIds)";
        try {
            $supplyImproveFees = $this->executeQueryForList($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $supplyImproveFees;
    }
    /**
     * @author Vishnu M
     */
    public function generateSupplyImproveChallanNo () {
        $challanNo = null;
        $sql = "SELECT IF ( MAX(challanNo) , MAX(challanNo) + 1, 1) AS challanNo FROM exam_supplementary_student_details ";
        try {
            $challanNo = $this->executeQueryForObject($sql)->challanNo;
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $challanNo;
    }
    /**
     * @author Vishnu M
     */
    public function addSupplyImproveStudentSubjectDetails ( $supplyImprove ) {
        $values = [];
        $supplyImprove = $this->realEscapeObject($supplyImprove);
        try {
            $sqlDetails = "INSERT INTO exam_supplementary_student_details ( exam_supplementary_id, studentID, total_fees, challanNo, isSupply ) VALUES ( $supplyImprove->supplyId$supplyImprove->studentId,$supplyImprove->totalFees, '$supplyImprove->challanNo', $supplyImprove->isSupply )";
            $this->executeQuery($sqlDetails);
            $sqlSubjects = "INSERT INTO exam_supplementary_student_subjects (exam_supplementary_id, studentID, examID) VALUES ";
            foreach ( $supplyImprove->supplyImproveExamIds as $examId ) {
                $values[] = "($supplyImprove->supplyId$supplyImprove->studentId$examId)";
            }
            $sqlSubjects .= implode ( ",", $values );
            $this->executeQuery($sqlSubjects);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return true;
    }
    /**
     * Get supply exam publish from & to date
     * @param Integer $supplyRegId
     * @param Integer $batchId
     * @param Integer $semId
     * @throws ProfessionalException
     * @return Object $publishDates
     * @author Vishnu M
     */
    public function getSupplyPublishDate ( $supplyRegId, $batchId, $semId ) {
        $publishDates = null;
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        try {
            $sql = "SELECT fromDate, toDate FROM supplyexam_publishresult WHERE batchID = '$batchId' AND semID = '$semId' AND exam_supplementary_id = '$supplyRegId";
            $publishDates = $this->executeQueryForObject($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $publishDates;
    }
    public function saveSupplementary( $supplementary ) {
        $supplementary = $this->realEscapeObject($supplementary);
        $sql = null;
        try {
            $patternIds = implode(",", $supplementary->patternID);
            if ( $supplementary->id ) {
                $sql = "UPDATE exam_supplementary SET 
                            supplyDesc = '$supplementary->supplyDesc', 
                            examDate = '$supplementary->examDate', 
                            startDate = '$supplementary->startDate', 
                            endDate = '$supplementary->endDate', 
                            subjectLimit = $supplementary->subjectLimit
                            semID = $supplementary->semId
                            patternID = '$patternIds', 
                            enable_hlticket = $supplementary->enableHallTicket,     
                            examMonth = $supplementary->examMonth
                            examYear = $supplementary->examYear,
                            pimage = $supplementary->profileImage
                            simage = $supplementary->signatureImage
                            isSpecialExam = $supplementary->isSpecialExam
                            considerFlag = $supplementary->considerFlag,
                            allowNotification = $supplementary->allowNotification 
                        WHERE id = '$supplementary->id";
            }
            else {
                $sql = "INSERT IGNORE INTO exam_supplementary (supplyDesc, examDate, startDate, endDate, subjectLimit, semID, patternID, enable_hlticket, examMonth, examYear, pimage, simage, isSpecialExam, considerFlag, allowNotification) VALUES (
                    '$supplementary->supplyDesc', 
                    '$supplementary->examDate', 
                    '$supplementary->startDate', 
                    '$supplementary->endDate', 
                    '$supplementary->subjectLimit', 
                    '$supplementary->semId', 
                    '$patternIds', 
                    '$supplementary->enableHallTicket', 
                    '$supplementary->examMonth', 
                    '$supplementary->examYear',
                    '$supplementary->profileImage', 
                    '$supplementary->signatureImage', 
                    '$supplementary->isSpecialExam', 
                    '$supplementary->considerFlag', 
                    '$supplementary->allowNotification
                )";
            }
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Delete supply by id
     * @param Integer $examSupplementaryId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function deleteExamSupplementaryById ( $examSupplementaryId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $sql = null;
        try {
            $sql = "DELETE FROM exam_supplementary WHERE id = '$examSupplementaryId";
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    } 
    public function getExamSupplementaryBatchSubjectFees ($examSupplementaryId) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $sql = null;
        $batchSubjectFees = [];
        try {
            $sql = "SELECT 
                        sisf.id,
                        b.batchID AS batchId,
                        b.batchName,
                        b.batchDesc,
                        es.semID AS semId,
                        s.subjectID AS subjectId,
                        s.subjectName,
                        s.subjectDesc,
                        s.isTheory,
                        s.syllabusName,
                        eReg.examID AS examId,
                        sisf.examfeesID AS examFeesId,
                        eft.examfeesName AS examFeesName,
                        sisf.supply_subject_amount AS supplySubjectFees,
                        sisf.improve_subject_amount AS improveSubjectFees
                    FROM
                        exam_supplementary es
                            INNER JOIN
                        supply_improve_batches sib ON (es.id = sib.exam_supplementary_id)
                            INNER JOIN
                        sbs_relation sbs ON (sbs.batchID = sib.batchID
                            AND sbs.semID = es.semID)
                            INNER JOIN
                        subjects s ON (s.subjectID = sbs.subjectID)
                            INNER JOIN
                        batches b ON (sib.batchID = b.batchID)
                            INNER JOIN
                        exam eReg ON (eReg.subjectID = sbs.subjectID
                            AND eReg.batchID = sib.batchID
                            AND eReg.semID = sbs.semID
                            AND eReg.examregID is NOT NULL)
                        INNER JOIN
                        supply_improve_subject_fees sisf ON (sisf.exam_supplementary_id = es.id AND sisf.examID = eReg.examID)
                        INNER JOIN
                        exam_feestype eft ON (eft.examfeesID = sisf.examfeesID)
                    WHERE
                        es.id = '$examSupplementaryId' ORDER BY b.batchStartYear ASC, s.isTheory DESC";
            $batchSubjectFees = $this->executeQueryForList($sql, $this->mapper[ExamSupplementaryServiceMapper::GET_SUPPLEMENTARY_BATCH_SUBJECT_FEES]);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $batchSubjectFees;
    }
    /**
     * @author Vishnu M
     */
    public function getExamSupplementaryBatchSubject($courseTypeId, $batchStartYear, $supplementaryId, $considerAlreadyAssignedBatches = TRUE ) {
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $batchStartYear = $this->realEscapeString($batchStartYear);
        $supplementaryId = $this->realEscapeString($supplementaryId);
        $sql = null;
        $conditions = null;
        $batchSubject = [];
        
        if ( $considerAlreadyAssignedBatches === FALSE ) {
            $conditions .= " AND sbs.batchID NOT IN (SELECT batchID FROM supply_improve_batches WHERE exam_supplementary_id = '$supplementaryId' )";
        }
        try {
            $sql = "SELECT DISTINCT 
                        b.batchID AS batchId,
                        b.batchName, 
                        b.batchDesc, 
                        s.subjectID AS subjectId,
                        s.subjectName, 
                        s.subjectDesc, 
                        s.isTheory,
                        eReg.examID AS examId,
                        eft.examfeesID AS examFeesId,
                        eft.examfeesName AS examFeesName
                    FROM 
                        exam_supplementary es 
                            INNER JOIN 
                        batches b ON FIND_IN_SET(b.patternID, es.patternID) 
                            INNER JOIN 
                        sbs_relation sbs ON (sbs.batchID = b.batchID 
                            AND es.semID = sbs.semID) 
                            INNER JOIN 
                        subjects s ON (sbs.subjectID = s.subjectID) 
                            INNER JOIN 
                        exam eReg ON (eReg.subjectID = sbs.subjectID
                            AND eReg.batchID = sbs.batchID
                            AND eReg.semID = sbs.semID
                            AND eReg.examregID IS NOT NULL)
                            INNER JOIN
                        exam_feestype eft
                    WHERE 
                        es.id = $supplementaryId
                        AND b.courseTypeID = $courseTypeId
                        AND b.batchStartYear = $batchStartYear 
                        $conditions
                    ORDER BY b.batchstartYear ASC, b.batchName ASC, s.isTheory DESC";
                $batchSubject = $this->executeQueryForList($sql, $this->mapper[ExamSupplementaryServiceMapper::GET_SUPPLEMENTARY_BATCH_SUBJECT_FEES]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $batchSubject;
    }
    /**
     * @author Vishnu M
     */
    public function saveExamSupplementaryBatchSubjectFees ( $batchSubjectFees ) {
        $batchSubjectFees = (object) $this->realEscapeObject($batchSubjectFees);
        $request = new \stdClass();
        $request->batchId = $batchSubjectFees->id;
        $request->supplementaryId = $batchSubjectFees->supplementaryId;
        $this->saveSupplyImproveBatches ( $request );
        $supplyImproveExamFeesArray = [];
        foreach ( $batchSubjectFees->subjects as $subject ) {
            $subject = (object) $subject;
            $supplyImproveFees = (object) $subject->supplyImproveFees;
            $supplyImproveSubjectFees = new \stdClass();
            $supplyImproveSubjectFees->supplementaryId = $batchSubjectFees->supplementaryId;
            $supplyImproveSubjectFees->examId = $subject->examId;
            $supplyImproveSubjectFees->examFeesId = $supplyImproveFees->id;
            $supplyImproveSubjectFees->supplySubjectFees = $supplyImproveFees->supplySubjectFees;    
            $supplyImproveSubjectFees->improveSubjectFees = $supplyImproveFees->improveSubjectFees;  
            $supplyImproveSubjectFeesArray[] = $supplyImproveSubjectFees;
            if ( !isset ( $supplyImproveExamFeesArray[$supplyImproveFees->id] ) ) {
                $supplyImproveExamFees = new \stdClass();
                $supplyImproveExamFees->supplementaryId = $batchSubjectFees->supplementaryId; 
                $supplyImproveExamFees->id = $supplyImproveFees->id; 
                $supplyImproveExamFees->supplyFees = $supplyImproveFees->supplySubjectFees; 
                $supplyImproveExamFees->improveFees = $supplyImproveFees->improveSubjectFees; 
                $supplyImproveExamFeesArray[$supplyImproveFees->id] = $supplyImproveExamFees;
            }
        }
        $this->saveSupplyImproveSubjectFees ( $supplyImproveSubjectFeesArray );
        $this->saveSupplyImproveExamFees ( $supplyImproveExamFeesArray );
    }
    /**
     * @author Vishnu M
     */
    public function saveSupplyImproveBatches ( $request ) {
        $request = $this->realEscapeObject($request);
        $sql = null;
        try {
            $sql = "INSERT IGNORE INTO supply_improve_batches (batchID, current_semID, exam_supplementary_id) SELECT batchID, semID, '$request->supplementaryId' FROM batches WHERE batchID = '$request->batchId";
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @author Vishnu M
     */
    public function saveSupplyImproveSubjectFees ( $supplyImproveSubjectFeesArray ) {
        $supplyImproveSubjectFeesArray = $this->realEscapeArray($supplyImproveSubjectFeesArray);
        $sql = null;
        try {
            foreach ( $supplyImproveSubjectFeesArray as $supplyImproveSubjectFees ) {
                $supplyImproveSubjectFees->supplySubjectFees   = $supplyImproveSubjectFees->supplySubjectFees ? $supplyImproveSubjectFees->supplySubjectFees :0;
                $supplyImproveSubjectFees->improveSubjectFees  = $supplyImproveSubjectFees->improveSubjectFees ? $supplyImproveSubjectFees->improveSubjectFees :0;
                $values[] = "(
                    $supplyImproveSubjectFees->supplementaryId,
                    $supplyImproveSubjectFees->examId,
                    $supplyImproveSubjectFees->examFeesId,
                    $supplyImproveSubjectFees->supplySubjectFees,    
                    $supplyImproveSubjectFees->improveSubjectFees    
                )";
            }
            if ( !empty ( $values ) ) {
                $sql = "INSERT INTO supply_improve_subject_fees (exam_supplementary_id, examID, examfeesID, supply_subject_amount, improve_subject_amount) VALUES " . implode ( ", ", $values ) . 
                ON DUPLICATE KEY UPDATE 
                    supply_subject_amount = VALUES(supply_subject_amount),
                    improve_subject_amount = VALUES(improve_subject_amount)";
                $this->executeQuery($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @author Vishnu M
     */
    public function saveSupplyImproveExamFees ( $supplyImproveExamFeesArray ) {
        $supplyImproveExamFees = $this->realEscapeArray($supplyImproveExamFeesArray);
        $sql = null;
        try {
            if ( !empty ( $supplyImproveExamFees ) ) {
                $sql = "INSERT INTO supply_improve_exam_fees (exam_supplementary_id, examfeesID, supply_feesAmount, improve_feesAmount) VALUES ";
                $values = [];
                foreach ( $supplyImproveExamFees as $fees ) {
                    $values[] = "(
                        '$fees->supplementaryId',
                        '$fees->id',
                        '$fees->supplyFees',
                        '$fees->improveFees'
                    )";
                }
                $sql .= implode ( ",", $values ) . " ON DUPLICATE KEY UPDATE supply_feesAmount = VALUES(supply_feesAmount), improve_feesAmount = VALUES(improve_feesAmount)";
                $this->executeQuery($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Delete supply improve batches & subject fees
     * 
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function deleteExamSupplementaryBatchSubjectFees ( $batchSubjectFees ) {
        $batchSubjectFees = (object) $this->realEscapeObject($batchSubjectFees);
        $examSupplementaryId = $batchSubjectFees->supplementaryId;
        $this->deleteSupplyImproveBatches ( $examSupplementaryId, $batchSubjectFees->id );
        foreach ( $batchSubjectFees->subjects as $subject ) {
            $subject = (object) $subject;
            $examIdArr[] = $subject->examId;
        }
        $this->deleteSupplyImproveSubjectFees ( $examSupplementaryId, $examIdArr );
    }
    /**
     * Delete supply improve batches
     * @param Integer $examSupplementaryId
     * @param Integer $batchId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function deleteSupplyImproveBatches ( $examSupplementaryId, $batchId ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $batchId = $this->realEscapeString($batchId);
        $sql = null;
        try {
            $sql = "DELETE FROM supply_improve_batches WHERE exam_supplementary_id = '$examSupplementaryId' AND batchID = '$batchId";
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Delete supply improve subject fees
     * @param Integer $examSupplementaryId
     * @param Array $examIdArr
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function deleteSupplyImproveSubjectFees ( $examSupplementaryId, $examIdArr ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $examIdArr = $this->realEscapeArray($examIdArr);
        $examIds = implode(", ", $examIdArr);
        $sql = null;
        try {
            $sql = "DELETE FROM supply_improve_subject_fees WHERE exam_supplementary_id = '$examSupplementaryId' AND examID IN ($examIds";
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Save supply/improvement Common fees & fine
     * @param ExamSupplementaryRegistrationFees $supplyImproveRegFeeFine
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function saveExamSupplementaryRegistrationFeesFine ( $supplyImproveRegFeeFine ) {
        $supplyImproveRegFeeFine = $this->realEscapeObject($supplyImproveRegFeeFine);
        $sql = null;
        $registrationType = "supplementary";
        try {
            if ( $supplyImproveRegFeeFine->supplementaryId ) {
                $paymentOptions = [1, 2, 3];
                if ( !empty ( $supplyImproveRegFeeFine->paymentOptions ) ) {
                    $sql = "INSERT IGNORE INTO exam_paymentmethod_settings (exam_paymentmethod_id, exam_registration_type, exam_registration_type_id) VALUES ";
                    foreach ( $supplyImproveRegFeeFine->paymentOptions as $paymentOption ) {
                        $values[] = "(
                            $paymentOption,
                            '$registrationType',
                            $supplyImproveRegFeeFine->supplementaryId
                        )";
                    } 
                    $sql .= implode ( ",", $values );
                    $this->executeQuery($sql);
                    $deletePaymentOptions = array_diff($paymentOptions, $supplyImproveRegFeeFine->paymentOptions);
                    if ( !empty ( $deletePaymentOptions ) ) {
                        $sql = "DELETE FROM exam_paymentmethod_settings WHERE exam_paymentmethod_id IN (".implode ( ",", $deletePaymentOptions ).") AND exam_registration_type = '$registrationType' AND exam_registration_type_id = $supplyImproveRegFeeFine->supplementaryId ";
                        $this->executeQuery($sql);
                    }
                }
                
                if ( !empty ( $supplyImproveRegFeeFine->supplementaryFees ) ) {
                    $sql = "INSERT INTO supply_improve_exam_fees (exam_supplementary_id, examfeesID, supply_feesAmount, improve_feesAmount) VALUES ";
                    $values = [];
                    foreach ( $supplyImproveRegFeeFine->supplementaryFees as $fees ) {
                        $values[] = "(
                            $supplyImproveRegFeeFine->supplementaryId,
                            '$fees->id',
                            '$fees->supplyFees',
                            '$fees->improveFees'
                        )";
                    }
                    $sql .= implode ( ",", $values ) . " ON DUPLICATE KEY UPDATE supply_feesAmount = VALUES(supply_feesAmount), improve_feesAmount = VALUES(improve_feesAmount)";
                    $this->executeQuery($sql);
                }
                if ( !empty ( $supplyImproveRegFeeFine->supplementaryFine ) ) {
                    $sql = "INSERT INTO supply_improve_exam_fine (exam_supplementary_id, examfineID, supply_fineAmount, supply_startDate, supply_endDate, improve_fineAmount, improve_startDate, improve_endDate, supply_verification_date, improvement_verification_date) VALUES ";
                    $values = [];
                    foreach ( $supplyImproveRegFeeFine->supplementaryFine as $fine ) {
                        $values[] = "(
                            $supplyImproveRegFeeFine->supplementaryId,
                            '$fine->id',
                            '$fine->supplyFineAmount',
                            '$fine->supplyStartDate',
                            '$fine->supplyEndDate',
                            '$fine->improveFineAmount',
                            '$fine->improveStartDate',
                            '$fine->improveEndDate',
                            '$fine->supplyVerificationDate',
                            '$fine->improveVerificationDate'
                        )";
                    }
                    $sql .= implode ( ",", $values ) . " ON DUPLICATE KEY UPDATE 
                        supply_fineAmount   = VALUES(supply_fineAmount),
                        supply_startDate   = VALUES(supply_startDate),
                        supply_endDate     = VALUES(supply_endDate),
                        improve_fineAmount  = VALUES(improve_fineAmount),
                        improve_startDate  = VALUES(improve_startDate),
                        improve_endDate    = VALUES(improve_endDate),
                        supply_verification_date      = VALUES(supply_verification_date),
                        improvement_verification_date = VALUES(improvement_verification_date)";
                    $this->executeQuery($sql);
                }
            }
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    public function enableDisableSupplementaryHallTicket ( $examSupplementaryId, $enableHallTicket ) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $enableHallTicket = $this->realEscapeString($enableHallTicket);
        $sql = null;
        try {
            $sql = "UPDATE exam_supplementary SET enable_hlticket = $enableHallTicket WHERE id = '$examSupplementaryId";
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Get Supply/Improve exam registration batches
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getSupplyImproveBatches ( $request ) {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if($request->batchId){
            $condition .=" AND b.batchID IN ($request->batchId)";
        }
        $batches = null;
        try {
            $sql = "SELECT sib.batchID AS id, b.batchName AS name, es.semID AS semId, ct.typeName AS courseTypeName, b.courseTypeID AS courseTypeId,ct.course_Type FROM exam_supplementary es INNER JOIN supply_improve_batches sib ON (sib.exam_supplementary_id = es.id) INNER JOIN batches b ON (b.batchID = sib.batchID) LEFT JOIN course_type ct ON ct.courseTypeID = b.courseTypeID WHERE es.id = '$request->supplyRegId$condition";
            
            $batches = $this->executeQueryForList($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $batches;
    }
    /**
     * Get supply / improvement registered student subject details by examSupplementaryId and studentId
     * @param Integer $examSupplementaryId
     * @param Integer $studentId
     * @return Array $details
     * @throws ProfessionalException
     * @author Sibin 
     */
    public function getSupplyImproveRegisteredStudentSubjectDetailswithSubjectCat($examSupplementaryId, $studentId)
    {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $studentId = $this->realEscapeString($studentId);
        $sql = null;
        $details = [];
        $sql = "SELECT esss.exam_supplementary_id, 
                        esss.studentID, esss.examID, 
                        esss.approveImprovementMarkStatus, 
                        s.subjectID, 
                        s.subjectName, 
                        s.subjectDesc, 
                        s.syllabusName ,
                        s.isTheory,
                        s.subjectcatID,
                        sc.subjectcatName
                        FROM exam_supplementary_student_subjects esss 
                        INNER JOIN exam e ON (e.examID = esss.examID) 
                        INNER JOIN subjects s ON (e.subjectID = s.subjectID) 
                        INNER JOIN subject_category sc ON sc.subjectcatID = s.subjectcatID 
                        WHERE esss.exam_supplementary_id = '$examSupplementaryId' AND esss.studentID = '$studentId";
        try {
            $details = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $details;
    }
    /**
     * Get supply / improvement student mark details
     * @throws ProfessionalException
     * @author Sibin 
     */
    public function getSupplyImproveMarksByStudent($request)
    {
        $request =$this->realEscapeObject($request);
        $sql = null;
        $studentMarkDetails = [];
        $limit = (int) $request->limit;
        $isSupply = (int) $request->isSupply;
        $courseTypeUG = CourseTypeConstants::UG;
        $courseTypeUGPRO = CourseTypeConstants::UG_PRO;
        $sql = "SELECT DISTINCT
                    e.examDate,
                    sa.studentID,
                    sa.studentName,
                    sa.regNo,
                    ea.isAbsent,
                    s.subjectName,
                    s.subjectDesc,
                    essd.isSupply AS isSupplyImprove,
                    t1.examregID AS regular_examRegID,
                    esss.examID AS regularExamId,
                    es.id AS supply_examregID,
                    es.supplyDesc,
                    e.examID AS supplyExamId,
                    e.examName,
                    e.examTotalMarks AS externalMax,
                    e.subjectID,
                    e.batchID,
                    e.semID,
                    IF(ct.course_Type IN ('$courseTypeUG','$courseTypeUGPRO'), ee.id, eef.examfinalizeID) AS markId,
                    IF(ct.course_Type IN ('$courseTypeUG','$courseTypeUGPRO'), ee.mark, eef.mark) AS externalMark
                FROM
                    exam_supplementary_student_subjects esss
                        INNER JOIN
                    exam_supplementary_student_details essd 
                        ON esss.exam_supplementary_id = essd.exam_supplementary_id
                        AND esss.studentID = essd.studentID
                        INNER JOIN
                    studentaccount sa ON sa.studentID = essd.studentID
                        INNER JOIN 
                    exam_supplementary es ON es.id = esss.exam_supplementary_id
                        INNER JOIN
                    exam t1 ON t1.examID = esss.examID
                        INNER JOIN 
                    exam e ON e.subjectID = t1.subjectID
                        AND e.batchID = t1.batchID
                        AND e.supply_examreg_id = esss.exam_supplementary_id
                        INNER JOIN
                    subjects s ON e.subjectID = s.subjectID
                        INNER JOIN
                    exam_type et ON et.typeID = e.examTypeID
                        INNER JOIN
                    batches b ON b.batchID = e.batchID
                        INNER JOIN 
                    course_type ct ON ct.courseTypeID = b.courseTypeID
                        LEFT JOIN
                    exammarks_external ee ON ee.examID = e.examID
                        AND sa.studentID = ee.studentID
                        LEFT JOIN
                    externalexammarks_finalized eef ON eef.examID = e.examID
                        AND sa.studentID = eef.studentID
                        LEFT JOIN
                    exam_attendance ea ON ea.examID = e.examID
                        AND ea.studentID = sa.studentID
                        LEFT JOIN 
                    exam_subjectcredit esc ON esc.subjectID = e.subjectID
                        AND esc.semID = e.semID
                        AND esc.batchID = e.batchID
                        LEFT JOIN
                    failed_students fs ON fs.studentID = sa.studentID
                        AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                WHERE
                    essd.paid = 1 AND essd.approved = 1
                        AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID)
                         AND essd.isSupply = '$isSupply'  AND sa.studentID IN ('$request->studentId')  AND sa.batchID IN ('$request->batchId')  AND e.semID IN ('$request->semId') AND esss.examID='$request->examId'
                ORDER BY es.examYear ASC, IF(CAST(es.examMonth AS SIGNED) = 0, 99999, CAST(es.examMonth AS SIGNED)) ASC, e.semID ASC limit $limit";
        try {
            $studentMarkDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentMarkDetails;
    }
  /**
     * Get Student Exam Supply Registrations By Sem 
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getStudentExamSupplyRegistrationsBySem ( $request ) {
        $request = $this->realEscapeObject($request);
        $supplyRegs = null;
        try {
            $sql = "SELECT essd.id,essd.exam_supplementary_id,essd.isSupply from exam_supplementary_student_details essd
                        INNER JOIN exam_supplementary es ON es.id = essd.exam_supplementary_id
                        WHERE es.semID = '$request->semId
                        and essd.studentID = '$request->studentId'
                        AND essd.paid = 1
                        AND essd.approved = 1
                        ORDER BY IF(CAST(es.examYear AS SIGNED) = 0, 99999, CAST(es.examYear AS SIGNED)) ,IF(CAST(es.examMonth AS SIGNED) = 0, 99999, CAST(es.examMonth AS SIGNED))";
            
            $supplyRegs = $this->executeQueryForList($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $supplyRegs;
    }
    
    /**
     * Get Supply Exam By SupplyRegId,Batch,Sem 
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getSupplyExamBySupplyRegIdAndBatchAndSem($request)
    {
        $request = $this->realEscapeObject($request);
        $supplyExam = null;
        try {
            $sql = "SELECT e.examID ,e.examName,e.subjectID,e.examTotalMarks from exam e
                        INNER JOIN exam_supplementary_student_subjects esss ON esss.exam_supplementary_id = e.supply_examreg_id
                        WHERE e.supply_examreg_id = '$request->supplyRegId' and semID = '$request->semId' and batchID='$request->batchId' and e.subjectID = '$request->subjectId'
                        AND esss.studentID ='$request->studentId' and esss.examID='$request->regularExamId'";
            $supplyExam = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyExam;
    }
     /* @author Sibin
     * get supply exam reg students by batch and subjectid
     */
    public function getSupplyExamRegisteredStudentsByBatchAndSubjectId($examRegId, $batchId, $subjectId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "SELECT essd.exam_supplementary_id,e.examID,se.examID as supplyExamId,essd.studentID,sa.regNo,sa.studentName from exam_supplementary_student_details essd
                    INNER JOIN exam e ON e.batchID='$batchId' and e.subjectID='$subjectId' and examregID IS NOT NULL
                    INNER JOIN exam se ON se.batchID='$batchId' and se.subjectID='$subjectId' and se.supply_examreg_id = '$examRegId'
                    INNER JOIN exam_supplementary_student_subjects esss 
                        on esss.exam_supplementary_id = essd.exam_supplementary_id and esss.examID = e.examID and esss.studentID = essd.studentID
                    INNER JOIN studentaccount sa on sa.studentID=essd.studentID
                    WHERE essd.exam_supplementary_id='$examRegId' and sa.batchID='$batchId' and essd.paid=1
                    order by sa.regNo";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    /**
     * get batch exam month yearsof supply
     */
    public function getExamMonthYearsOfBatch($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT DISTINCT
            DATE_FORMAT(CONCAT(er.examYear,'-',er.examMonth,'-','1'),'%Y%m') AS regularExamMonth,
            DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y%m') AS supplyExamMonth,
            DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y-%c') AS id,
            DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y %b') name
        FROM
            exam_registration er
        INNER JOIN exam_registration_batches erb ON
            erb.examregID = er.examregID
        INNER JOIN supply_improve_batches sib ON
            sib.batchID = erb.batchID
        INNER JOIN exam_supplementary es ON
            es.id = sib.exam_supplementary_id
        WHERE erb.batchID = $batchId
        ORDER BY name";
        try {
            $examMonthYears  = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examMonthYears;
    }
      /**
     * Get supply / improvement registered student subject details by examSupplementaryId and studentId
     * @param Integer $examSupplementaryId
     * @param Integer $studentId
     * @return Array $details
     * @throws ProfessionalException
     */
    public function getSupplyImproveRegisteredStudentByBatchSemRelation($examSupplementaryId, $studentId)
    {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $studentId = $this->realEscapeString($studentId);
        $sql = null;
        $details = [];
        $sql = "SELECT esss.exam_supplementary_id, 
                    esss.studentID, esss.examID, 
                    esss.approveImprovementMarkStatus, 
                    s.subjectID, 
                    s.subjectName, 
                    s.subjectDesc, 
                    s.syllabusName ,
                    s.isTheory,
                    bss.subjectcatID,
                    sc.subjectcatName
                    FROM exam_supplementary_student_subjects esss 
                    INNER JOIN exam e ON (e.examID = esss.examID) 
                    INNER JOIN subjects s ON (e.subjectID = s.subjectID) 
                    INNER JOIN batch_sem_subjectCategory_relation bss ON (bss.batchID = e.batchID and bss.semID = e.semID and bss.subjectID =e.subjectID )
                    INNER JOIN subject_category sc ON (sc.subjectcatID = bss.subjectcatID) 
                    WHERE esss.exam_supplementary_id = '$examSupplementaryId' AND esss.studentID = '$studentId";
        try {
            $details = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $details;
    }
    /**
     *  get distinct ExamSupplementary Years
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamSupplementaryMonthYears()
    {
        $sql = null;
        $years = null;
        try {
            $sql = "SELECT distinct CONCAT(examYear,examMonth) as id ,CONCAT(examYear,'-',examMonth) as name,examYear,examMonth  from exam_supplementary 
                        ORDER BY IF(CAST(examYear AS SIGNED) = 0, 99999, CAST(examYear AS SIGNED)) desc,IF(CAST(examMonth AS SIGNED) = 0, 99999 , CAST(examMonth AS SIGNED)) desc;";
            $years = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $years;
    }
    public function getExamSupplementaryByMonthAndYear($examMonthYear)
    {
        $examMonthYear = $this->realEscapeString($examMonthYear);
        $sql = null;
        $examSupplementary = null;
        $sql = "SELECT id FROM exam_supplementary WHERE CONCAT(examYear,examMonth) IN($examMonthYear)";
        try {
            $examSupplementary = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examSupplementary;
    }
    public function getExamSupplementaryStudentsBySupplyRegAndBatch($supplyReg, $batchId)
    {
        $supplyReg = $this->realEscapeString($supplyReg);
        $batchId = $this->realEscapeString($batchId);
        $sql = null;
        $examSupplementaryStudents = null;
        $sql = "SELECT distinct essd.studentID from exam_supplementary_student_details essd 
                    INNER JOIN exam_supplementary_student_subjects esss ON esss.studentID = essd.studentID AND esss.exam_supplementary_id = essd.exam_supplementary_id
                    INNER JOIN studentaccount sa ON sa.studentID = essd.studentID
                    WHERE essd.exam_supplementary_id IN ($supplyReg) and sa.batchID IN ($batchId)";
        try {
            $examSupplementaryStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examSupplementaryStudents;
    }
    public function getExamSupplementaryPublishDateByBatchAndMonthYear($publishDateRequest)
    {
        $publishDateRequest = $this->realEscapeObject($publishDateRequest);
        $sql = null;
        $publishDate = null;
        $sql = "SELECT MAX(sp.fromDate) as publishDate from exam_supplementary es
                    INNER JOIN supplyexam_publishresult sp  ON sp.exam_supplementary_id = es.id 
                    where es.examYear='$publishDateRequest->examYear' AND es.examMonth='$publishDateRequest->examMonth'
                    AND sp.batchID='$publishDateRequest->batchId'";
        try {
            $publishDate = $this->executeQueryForObject($sql)->publishDate;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $publishDate;
    }
    /**
     * Get Student Exam Supply Registrations By Sem 
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getStudentExamSupplyRegistrationsByStudent($request)
    {
        $request = $this->realEscapeObject($request);
        if($request->examYear){
            $condition =" AND es.examYear IN($request->examYear)";
        }
        if ($request->examYearFrom) {
            $condition .= " AND es.examYear >= '$request->examYearFrom";
        }
        $supplyRegs = null;
        try {
            $sql = "SELECT es.supplyDesc as name,essd.exam_supplementary_id as id,essd.isSupply,essd.paid,es.semId from exam_supplementary_student_details essd
                        INNER JOIN exam_supplementary es ON es.id = essd.exam_supplementary_id
                        WHERE essd.studentID = '$request->studentId'
                        $condition
                        ORDER BY es.examYear  DESC,es.semId DESC";
            $supplyRegs = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyRegs;
    }
    /**
     * Get student supply exam subjects
     * @param Object
     * @return Array Exam subject list
     * @throws ProfessionalException
     * @author sibin
     */
    public function getStudentSupplyExamSubjects($request)
    {
        $request = $this->realEscapeObject($request);
        $subjects = [];
        $sql = "SELECT ers.studentID,ers.exam_supplementary_id as examregID,e.semID,e.examID,e.examName,e.examTotalMarks,e.examDate,e.examStartTime,e.examEndTime,e.subjectID,s.syllabusName,s.subjectName,s.subjectDesc
                    from exam_supplementary_student_subjects ers
                        INNER JOIN exam e2 ON e2.examID = ers.examID
                        INNER JOIN exam e ON e.subjectID = e2.subjectID AND e.supply_examreg_id = ers.exam_supplementary_id
                        INNER JOIN subjects s ON s.subjectID = e.subjectID
                        where ers.exam_supplementary_id='$request->examRegId
                            and e.batchID='$request->batchId'
                            and e.semID='$request->semId'
                            and ers.studentID='$request->studentId'";
        try {
            $subjects = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    /**get all exam supplementary 
     * @author Sibin
     */
    public function getAllRegisteredSupplyExams($showFutureExamsOnly = FALSE)
    {
        $sql = "SELECT id, supplyDesc as name, semID AS semId ,examYear,examMonth FROM exam_supplementary ";
        if ($showFutureExamsOnly) {
            $month = (int)date("m");
            $year = (int)date("Y") - 1;
            $sql .= " WHERE examMonth >= " . $month . " AND examYear >= " . $year;
        }
        $sql .= " ORDER BY IF(CAST(examYear AS SIGNED) = 0, 99999, CAST(examYear AS SIGNED)) DESC,IF(CAST(examMonth AS SIGNED) = 0, 99999, CAST(examMonth AS SIGNED)) DESC ";
        try {
            $supply = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supply;
    }
    /**get gExamSupplementary Registration SubjectDetails with student count
     * @author Sibin
     */
    public function getExamSupplementaryRegSubjectDetails($supplyExamRegId)
    {
        $supplyExamRegId = $this->realEscapeString($supplyExamRegId);
        $supplyExamRegSubjectDetails=[];
        $sql = "SELECT e.examID as regularExamId,count(e.examID) AS  examRegStudentCount,s.subjectID,s.subjectName,s.subjectDesc ,ex.examID as supplyExamId,
                ex.examDate ,ex.examStartTime,CONCAT(ex.examDate ,' ',ex.examStartTime) as examDateTime,
                CONCAT(DATE_FORMAT(ex.examDate,'%d-%m-%Y'),' ',ex.examStartTime) as examDateTimeFormatted 
                FROM exam_supplementary_student_subjects esss 
                INNER JOIN exam e ON e.examID = esss.examID 
                INNER JOIN subjects s ON s.subjectID = e.subjectID
                INNER JOIN exam ex ON ex.supply_examreg_id = esss.exam_supplementary_id and ex.batchID = e.batchID and ex.semID = e.semID and  ex.subjectID = e.subjectID 
                where esss.exam_supplementary_id = '$supplyExamRegId' GROUP BY e.examID order by e.examID";
        try {
            $supplyExamRegSubjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyExamRegSubjectDetails;
    }
     /**
     * get Exam Registration Details By Course Type And Batch StartYear
     */
    public function getExamRegistrationDetailsByCourseTypeAndBatchStartYear($courseTypeId, $batchStartYear)
    {
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $batchStartYear = $this->realEscapeString($batchStartYear);
        $sql = "SELECT DISTINCT
            DATE_FORMAT(CONCAT(er.examYear,'-',er.examMonth,'-','1'),'%Y%m') AS regularExamMonth,
            DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y%m') AS supplyExamMonth,
            DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y-%c') AS id,
            DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y %b') name,
            er.examregID as examRegID,
            er.examregName as examregName,
            es.id as supplyRegId,
            es.supplyDesc as supplyDesc
        FROM
            exam_registration er
        INNER JOIN exam_registration_batches erb ON
            erb.examregID = er.examregID
        INNER JOIN supply_improve_batches sib ON
            sib.batchID = erb.batchID
        INNER JOIN exam_supplementary es ON
            es.id = sib.exam_supplementary_id
        INNER JOIN batches bt ON
            bt.batchID = sib.batchID and bt.batchID = erb.batchID 
        WHERE bt.batchStartYear = $batchStartYear and bt.courseTypeID = $courseTypeId
        ORDER BY name";
        try {
            $examMonthYears  = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examMonthYears;
    }
     /**
     * get supply batches by supplyIds
     */
    public function getSupplyBatchesBySupplyIds($supplyIds)
    {
        $supplyIds = $this->realEscapeString($supplyIds);
        $sql = "SELECT DISTINCT
                ex.batchID as batchId, b.batchName AS batchName 
            FROM 
                exam ex  
            INNER JOIN batches b ON 
                (ex.batchID = b.batchID) 
            WHERE 
                ex.supply_examreg_id in ($supplyIds)";
        try {
            $supplyBatches  = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyBatches;
    }
     /**
     * @param $batchId
     * @param $month
     * @param $year
     * save program result month and year
     */
    public function saveSupplyProgramResultMonthAndYear($batchId,$month,$year)
    {
        $batchId = $this->realEscapeString($batchId);
        $month = $this->realEscapeString($month);
        $year = $this->realEscapeString($year);
        $user = $_SESSION['adminID'];
        $date = date("Y-m-d");
        $sql = "SELECT * from supply_program_resuslt_date WHERE batchID ='$batchId'";
        try {
            $result = $this->executeQueryForList($sql);
            if(empty($result)){
                $sql1 = "INSERT INTO supply_program_resuslt_date(batchID,examMonth,examYear,created_by,created_date) VALUES('$batchId',$month,$year,$user, '$date')";
            }
            else{
                $condition = "NULL";
                if($month){
                    $condition = "examMonth='$month'";
                    if($year){
                        $condition .= " ,examYear='$year'";
                    }
                }
                else{
                    $condition = "examYear='$year'";
                }
                $condition .= ",updated_by='$user', updated_date='$date'";
                $sql1 = "UPDATE supply_program_resuslt_date set ".$condition." WHERE batchID =$batchId";
            }
            $this->executeQuery($sql1);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
      /**
     * @param $batchId
     * get program result month and year
     */
    public function getSupplyProgramResultMonthAndYear($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT examMonth, examYear from supply_program_resuslt_date WHERE batchID ='$batchId'";
        try {
            $result = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result [0];
    }
         /**
     * @param $studentId
     * @param $supplyIds
     * get program result month and year
     */
    public function getSupplyRegisteredStudentDetails($studentId, $supplyIds)
    {
        $studentId = $this->realEscapeString($studentId);
        $supplyIds = $this->realEscapeString($supplyIds);
        $sql = "SELECT studentID from exam_supplementary_student_details essd where studentID =$studentId and exam_supplementary_id IN ($supplyIds)";
        try {
            $result = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
        /**
     * For changing examSupplementaryId
     * @param $batchId
     * @param $semId
     * @param $supplyRegId
     * @param $oldSupplyRegId
     */
    public function changeSupplyExamRegistration($batchId,$semId,$supplyRegId,$oldSupplyRegId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $oldSupplyRegId = $this->realEscapeString($oldSupplyRegId);
        try {
        $sql = "UPDATE IGNORE supply_improve_subject_fees es inner join exam ex on (es.examID = ex.examID ) set es.exam_supplementary_id =$supplyRegId where  es.exam_supplementary_id =$oldSupplyRegId and ex.batchID =$batchId and semID =$semId";
        $this->executeQuery($sql);
        $sql1 = "UPDATE IGNORE supply_improve_batches set exam_supplementary_id=$supplyRegId where exam_supplementary_id =$oldSupplyRegId and batchID =$batchId";
        $this->executeQuery($sql1);
        $sql2 = "UPDATE IGNORE exam_supplementary_student_details es inner join studentaccount sa on (es.studentID = sa.studentID ) set es.exam_supplementary_id =$supplyRegId where  es.exam_supplementary_id =$oldSupplyRegId and sa.batchID = $batchId";
        $this->executeQuery($sql2);
        $sql3 = "UPDATE IGNORE exam_supplementary_student_subjects es inner join studentaccount sa on (es.studentID = sa.studentID ) set es.exam_supplementary_id =$supplyRegId where  es.exam_supplementary_id =$oldSupplyRegId and sa.batchID = $batchId";
        $this->executeQuery($sql3);
        $sql4 = "UPDATE exam set supply_examreg_id =$supplyRegId where batchID =$batchId and semID =$semId and supply_examreg_id =$oldSupplyRegId";
        $this->executeQuery($sql4);
        
        $sql5 = "DELETE es FROM supply_improve_subject_fees es inner join exam ex on (es.examID = ex.examID ) where  es.exam_supplementary_id =$oldSupplyRegId and ex.batchID =$batchId and semID =$semId";
        $this->executeQuery($sql5);
        $sql6 = "DELETE FROM supply_improve_batches where exam_supplementary_id =$oldSupplyRegId and batchID =$batchId";
        $this->executeQuery($sql6);
        $sql7 = "DELETE es FROM exam_supplementary_student_details es inner join studentaccount sa on (es.studentID = sa.studentID ) where  es.exam_supplementary_id =$oldSupplyRegId and sa.batchID = $batchId";
        $this->executeQuery($sql7);
        $sql8 = "DELETE es FROM exam_supplementary_student_subjects es inner join studentaccount sa on (es.studentID = sa.studentID ) where  es.exam_supplementary_id =$oldSupplyRegId and sa.batchID = $batchId";
        $this->executeQuery($sql8);
        $sql9 = "DELETE FROM exam where batchID =$batchId and semID =$semId and supply_examreg_id =$oldSupplyRegId";
        $this->executeQuery($sql9);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
      /**
     * @param $studentId
     * @param $supplyIds
     * get program result month and year
     */
    public function deleteExamsOfSimilarRegistrations($batchId, $semId, $supplyRegId,$oldSupplyRegId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $sql = "SELECT e.examID from 
        exam e 
        inner join 
        exammarks_external ee 
        on (e.examID = ee.examID ) 
        WHERE e.batchID =$batchId and e.semID =$semId and e.supply_examreg_id =$supplyRegId";
        try {
            $markTable1 = $this->executeQueryForList($sql);
            $sql2 = "SELECT e.examID from 
            exam e 
            inner join 
            externalexammarks_finalized ee 
            on (e.examID = ee.examID ) 
            WHERE e.batchID =$batchId and e.semID =$semId and e.supply_examreg_id =$supplyRegId";
            $markTable2 = $this->executeQueryForList($sql2);
            $sql3 = "SELECT e.examID from 
            exam e 
            inner join 
            externalexammarks_finalized ee 
            on (e.examID = ee.examID ) 
            WHERE e.batchID =$batchId and e.semID =$semId and e.supply_examreg_id =$oldSupplyRegId";
            $markTable3 = $this->executeQueryForList($sql3);
            
            $sql4 = "SELECT e.examID from 
            exam e 
            inner join 
            exammarks_external ee 
            on (e.examID = ee.examID ) 
            WHERE e.batchID =$batchId and e.semID =$semId and e.supply_examreg_id =$oldSupplyRegId";
            $markTable4 = $this->executeQueryForList($sql4);
    
            if(empty($markTable1) && empty($markTable2)){
                $sql3 = "DELETE FROM supply_improve_batches where exam_supplementary_id =$supplyRegId and batchID =$batchId";
                $this->executeQuery($sql3);
                $sql4 = "DELETE FROM exam where batchID =$batchId and semID =$semId and supply_examreg_id =$supplyRegId";
                $this->executeQuery($sql4);
                return 1;
            }
            elseif(empty($markTable3) && empty($markTable4)){
                $sql3 = "DELETE FROM supply_improve_batches where exam_supplementary_id =$oldSupplyRegId and batchID =$batchId";
                $this->executeQuery($sql3);
                $sql4 = "DELETE FROM exam where batchID =$batchId and semID =$semId and supply_examreg_id =$oldSupplyRegId";
                $this->executeQuery($sql4);
                return 2;
            }
            else{
                return 0;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function enableDisableSupplementaryNominalRole($examSupplementaryId) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $sql = null;
        try {
            $sql = "UPDATE exam_supplementary SET enableNominalRole = !enableNominalRole WHERE id = '$examSupplementaryId";
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
         /**
     * get Distinct Supply Registration Details By Course Type And Batch StartYear
     */
    public function getDistinctSupplyRegistratin($courseTypeId, $batchStartYear)
    {
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $batchStartYear = $this->realEscapeString($batchStartYear);
        $sql = "SELECT DISTINCT es.id as supplyRegId , es.supplyDesc FROM supply_improve_batches sib inner join exam_supplementary es on (es.id = sib.exam_supplementary_id) inner join batches bt on (bt.batchID = sib.batchID ) where bt.batchStartYear =$batchStartYear and bt.courseTypeID =$courseTypeId  ORDER BY es.examYear Desc";
        try {
            $examDetails  = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
    /**
     * Get exam supply registrations by admission year,courseType
     * @param int $admissionyear,$courseType
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     * @author sibin
     */
    public function getExamSupplyRegistrationsByAdmissionYear($courseType = NULL, $admissionYear = Null)
    {
        $courseType = $this->realEscapeString($courseType);
        $admissionYear = $this->realEscapeString($admissionYear);
        $conditions = "";
        if ($courseType) {
            $conditions .= "AND b.courseTypeID = '$courseType'";
        }
        if ($admissionYear) {
            $conditions .= "AND b.batchStartYear = '$admissionYear'";
        }
        $sql = "SELECT DISTINCT es.id, es.supplyDesc FROM exam_supplementary es
                    INNER JOIN supply_improve_batches sib ON sib.exam_supplementary_id = es.id
                    INNER JOIN batches b ON b.batchID = sib.batchID
                    WHERE 1 = 1
                    $conditions
                    order by es.id DESC";
        try {
            $examRegistrations = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistrations;
    }
    /**
     * get Supply Exam Registration Month Year Details By Course Type And Batch StartYear
     */
    public function getSupplyExamRegistrationMonthYearDetailsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if($request->monthYear){
            $condition .= " AND date_format(str_to_date(DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%M %Y'),'%M %Y'),'%Y-%m-01') <= '$request->monthYear";
        }
        if(!$request->getAllSupplyReg){
            $groupBy = " GROUP BY DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y %b') ";
        }
        if($request->semId){
            $condition .= " AND es.semID IN ($request->semId)";
        }
        $sql = "SELECT DISTINCT
                        date_format(str_to_date(DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%M %Y'),'%M %Y'),'%Y-%m-01') AS id,
                        DATE_FORMAT(CONCAT(es.examYear,'-',es.examMonth,'-','1'),'%Y %b') name,
                        es.id as supplyRegId,
                        es.supplyDesc as supplyDesc
                        FROM
                        supply_improve_batches sib 
                        INNER JOIN exam_supplementary es ON
                            es.id = sib.exam_supplementary_id
                        INNER JOIN batches bt ON
                            bt.batchID = sib.batchID 
                        WHERE bt.batchStartYear = $request->startYear and bt.courseTypeID = $request->courseTypeId
                        $condition
                        $groupBy
                        ORDER BY IF(CAST(es.examYear AS SIGNED) = 0, 99999, CAST(es.examYear AS SIGNED)) DESC ,IF(CAST(es.examMonth AS SIGNED) = 0, 99999, CAST(es.examMonth AS SIGNED)) DESC";
        try {
            $examMonthYears  = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examMonthYears;
    }
    /**
     * change supply improve status
     */
    public function changeSupplyImproveStatus($examSupplementaryId, $studentId, $isSupply) {
        $examSupplementaryId = $this->realEscapeString($examSupplementaryId);
        $studentId = $this->realEscapeString($studentId);
        $isSupply = $this->realEscapeString($isSupply);
        $sql = null;
        try {
            $sql = "UPDATE exam_supplementary_student_details SET isSupply = $isSupply WHERE exam_supplementary_id = '$examSupplementaryId' AND studentID = $studentId";
            $this->executeQuery($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
     /**
     * Get Student Exam Supply Registrations By semId
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentSupplyRegistrationsBySemId ( $request ) {
        $request = $this->realEscapeObject($request);
        $supplyRegs = null;
        $condition="";
        if($request->semId){
            $condition .=" AND es.semID = '$request->semId";
        }
        try {
            $sql = "SELECT DISTINCT essd.exam_supplementary_id,es.supplyDesc, essd.isSupply,es.semID AS semId, es.examYear ,es.examMonth from exam_supplementary_student_details essd
                        INNER JOIN exam_supplementary es ON es.id = essd.exam_supplementary_id
                        WHERE 1 = 1
                        and essd.studentID = '$request->studentId'
                        AND essd.paid = 1
                        AND essd.approved = 1
                        $condition
                        ORDER BY IF(CAST(es.examYear AS SIGNED) = 0, 99999, CAST(es.examYear AS SIGNED)) ,IF(CAST(es.examMonth AS SIGNED) = 0, 99999, CAST(es.examMonth AS SIGNED))";
            
            $supplyRegs = $this->executeQueryForList($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $supplyRegs;
    }
     /**
     * Get Supply Registrations By Sem and batch
     * @param $semId, $batchId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getSupplyRegistrationsBySemAndBatchId (  $semId, $batchId ) {
        $semId = $this->realEscapeString($semId);
        $batchId = $this->realEscapeString($batchId);
        $supplyRegs = null;
        try {
            $sql = "SELECT DISTINCT es.id,es.semID AS semId,es.examMonth,es.examYear from supply_improve_batches sib
                        INNER JOIN exam_supplementary es ON es.id = sib.exam_supplementary_id
                        WHERE es.semID = '$semId
                        AND sib.batchID IN ($batchId)
                        GROUP BY concat(es.semID,es.examMonth,es.examYear)
                        ORDER BY IF(CAST(es.examYear AS SIGNED) = 0, 99999, CAST(es.examYear AS SIGNED)) ,IF(CAST(es.examMonth AS SIGNED) = 0, 99999, CAST(es.examMonth AS SIGNED))";
            
            $supplyRegs = $this->executeQueryForList($sql);
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $supplyRegs;
    }
    /**
     *  to get all registered students in subjects for supply
     * @param $subjectId, $supplyRegId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getAllSupplyRegisteredStudentsForSubjects($supplyRegId,$subjectId)
    {
        $subjectId = $this->realEscapeString($subjectId);
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $students = [];
        $sql = " SELECT ex.subjectID, sa.regNo, sa.studentID , sa.studentName ,sa.batchID, bt.batchName, sa.studentPhone ,sa.studentEmail FROM exam_supplementary_student_subjects esss INNER JOIN exam ex ON (esss.examID = ex.examID )  INNER JOIN studentaccount sa ON (sa.studentID = esss.studentID )
        INNER JOIN exam_supplementary_student_details essd ON (essd.studentID = sa.studentID AND essd.exam_supplementary_id = esss.exam_supplementary_id)
        INNER JOIN batches bt ON (bt.batchID = sa.batchID ) WHERE ex.subjectID = '$subjectId' and esss.exam_supplementary_id = '$supplyRegId' and essd.paid = 1";
        try {
            $students = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $students;
    }
    /**
     *  to get studentwise report for supply
     * @param $supplyRegId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getSupplyStudentWiseReportBySupplyRegId($supplyRegId)
    {
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $students = [];
        $sql = " SELECT ex.subjectID, sa.regNo, sa.studentID , sa.studentName ,sa.batchID, bt.batchName, sa.studentPhone ,sa.studentEmail, sb.subjectName, sb.subjectDesc FROM exam_supplementary_student_subjects esss INNER JOIN exam ex ON (esss.examID = ex.examID )  INNER JOIN studentaccount sa ON (sa.studentID = esss.studentID )  INNER JOIN batches bt ON (bt.batchID = sa.batchID )  INNER JOIN exam_supplementary_student_details essd ON (essd.studentID = sa.studentID AND essd.exam_supplementary_id = esss.exam_supplementary_id) INNER JOIN subjects sb ON (sb.subjectID = ex.subjectID) WHERE   esss.exam_supplementary_id = '$supplyRegId'  and essd.paid = 1";
        try {
            $students = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $students;
    }
     /**
     * Get supply exam marks by studentID and regular examID
     */
    public function getSupplyMarkDetailsByStudentAndRegularExamId($studentId, $examId, $type = NULL)
    {
        $examId = (int)$this->realEscapeString($examId);
        $studentId = (int)$this->realEscapeString($studentId);
        $type = $this->realEscapeString($type);
        $supplyMarks = [];
        $courseType = StudentService::getInstance()->getCourseTypeByStudentId($studentId);
        $batchCourseType = $courseType->courseType;
        $marksTable = 'exammarks_external';
        if ($batchCourseType == CourseTypeConstants::UG) {
            $marksTable = 'exammarks_external';
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD || $batchCourseType == CourseTypeConstants::PG_BLISC || $batchCourseType == CourseTypeConstants::MBA || $batchCourseType == CourseTypeConstants::MSW || $batchCourseType == CourseTypeConstants::LIB) {
            $marksTable = 'externalexammarks_finalized';
        }
        $orderBy = " ORDER BY e.examDate ASC ";
        if ($type == "HIGHEST") {
            $orderBy = " ORDER BY ee.mark DESC LIMIT 1";
        } else if ($type == "LATEST") {
            // $orderBy = " ORDER BY e.examDate DESC LIMIT 1";
            $orderBy = " ORDER BY CAST(es.examYear AS UNSIGNED) DESC, CAST(es.examMonth AS UNSIGNED) DESC LIMIT 1";
        }
        $sql = "SELECT
                ee.mark,
                es.examMonth,
                es.examYear,
                esss.exam_supplementary_id AS supplyRegId,
                essd.isSupply AS isSupply,
                e.examID AS examId
            FROM
                exam_supplementary_student_subjects esss
            INNER JOIN exam_supplementary_student_details essd ON
                esss.exam_supplementary_id = essd.exam_supplementary_id
                AND esss.studentID = essd.studentID
            INNER JOIN exam_supplementary es ON
                (es.id = esss.exam_supplementary_id)
            INNER JOIN exam e1 ON
                (e1.examID = esss.examID)
            INNER JOIN exam e ON
                (e.subjectID = e1.subjectID
                AND e.supply_examreg_id = esss.exam_supplementary_id)
            INNER JOIN studentaccount sa ON
                (sa.studentID = esss.studentID)
            INNER JOIN $marksTable ee ON
                (ee.studentID = sa.studentID
                AND ee.examID = e.examID)
            WHERE
                esss.studentID = '$studentId'
                AND esss.examID = '$examId
                AND essd.isSupply = 1
                GROUP BY e.examID
                $orderBy";
        try {
            if ($type) {
                $supplyMarks = $this->executeQueryForObject($sql);
            } else {
                $supplyMarks = $this->executeQueryForList($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyMarks;
    }
             /**
     * Get supply exam absent status by studentID and regular examID
     */
    public function getSupplyAbsentStatusDetailsByStudentAndRegularExamId($studentId, $examId, $type = NULL)
    {
        $examId = (int)$this->realEscapeString($examId);
        $studentId = (int)$this->realEscapeString($studentId);
        $type = $this->realEscapeString($type);
        $supplyMarks = [];
        $courseType = StudentService::getInstance()->getCourseTypeByStudentId($studentId);
        $batchCourseType = $courseType->courseType;
        $marksTable = 'exammarks_external';
        if ($batchCourseType == CourseTypeConstants::UG) {
            $marksTable = 'exammarks_external';
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD) {
            $marksTable = 'externalexammarks_finalized';
        }
        $orderBy = " ORDER BY e.examDate ASC ";
        if ($type == "HIGHEST") {
            $orderBy = " ORDER BY ee.mark DESC LIMIT 1";
        } else if ($type == "LATEST") {
            // $orderBy = " ORDER BY e.examDate DESC LIMIT 1";
            $orderBy = " ORDER BY CAST(es.examYear AS UNSIGNED) DESC, CAST(es.examMonth AS UNSIGNED) DESC LIMIT 1";
        }
        $sql = "SELECT
                -- ee.mark,
                ea.isAbsent,
                es.examMonth,
                es.examYear,
                esss.exam_supplementary_id AS supplyRegId,
                essd.isSupply AS isSupply,
                e.examID AS examId
            FROM
                exam_supplementary_student_subjects esss
            INNER JOIN exam_supplementary_student_details essd ON
                esss.exam_supplementary_id = essd.exam_supplementary_id
                AND esss.studentID = essd.studentID
            INNER JOIN exam_supplementary es ON
                (es.id = esss.exam_supplementary_id)
            INNER JOIN exam e1 ON
                (e1.examID = esss.examID)
            INNER JOIN exam e ON
                (e.subjectID = e1.subjectID
                AND e.supply_examreg_id = esss.exam_supplementary_id)
            INNER JOIN studentaccount sa ON
                (sa.studentID = esss.studentID)
            -- INNER JOIN $marksTable ee ON
            --     (ee.studentID = sa.studentID
            --     AND ee.examID = e.examID)
            INNER JOIN exam_attendance ea ON ea.examID = e.examID
                    AND ea.studentID = esss.studentID
                    AND ea.studentID = essd.studentID
                    AND ea.studentID = sa.studentID
            WHERE
                esss.studentID = '$studentId'
                AND esss.examID = '$examId'
                AND essd.isSupply = 1
                $orderBy";
        try {
            if ($type) {
                $supplyMarks = $this->executeQueryForObject($sql);
            } else {
                $supplyMarks = $this->executeQueryForList($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyMarks;
    }
    /**
     * @author Sibin
     */
    public function getExamSubjectListByBatch($request)
    {
        $request = $this->realEscapeObject($request);
        $subjectDetails = null;
        $sql = "SELECT distinct s.subjectID, s.subjectName, s.subjectDesc,concat(s.subjectName,' - ',s.subjectDesc) as subjectDisplay from exam e 
                INNER JOIN subjects s ON s.subjectID = e.subjectID 
                WHERE e.batchID IN ($request->batchId) AND e.supply_examreg_id = '$request->examRegId' ORDER BY s.subjectName ASC";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    /* get ug exam supply reg pg students with valuation marks by examregid and subjectid
    */
    public function getSupplyExamRegisteredPgStudentsWithMarksBySubject($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        if ($request->packetNo) {
            $whereConditions .= " AND evpr.packetNo IN ('$request->packetNo') ";
        }
        $sql = "SELECT distinct erss.studentID,sa.regNo,sa.studentName,e.examID,e.batchID,e.semID,e.subjectID,e.examTotalMarks,ee.mark as mark1,ee2.mark as mark2,ee3.mark as mark3,eef.mark as finalizedMark,
                Abs(ee.mark - ee2.mark) AS markDifference,efn.false_number as falseNumber,efn.alpha_numeric_code as alphaNumericCode,evpr.packetNo
                FROM exam_supplementary_student_subjects erss
                INNER JOIN exam_supplementary_student_details ersc ON ersc.studentID = erss.studentID AND ersc.exam_supplementary_id = erss.exam_supplementary_id
                INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                INNER JOIN supply_improve_batches erb ON erb.exam_supplementary_id = erss.exam_supplementary_id AND erb.batchID = sa.batchID
                INNER JOIN exam e ON e.supply_examreg_id = erss.exam_supplementary_id  AND e.batchID = sa.batchID
                INNER JOIN examcontroller_false_number efn ON efn.examID = e.examID AND efn.studentID = erss.studentID
                INNER JOIN examValuationStudentPacketsRelation evpr ON evpr.studentId = erss.studentID AND evpr.examId = e.examID
                LEFT JOIN exammarks_external ee ON ee.examID = e.examID AND ee.studentID = erss.studentID
                LEFT JOIN  external_exammarks ee2 ON ee2.examID = e.examID AND ee2.studentID = erss.studentID AND ee2.valuationCount = 2
                LEFT JOIN  external_exammarks ee3 ON ee3.examID = e.examID AND ee3.studentID = erss.studentID AND ee3.valuationCount = 3
                LEFT JOIN externalexammarks_finalized eef ON eef.examID = e.examID AND eef.studentID = erss.studentID
                WHERE erss.exam_supplementary_id = '$request->examRegId' AND e.subjectID = '$request->subjectId' AND ersc.paid=1 
                $whereConditions
                order by sa.regNo";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    /**
     * @author Sibin
     * get supply exam reg ug students with valuation marks by examregid and subjectid
     */
    public function getSupplyExamRegisteredUgStudentsWithMarksBySubject($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        if ($request->packetNo) {
            $whereConditions .= " AND evpr.packetNo IN ('$request->packetNo') ";
        }
        $sql = "SELECT distinct erss.studentID,sa.regNo,sa.studentName,e.examID,e.batchID,e.semID,e.subjectID,e.examTotalMarks,ee.mark as mark1,ee2.mark as mark2,ee3.mark as mark3,eef.mark as finalizedMark,
                Abs(ee.mark - ee2.mark) AS markDifference,efn.false_number as falseNumber,efn.alpha_numeric_code as alphaNumericCode,evpr.packetNo
                FROM exam_supplementary_student_subjects erss
                INNER JOIN exam_supplementary_student_details ersc ON ersc.studentID = erss.studentID AND ersc.exam_supplementary_id = erss.exam_supplementary_id
                INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                INNER JOIN supply_improve_batches erb ON erb.exam_supplementary_id = erss.exam_supplementary_id AND erb.batchID = sa.batchID
                INNER JOIN exam e ON e.supply_examreg_id = erss.exam_supplementary_id AND e.batchID = sa.batchID 
                INNER JOIN examcontroller_false_number efn ON efn.examID = e.examID AND efn.studentID = erss.studentID
                INNER JOIN examValuationStudentPacketsRelation evpr ON evpr.studentId = erss.studentID AND evpr.examId = e.examID
                LEFT JOIN examValuationMarks ee ON ee.examId = e.examID AND ee.studentId = erss.studentID AND ee.valuationCount = 1 AND ee.additionalEvaluator IS NOT NULL
                LEFT JOIN examValuationMarks ee2 ON ee2.examId = e.examID AND ee2.studentId = erss.studentID AND ee2.valuationCount = 1  AND ee2.chiefEvaluator IS NOT NULL
                LEFT JOIN examValuationMarks ee3 ON ee3.examId = e.examID AND ee3.studentId = erss.studentID AND ee3.valuationCount = 2 
                LEFT JOIN exammarks_external eef ON eef.examID = e.examID AND eef.studentID = erss.studentID
                WHERE erss.exam_supplementary_id = '$request->examRegId' AND e.subjectID = '$request->subjectId' AND ersc.paid=1 
                $whereConditions
                group by sa.studentID order by sa.regNo";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    public function getPublishedExamSupplyRegistrationSbyRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $supplyExamRegistrations=[];
        $condition = "";
        if(!$request->considerPublishStatusOnly){
            $condition .= " AND TIMESTAMP(epr.fromDate,'00:00:00') < NOW() ";
        }
        if($request->batchId){
            $condition .= " AND epr.batchID IN($request->batchId";
        }
        if ($request->semId) {
            $condition .= " AND epr.semID IN($request->semId";
        }
        try {
                $sql = "SELECT epr.exam_supplementary_id as supplyRegId,epr.fromDate, epr.toDate 
                        FROM supplyexam_publishresult epr
                        WHERE  1 = 1  
                        $condition";
                $supplyExamRegistrations = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyExamRegistrations;
    }
    public function getStudentAbsentStatusOfSupplyExamByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $supplyExam = null;
        $condition="";
        $yearUpperLimit = $request->yearUpperLimit;
        $monthUpperLimit = $request->monthUpperLimit;
        if($yearUpperLimit && $monthUpperLimit){
            $condition .= " AND UNIX_TIMESTAMP(CONCAT (es.examYear,'-',es.examMonth,'-01')) <=  UNIX_TIMESTAMP('$yearUpperLimit-$monthUpperLimit-01') ";
        }
        try {
            if ($request->studentId && $request->examId && $request->semId && $request->batchId && $request->examRegId) {
                $condition .= " AND sa.studentID IN ($request->studentId)  AND sa.batchID IN ($request->batchId)  
                        AND e.semID IN ($request->semId)  AND t1.examRegID IN ($request->examRegId) AND t1.examID IN ($request->examId";
                $sql = "SELECT DISTINCT
                    sa.studentID,
                    sa.studentName,
                    sa.regNo,
                    b.batchID,
                    ea.isAbsent,
                    s.subjectID,
                    s.isTheory,
                    essd.isSupply AS isSupplyImprove,
                    essd.exam_supplementary_id,
                    esss.examID AS regularExamId,
                    es.id AS supply_examregID,
                    es.id AS supplyRegId,
                    es.supplyDesc,
                    es.examMonth,
                    es.examYear,
                    e.examID AS supplyExamId,
                    e.examID AS examId,
                    e.examName,
                    t1.examregID AS regular_examRegID
                FROM
                    exam_supplementary_student_subjects esss
                        INNER JOIN
                    exam_supplementary_student_details essd 
                        ON esss.exam_supplementary_id = essd.exam_supplementary_id
                        AND esss.studentID = essd.studentID
                        INNER JOIN
                    studentaccount sa ON sa.studentID = essd.studentID
                        INNER JOIN 
                    exam_supplementary es ON es.id = esss.exam_supplementary_id
                        INNER JOIN
                    exam t1 ON t1.examID = esss.examID
                        INNER JOIN 
                    exam e ON e.subjectID = t1.subjectID
                        AND e.batchID = t1.batchID
                        AND e.supply_examreg_id = esss.exam_supplementary_id
                        INNER JOIN
                    subjects s ON e.subjectID = s.subjectID
                        INNER JOIN
                    exam_type et ON et.typeID = e.examTypeID
                        INNER JOIN
                    batches b ON b.batchID = e.batchID
                        LEFT JOIN
                    exam_attendance ea ON ea.examID = e.examID
                        AND ea.studentID = sa.studentID
                        LEFT JOIN
                    failed_students fs ON fs.studentID = sa.studentID
                        AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                WHERE
                    essd.paid = 1 AND essd.approved = 1
                        AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID)
                        AND essd.isSupply = 1  $condition
                        ORDER BY CAST(es.examYear AS UNSIGNED) DESC, CAST(es.examMonth AS UNSIGNED) DESC LIMIT 1";
                $supplyExam = $this->executeQueryForObject($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyExam;
    }
    /**
     * Method to get subject List for a supplementary exam
     * 
     * @author Sibin
     */
    public function getSubjectListSupp($request)
    {
        $request = $this->realEscapeObject($request);
        $examDetails = null;
        $condition = $innerJoinExam = $examStartTime = "";
        if ($request->batchId) {
            $condition .= " AND e.batchID = $request->batchId ";
        }
        if ($request->subjectTypeId) {
            $condition .= " AND s.paperTypeId = $request->subjectTypeId ";
        }
        if ($request->examDate) {
            $condition .= " AND ex.examDate = '$request->examDate";
            $innerJoinExam = "INNER JOIN exam ex ON ex.supply_examreg_id = sisf.exam_supplementary_id AND ex.batchID  = e.batchID AND ex.subjectID = s.subjectID";
            $examStartTime = " , ex.examStartTime";
        }
        $orderCondition = $request->orderBySyllabusYear ? "s.syllabusYear" : "s.subjectName";
        $sql = "SELECT DISTINCT s.subjectID as subjectId,s.subjectName as subjectName,s.subjectDesc as subjectDesc,s.syllabusYear as syllabusYear,s.syllabusName 
                $examStartTime
                FROM subjects s 
                INNER JOIN exam e ON s.subjectID = e.subjectID 
                INNER JOIN supply_improve_subject_fees sisf ON e.examID = sisf.examID 
                $innerJoinExam
                WHERE sisf.exam_supplementary_id IN ($request->supplyRegId
                $condition
                ORDER BY $orderCondition ASC";
        try {
            $examDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
    /**
     * Method to get withheld supply reg of student
     * 
     * @author Sibin
     */
    public function getWithheldSupplyRegistrationsByStudent($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "SELECT studentID as studentId,reason,exam_supplementary_id as supplyRegId from supplyexam_students_withheld where withheld=1  and studentID='$request->studentId'";
        try {
            $supplyRegList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyRegList;
    }
    public function getSupplyExamRegistrationForBatch($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sqlCondition = "";
        if (!empty($batchId)) {
            $batchIdString = is_array($batchId) ? implode(",", $batchId) : $batchId;
            $sqlCondition .= " AND erb.batchID IN ($batchIdString";
        }
        if (!empty($semId)) {
            $semIdString = is_array($semId) ? implode(",", $semId) : $semId;
            $sqlCondition .= " AND er.semID IN ($semIdString";
        }
        $sql = "SELECT 
            er.id, 
            er.supplyDesc AS name
        FROM
            exam_supplementary er
        INNER JOIN supply_improve_batches erb ON
            erb.exam_supplementary_id = er.id
        WHERE
            er.id = er.id
            $sqlCondition GROUP BY er.id";
        try {
            $examRegistration = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistration;
    }
    /**
     * Get exam registrations by request
     * @param int $REQUEST
     * @throws ProfessionalException
     */
    public function getDistinctExamRegistrationByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if ($request->courseTypeId) {
            $condition .= " AND ct.courseTypeID IN($request->courseTypeId";
        }
        if ($request->semId) {
            $condition .= " AND er.semID IN($request->semId";
        }
        $examRegistrations = [];
        $sql = "SELECT DISTINCT erb.exam_supplementary_id as id, er.supplyDesc as name
                FROM supply_improve_batches erb 
                INNER JOIN batches b on erb.batchID = b.batchID
                INNER JOIN exam_supplementary er on er.id = erb.exam_supplementary_id 
                INNER JOIN course_type ct on ct.courseTypeID = b.courseTypeID 
                WHERE 1=1 
                $condition
                ORDER BY er.examYear DESC,er.id DESC";
        try {
            $examRegistrations =  $this->executeQueryForList($sql);
            return $examRegistrations;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get supply exam reg batches by request
     * @param int $REQUEST
     * @throws ProfessionalException
     */
    public function getDistinctSupplyExamRegBatchesByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = $joinCondition = $semField = "";
        if ($request->examRegId) {
            $condition .= " AND erb.exam_supplementary_id IN($request->examRegId";
        }
        if ($request->courseTypeId) {
            $condition .= " AND ct.courseTypeID IN($request->courseTypeId";
        }
        if ($request->batchStartYear) {
            $condition .= " AND b.batchStartYear IN($request->batchStartYear";
        }
        if($request->examCreatedBatchesOnly){
            $joinCondition .= "INNER JOIN exam e ON e.supply_examreg_id = erb.exam_supplementary_id AND e.batchID = erb.batchID
                                LEFT JOIN semesters s ON s.semID = e.semID";
            $semField = " ,s.semName , e.semID as semId";
        }
        $examRegistrations = [];
        $sql = "SELECT DISTINCT erb.batchID,b.batchName,
                IF(sep.fromDate = '0000-00-00','',sep.fromDate) AS fromDate,IF(sep.toDate = '0000-00-00','',sep.toDate) AS toDate,sep.publish,
                dp.deptName,dp.departmentDesc,cp.patternName
                $semField
                FROM supply_improve_batches erb 
                INNER JOIN batches b ON b.batchID = erb.batchID
                INNER JOIN course_type ct on ct.courseTypeID = b.courseTypeID  
                LEFT JOIN supplyexam_publishresult sep ON sep.exam_supplementary_id= erb.exam_supplementary_id AND sep.batchID = erb.batchID
                LEFT JOIN department dp ON dp.deptID = b.deptID
                LEFT JOIN course_pattern cp ON cp.patternID = b.patternID
                $joinCondition
                WHERE 1=1 
                $condition";
        try {
            $examRegistrations =  $this->executeQueryForList($sql);
            return $examRegistrations;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Method to get student count for a supplementary exam
     * 
     * @author Sibin
     */
    public function getStudentCountDetailsSupp($request)
    {
        $request = $this->realEscapeObject($request);
        $studentcount = null;
        $condition = "";
        if ($request->batchId) {
            $condition .= " AND sa.batchID IN ($request->batchId";
        }
        $sql = "SELECT count(distinct esss.studentID) as studentCount FROM exam_supplementary_student_subjects esss 
                INNER JOIN exam_supplementary_student_details essd ON esss.exam_supplementary_id = essd.exam_supplementary_id AND esss.studentID = essd.studentID 
                INNER JOIN studentaccount sa ON sa.studentID = essd.studentID 
                WHERE esss.examID IN (SELECT e.examID FROM exam e WHERE e.subjectID = $request->subjectId
                AND esss.exam_supplementary_id IN ($request->examSuppId) AND essd.paid = 1 AND  essd.approved = 1
                $condition ";
        try {
            $studentcount = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentcount;
    }
    /**
     * Get supply exam publish details
     * @param Integer $request
     * @throws ProfessionalException
     * @return Object $publishDetails
     * @author Sibin
     */
    public function getSupplyPublishDetailsByRequest($request)
    {
        $publishDates = null;
        $request = $this->realEscapeObject($request);
        try {
            $sql = "SELECT sp.publish,sp.fromDate,sp.toDate FROM exam e
                    INNER JOIN supplyexam_publishresult sp  ON sp.batchID = e.batchID AND sp.semID = e.semID AND sp.exam_supplementary_id = e.supply_examreg_id
                    WHERE e.examID = '$request->examId' AND e.semID = '$request->semId' AND e.supply_examreg_id = '$request->id";
            $publishDates = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $publishDates;
    }
    /**
     * Get Student Exam Supply Registrations By examId
     * @param $examId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentLatestSupplyRegistrationOfSubject($examId, $studentId)
    {
        $examId = $this->realEscapeString($examId);
        $studentId = $this->realEscapeString($studentId);
        try {
            $sql = "SELECT es.id , es.examMonth , es.examYear , essd.isSupply FROM exam_supplementary_student_subjects esss INNER JOIN exam_supplementary_student_details essd ON (esss.studentID = essd.studentID AND esss.exam_supplementary_id = essd.exam_supplementary_id) INNER JOIN exam_supplementary es ON (esss.exam_supplementary_id = es.id) WHERE esss.studentID = $studentId AND esss.examID = $examId AND essd.paid = 1 ORDER BY CAST(es.examYear AS UNSIGNED) DESC, CAST(es.examMonth AS UNSIGNED) DESC LIMIT 1";
            $supplyRegs = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyRegs;
    }
     /** Finalize student supply exam details
     * @param $request
     * @return Object
     * @throws ProfessionalException
     */
    public function finalizeSupplyExamDetails($request)
    {
        $request = $this->realEscapeObject($request);
            $sql = "UPDATE supplyexam_publishresult SET finalize = $request->finalize WHERE batchID = '$request->batchId' AND exam_supplementary_id = '$request->examRegId' AND semID = '$request->semId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /** get finalized student supply exam details
     * @param $request
     * @return Object
     * @throws ProfessionalException
     */
    public function getSupplyExamFinalizeDetails($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "SELECT finalize FROM supplyexam_publishresult WHERE batchID = '$request->batchId' AND exam_supplementary_id = '$request->examRegId' AND semID = '$request->semId";
        try {
            $finalizeDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $finalizeDetails;
    }
    /** set supply exam reg batch publish dates
     * @param $request
     * @return Object
     * @throws ProfessionalException
     */
    public function setSupplyExamRegBatchPublishDates($request)
    {
        $request = $this->realEscapeObject($request);
        $insertValues = [];
        try {
            foreach ($request->batches as $batch) {
                $insertValues[] = "($request->examRegId,$batch->batchID,$batch->semId,'$batch->fromDate','$batch->toDate',$request->publish,$request->updatedBy)";
                $batchIds[] = $batch->batchID;
            }
            if (!empty($insertValues)) {
                $insertValues = implode(",", $insertValues);
                $batchIds = implode(",", $batchIds);
                if ($request->publish) {
                    $sql = "INSERT INTO supplyexam_publishresult(exam_supplementary_id,batchID,semID,fromDate,toDate,publish,updatedBy)
                            VALUES $insertValues ON DUPLICATE KEY UPDATE fromDate = VALUES(fromDate),toDate = VALUES(toDate),publish = VALUES(publish) , updatedBy = VALUES(updatedBy)";
                } else {
                    $sql = "DELETE FROM supplyexam_publishresult WHERE exam_supplementary_id IN ($request->examRegId) AND batchID IN ($batchIds)";
                            
                }
                $this->executeQueryForObject($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get exam supply registrations by request
     * @param int $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     * @author sibin
     */
    public function getExamSupplyRegistrationsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $conditions = "";
        if ($request->courseTypeId) {
            $conditions .= " AND b.courseTypeID IN($request->courseTypeId";
        }
        if ($request->admissionYear) {
            $conditions .= " AND b.batchStartYear IN($request->admissionYear";
        }
        if ($request->semId) {
            $conditions .= " AND es.semID IN($request->semId";
        }
        $sql = "SELECT DISTINCT es.id, es.supplyDesc as name FROM exam_supplementary es
                    INNER JOIN supply_improve_batches sib ON sib.exam_supplementary_id = es.id
                    INNER JOIN batches b ON b.batchID = sib.batchID
                    WHERE 1 = 1
                    $conditions
                    order by es.id DESC";
        try {
            $examRegistrations = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistrations;
    }
    /**
     * Update supply approve flag
     * @param $request
     * @throws ProfessionalException
     */
    public function updateSupplyApproveStatusOfRegisteredStudents($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if($request->batchId){
            $condition .= " AND sa.batchID = $request->batchId";
        }
        if($request->deptId){
            $condition .= " AND sa.deptID = $request->deptId";
        }
        if($request->name){
            global $SUPPLY_IMPROVE_CHALLAN_PREFIX;
            $name = $request->name;
            $challan_name = str_replace($SUPPLY_IMPROVE_CHALLAN_PREFIX, "", strtoupper($name));
            $condition .= " AND (sa.regNo like '%$name%' OR sa.studentName like '%$name%' OR ess.challanNo like '%$challan_name%') ";
        }
        $sql = "SELECT distinct ess.studentID FROM exam_supplementary_student_details ess INNER JOIN studentaccount sa ON (sa.studentID = ess.studentID) WHERE exam_supplementary_id = '$request->examRegID' AND isSupply = '$request->isSupply' AND paid = 1  $condition";
        try {
            $studentList = $this->executeQueryForList($sql);
            foreach ( $studentList  as $student ) {
                $sql1 = "UPDATE exam_supplementary_student_details SET approved = $request->approve WHERE exam_supplementary_id = '$request->examRegID' AND studentID = '$student->studentID'";
                $this->executeQuery($sql1);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get student supply subject registered deails
     * @param $studentId, $examRegId, $examId
     * @return Object Exam subject
     * @throws ProfessionalException
     */
    public function getStudentSupplyExamSubjectRegisteredDetails($studentId, $examRegId, $examId)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $examId = $this->realEscapeString($examId);
        $subjects = [];
        $sql = "SELECT studentID FROM  exam_supplementary_student_subjects esss WHERE studentID = $studentId AND exam_supplementary_id = $examRegId AND examID = $examId ";
        try {
            $subjects = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    /**
     * Supply offline registration
     * @param $request
     * @throws ProfessionalException
     */
    public function addSupplyStudentSubjectForRegistrations ( $request ) {
        $request = $this->realEscapeObject($request);
        $createdBy = $_SESSION['adminID'];
        $createdDate = date('Y-m-d H:i:s', time());
        try {
            $studentEntry = $this->getSupplyImproveRegisteredStudentDetails ( $request->examRegId, $request->studentId );
            if(!$studentEntry){
                $query1 = "select max(challanNo) as challanNo from exam_supplementary_student_details";
                $challanNo = $this->executeQueryForObject($query1)->challanNo;
                $challanNo = $challanNo + 1;
            
                $sqlDetails = "INSERT INTO exam_supplementary_student_details (studentID, exam_supplementary_id, total_fees, challanNo,paid,isSupply,payment_method,approved) VALUES ($request->studentId$request->examRegId, '$request->totalFees', '$challanNo', '$request->paid',  $request->isSupply,  '$request->paymentMethod',  '$request->approved')";
                $this->executeQuery($sqlDetails);
            }
            foreach ( $request->supplySubjects as $supplySubject ) {
                $supplySubject = (object) $supplySubject;
                if($supplySubject->isSelected){
                    $subjectEntry = $this->getStudentSupplyExamSubjectRegisteredDetails ($request->studentId, $request->examRegId, $supplySubject->examID );
                    if(!$subjectEntry){
                        $sqlSubjects = "INSERT INTO exam_supplementary_student_subjects(studentID,exam_supplementary_id,examID,remark,created_by,created_date) VALUES ($request->studentId$request->examRegId, '$supplySubject->examID', '$request->remark', '$createdBy',  '$createdDate')";
                        $this->executeQuery($sqlSubjects);
                    }
                }
                else{
                    $deleteSql = "DELETE FROM exam_supplementary_student_subjects WHERE  studentID = $request->studentId AND exam_supplementary_id =  $request->examRegId AND examID = $supplySubject->examID ";
                    $this->executeQuery($deleteSql);
                }
            }
        }
        catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return true;
    }
    /**
     * Get all subjects that student need to register for supplementary exam
     * @param Integer $studentID
     * @param Integer $batchID
     * @param Integer $supplyregID
     * @return Array Supplementary exam subject list
     * @throws ProfessionalException
     */
    public function getStudentSupplySubjectsForOfflineRegistration($supplyregID, $batchID, $studentID = NULL, $currentStatus = TRUE, $isMarksCardRequest = FALSE)
    {
        global $COLLEGE_CODE;
        $supplyregID = (int)$this->realEscapeString($supplyregID);
        $batchID = (int)$this->realEscapeString($batchID);
        $studentID = $this->realEscapeString($studentID);
        $examreg = null;
        $examregID = null;
        $studentIds = explode(",", $studentID );
        if ( count($studentIds) === 1 ) {
            /**
             * If studentID contains multiple ids then we can't find a single batchID....
             * To be fixed...
             * 
             * Here the param $batchID is the student's current batch ID, We can't use that
             * So, we get the student's batchID in which the student studied during that semester
             */
            $examSupplementary = $this->getExamSupplementaryById ( $supplyregID );
            $checkInternalSubjectPresent = ExamService::getInstance()->checkInternalSubjectPresentInThatBatch($batchID,$examSupplementary->semID);
            // if( !empty ( $checkInternalSubjectPresent ) ){
                // $batchID = ExamService::getInstance()->getStudentExamBatchBySemester ($studentID, $examSupplementary->semID);
                // if ( empty ( $batchID ) ) {
                    //throw new ProfessionalException(ProfessionalException::DATA_EMPTY, "Student's internal marks not found for this semester for any subject!");
            //     }
            // }
        }
        $subjectDetails = [];
        $failedSubjects = [];
        $studentCondition = null;
        $examSupplementary = $this->getExamSupplementaryById ( $supplyregID );
        $studentBatchId = StudentService::getInstance()->getStudentPreviousBatchBySemId($studentID,$examSupplementary->semID);
        if(!empty( $studentBatchId)){
           $batchID =  $studentBatchId; 
        }
        if ($studentID) {
            $studentCondition = " AND erss.studentID IN ($studentID";
        }
        $sql = "SELECT erb.examregID, es.examMonth, es.examYear FROM exam_registration_batches erb INNER JOIN exam_supplementary es ON erb.semID = es.semID WHERE es.id = '$supplyregID' AND erb.batchID = '$batchID";
        try {
            $examreg = $this->executeQueryForObject($sql);
            if (!empty ($examreg)) {
                $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchID);
                $batchCourseType = $batchDetails->course_Type;
                $batchStartYear = $batchDetails->batchStartYear;
                if ($batchCourseType == CourseTypeConstants::UG) {
                    $marksTable = 'exammarks_external';
                } else if ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD) {
                    $marksTable = 'externalexammarks_finalized';
                }
                $termPaper = ExamSubjectTypeConstants::TERM_PAPER;
                $openElective = ExamSubjectTypeConstants::OPEN_ELECTIVE;
                $foundationCourse = ExamSubjectTypeConstants::FOUNDATION_COURSE;
                $additionalCredits = ExamSubjectTypeConstants::ADDITIONAL_CREDIT;
                $paperCondition = $subjectTypeCondition = "";
                if($COLLEGE_CODE == "SJCC" && $isMarksCardRequest){
                    $paperCondition = " OR esc.subjectType = '$additionalCredits'";
                }
                if($COLLEGE_CODE == "SJCC"){
                    $subjectTypeCondition = " OR esc.subjectType = '$foundationCourse";
                }
                if ($COLLEGE_CODE == "SJC" && $_SESSION['offlineSupplyReg']) {
                    $subjectTypeCondition = " OR esc.subjectType = '$foundationCourse";
                }
                $examregID = $examreg->examregID;
                $examYearMonthTime = strtotime($examreg->examYear . "-" . $examreg->examMonth . "-01");
                $sql = "SELECT 
                            erss.studentID,
                            e.examID,
                            e.subjectID,
                            s.subjectName,
                            s.subjectDesc,
                            esc.isInternal,
                            esc.isExternal,
                            esc.subjectType,
                            im.internalMarks AS intMark,
                            ims.maxInternalMarks AS intTotalMark,
                            ee.mark AS extMark,
                            e.examTotalMarks AS extTotalMark,
                            ee2.mark AS latestSupplyMark,
                            IF(CAST(UNIX_TIMESTAMP(CONCAT(es.examYear,'-',es.examMonth,'-01')) AS UNSIGNED) < $examYearMonthTime , IF(ee2.mark, ee2.mark, ee.mark), ee.mark) AS previousMarks
                        FROM
                            exam_reg_studentsubject erss
                                INNER JOIN
                            exam e ON (e.subjectID = erss.subjectID
                                AND e.examregID = erss.examregID)
                                INNER JOIN
                            exam_subjectcredit esc ON (esc.batchID = e.batchID
                                AND esc.semID = e.semID
                                AND esc.subjectID = e.subjectID)
                                INNER JOIN
                            subjects s ON (s.subjectID = erss.subjectID)
                                LEFT JOIN
                            $marksTable ee ON (ee.examID = e.examID
                                AND erss.studentID = ee.studentID)
                                LEFT JOIN
                            internal_marks im ON (im.batchID = e.batchID
                                AND im.semID = e.semID
                                AND im.subjectID = e.subjectID
                                AND im.studentID = erss.studentID)
                                LEFT JOIN
                            internal_marks_settings ims ON (ims.batchID = e.batchID
                                AND ims.semID = e.semID
                                AND ims.subjectID = e.subjectID)
                                LEFT JOIN
                            exam_supplementary_student_subjects esss ON (esss.studentID = erss.studentID
                                AND esss.examID = e.examID)
                                LEFT JOIN
                            exam_supplementary es ON (es.id = esss.exam_supplementary_id)
                                LEFT JOIN
                            exam e2 ON (e.subjectID = e2.subjectID
                                AND esss.exam_supplementary_id = e2.supply_examreg_id
                                AND e2.batchID = e.batchID
                                AND e2.semID = e.semID)
                                LEFT JOIN
                            $marksTable ee2 ON (ee2.studentID = erss.studentID
                                AND ee2.examID = e2.examID)
                        WHERE
                            ( esc.excludeSubjectFromTotal = 0 OR ( esc.excludeSubjectFromTotal = 1 AND (esc.subjectType = '$termPaper' OR esc.subjectType = '$openElective'  $paperCondition $subjectTypeCondition) ) ) AND
                            erss.examregID = '$examregID' AND e.batchID = '$batchID'
                                $studentCondition
                        ORDER BY erss.studentID ASC, es.examYear DESC , CAST(es.examMonth AS UNSIGNED) DESC , es.examDate DESC";
                        // WHERE (esc.excludeSubjectFromTotal = 0 OR esc.subjectType = '$termPaper' OR esc.subjectType = '$openElective' OR esc.subjectType = '$foundationCourse' OR esc.subjectType = '$additionalCredits')
                $subjectDetails = $this->executeQueryForList($sql);
                if (!empty ($subjectDetails)) {
                    /** To avoid duplicate entries of subjects in the student subjects list **/
                    $subjectExistsForStudent = [];
                    foreach ($subjectDetails as $index => $details) {
                        if ($subjectExistsForStudent[$details->studentID][$details->examID] == 1) {
                            unset($subjectDetails[$index]);
                        } else {
                            $subjectExistsForStudent[$details->studentID][$details->examID] = 1;
                        }
                    }
                    unset($subjectExistsForStudent);
                    /** code ends **/
                    
                    $passPercentConfigRequest = new UniversityMarkListPassPercentConfig();
                    $passPercentConfigRequest->courseTypeId = $batchDetails->courseTypeID;
                    $passPercentConfigRequest->batchYear = $batchDetails->batchStartYear;
                    $passPercentConfig = ExamService::getInstance()->getUniversityMarkListPassPercentConfig($passPercentConfigRequest)[0];
                    if (empty ($passPercentConfig)) {
                        // throw new ProfessionalException ( ProfessionalException::PASS_PERCENT_CONFIG_NOT_DEFINED, "University marklist pass percent configuration not defined");
                        // return [];
                    }
                    if ($passPercentConfig->internalCutOff) {
                        $internalPassCriteria = $passPercentConfig->internalCutOff;
                    }
                    if ($passPercentConfig->semExamCutOff) {
                        $externalPassCriteria = $passPercentConfig->semExamCutOff;
                    }
                    if ($passPercentConfig->subjectCutOff) {
                        $overallPassCriteria = $passPercentConfig->subjectCutOff;
                    }
                    foreach ($subjectDetails as $details) {
                        $obtTotalMark = 0;
                        $totalMark = 0;
                        $failedStatus = 0;
                        $considerOverallPassCriteriaOnly = 0;
                        if ($details->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                            $details->subjectType == ExamSubjectTypeConstants::FOUNDATION_COURSE ||
                            $details->subjectType == ExamSubjectTypeConstants::TERM_PAPER) {
                            $considerOverallPassCriteriaOnly = 1;
                        }
                        if ($COLLEGE_CODE == "SJCC" || $COLLEGE_CODE == "SJC") {
                            $details->intMark = round($details->intMark);
                        }
                        if ($details->isInternal == 1) {
                            $internalPercent = $details->intTotalMark ? 100 * $details->intMark / $details->intTotalMark : 0;
                            $obtTotalMark += $details->intMark;
                            $totalMark += $details->intTotalMark;
                            if (!empty ($internalPassCriteria) && $considerOverallPassCriteriaOnly == 0) {
                                $failedStatus = $internalPassCriteria <= $internalPercent ? $failedStatus : 1;
                            }
                        }
                        if ($details->isExternal == 1) {
                            if (!$currentStatus) {
                                $studentExternalMarks = $details->previousMarks;
                            } else {
                                $studentExternalMarks = $details->highestSupplyMark ? $details->highestSupplyMark : $details->extMark;
                            }
                            $studentExternalMarks = round($studentExternalMarks);
                            $externalPercent = $details->extTotalMark ? 100 * $studentExternalMarks / $details->extTotalMark : 0;
                            $obtTotalMark += $studentExternalMarks;
                            $totalMark += $details->extTotalMark;
                            if (!empty ($externalPassCriteria) && $considerOverallPassCriteriaOnly == 0) {
                                $failedStatus = $externalPassCriteria <= $externalPercent ? $failedStatus : 1;
                            }
                        }
                        $overallPercent = $totalMark ? 100 * $obtTotalMark / $totalMark : 0;
                        if (!empty ($overallPassCriteria)) {
                            $failedStatus = $overallPassCriteria <= $overallPercent ? $failedStatus : 1;
                        }
                        $details->isFailed = $failedStatus;
                        if ($failedStatus == 1) {
                            $failedSubjects[$details->studentID]->examID[] = $details->examID;
                            $failedSubjects[$details->studentID]->details[$details->subjectID] = $details;
                        }
                    }
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $failedSubjects;
    }
    /**
     * Get all subjects that student need to register for supplementary exam
     * @param Integer $studentID
     * @param Integer $batchID
     * @param Integer $supplyregID
     * @return Array Supplementary exam subject list
     * @throws ProfessionalException
     */
    public function getSupplyStudentSubjectsForConsolidated($supplyregID, $batchID, $studentID = NULL, $currentStatus = TRUE)
    {
        global $COLLEGE_CODE;
        $supplyregID = (int)$this->realEscapeString($supplyregID);
        $batchID = (int)$this->realEscapeString($batchID);
        $studentID = $this->realEscapeString($studentID);
        $examreg = null;
        $examregID = null;
        $studentIds = explode(",", $studentID );
        if ( count($studentIds) === 1 ) {
            /**
             * If studentID contains multiple ids then we can't find a single batchID....
             * To be fixed...
             * 
             * Here the param $batchID is the student's current batch ID, We can't use that
             * So, we get the student's batchID in which the student studied during that semester
             */
            $examSupplementary = ExamSupplementaryService::getInstance()->getExamSupplementaryById ( $supplyregID );
            $checkInternalSubjectPresent = ExamService::getInstance()->checkInternalSubjectPresentInThatBatch($batchID,$examSupplementary->semID);
            if( !empty ( $checkInternalSubjectPresent ) ){
                $batchID = ExamService::getInstance()->getStudentExamBatchBySemester ($studentID, $examSupplementary->semID);
                if ( empty ( $batchID ) ) {
                    //throw new ProfessionalException(ProfessionalException::DATA_EMPTY, "Student's internal marks not found for this semester for any subject!");
                }
            }
        }
        $examSupplementary = ExamSupplementaryService::getInstance()->getExamSupplementaryById ( $supplyregID );
        $failedSubjectsList = [];
        foreach($studentIds as $studentID){
            $studentBatchId = ExamService::getInstance()->getStudentExamBatchBySemester ($studentID, $examSupplementary->semID);
            if(!empty( $studentBatchId)){
               $batchID =  $studentBatchId; 
            }
            $subjectDetails = [];
            $failedSubjects = [];
            $studentCondition = null;
            if ($studentID) {
                $studentCondition = " AND erss.studentID IN ($studentID";
            }
            $sql = "SELECT erb.examregID, es.examMonth, es.examYear FROM exam_registration_batches erb INNER JOIN exam_supplementary es ON erb.semID = es.semID WHERE es.id = '$supplyregID' AND erb.batchID = '$batchID";
            try {
                $examreg = $this->executeQueryForObject($sql);
                if (!empty ($examreg)) {
                    $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchID);
                    $batchCourseType = $batchDetails->course_Type;
                    $batchStartYear = $batchDetails->batchStartYear;
                    if ($batchCourseType == CourseTypeConstants::UG) {
                        $marksTable = 'exammarks_external';
                    } else if ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD) {
                        $marksTable = 'externalexammarks_finalized';
                    }
                    $termPaper = ExamSubjectTypeConstants::TERM_PAPER;
                    $openElective = ExamSubjectTypeConstants::OPEN_ELECTIVE;
                    $foundationCourse = ExamSubjectTypeConstants::FOUNDATION_COURSE;
                    $additionalCredits = ExamSubjectTypeConstants::ADDITIONAL_CREDIT;
                    $examregID = $examreg->examregID;
                    $examYearMonthTime = strtotime($examreg->examYear . "-" . $examreg->examMonth . "-01");
                    $sql = "SELECT 
                                erss.studentID,
                                e.examID,
                                e.subjectID,
                                s.subjectName,
                                s.subjectDesc,
                                esc.isInternal,
                                esc.isExternal,
                                esc.subjectType,
                                im.internalMarks AS intMark,
                                ims.maxInternalMarks AS intTotalMark,
                                ee.mark AS extMark,
                                e.examTotalMarks AS extTotalMark,
                                ee2.mark AS latestSupplyMark,
                                IF(CAST(UNIX_TIMESTAMP(CONCAT(es.examYear,'-',es.examMonth,'-01')) AS UNSIGNED) < $examYearMonthTime , IF(ee2.mark, ee2.mark, ee.mark), ee.mark) AS previousMarks
                            FROM
                                exam_reg_studentsubject erss
                                    INNER JOIN
                                exam e ON (e.subjectID = erss.subjectID
                                    AND e.examregID = erss.examregID)
                                    INNER JOIN
                                exam_subjectcredit esc ON (esc.batchID = e.batchID
                                    AND esc.semID = e.semID
                                    AND esc.subjectID = e.subjectID)
                                    INNER JOIN
                                subjects s ON (s.subjectID = erss.subjectID)
                                    LEFT JOIN
                                $marksTable ee ON (ee.examID = e.examID
                                    AND erss.studentID = ee.studentID)
                                    LEFT JOIN
                                internal_marks im ON (im.batchID = e.batchID
                                    AND im.semID = e.semID
                                    AND im.subjectID = e.subjectID
                                    AND im.studentID = erss.studentID)
                                    LEFT JOIN
                                internal_marks_settings ims ON (ims.batchID = e.batchID
                                    AND ims.semID = e.semID
                                    AND ims.subjectID = e.subjectID)
                                    LEFT JOIN
                                exam_supplementary_student_subjects esss ON (esss.studentID = erss.studentID
                                    AND esss.examID = e.examID)
                                    LEFT JOIN
                                exam_supplementary es ON (es.id = esss.exam_supplementary_id)
                                    LEFT JOIN
                                exam e2 ON (e.subjectID = e2.subjectID
                                    AND esss.exam_supplementary_id = e2.supply_examreg_id
                                    AND e2.batchID = e.batchID
                                    AND e2.semID = e.semID)
                                    LEFT JOIN
                                $marksTable ee2 ON (ee2.studentID = erss.studentID
                                    AND ee2.examID = e2.examID)
                            WHERE
                                ( esc.excludeSubjectFromTotal = 1 AND (esc.subjectType = '$foundationCourse' ) ) AND
                                erss.examregID = '$examregID' AND e.batchID = '$batchID'
                                    $studentCondition
                            ORDER BY erss.studentID ASC, es.examYear DESC , CAST(es.examMonth AS UNSIGNED) DESC , es.examDate DESC";
                            // WHERE (esc.excludeSubjectFromTotal = 0 OR esc.subjectType = '$termPaper' OR esc.subjectType = '$openElective' OR esc.subjectType = '$foundationCourse' OR esc.subjectType = '$additionalCredits')
                    $subjectDetails = $this->executeQueryForList($sql);
                    if (!empty ($subjectDetails)) {
                        /** To avoid duplicate entries of subjects in the student subjects list **/
                        $subjectExistsForStudent = [];
                        foreach ($subjectDetails as $index => $details) {
                            if ($subjectExistsForStudent[$details->studentID][$details->examID] == 1) {
                                unset($subjectDetails[$index]);
                            } else {
                                $subjectExistsForStudent[$details->studentID][$details->examID] = 1;
                            }
                        }
                        unset($subjectExistsForStudent);
                        /** code ends **/
                        
                        $passPercentConfigRequest = new UniversityMarkListPassPercentConfig();
                        $passPercentConfigRequest->courseTypeId = $batchDetails->courseTypeID;
                        $passPercentConfigRequest->batchYear = $batchDetails->batchStartYear;
                        $passPercentConfig = ExamService::getInstance()->getUniversityMarkListPassPercentConfig($passPercentConfigRequest)[0];
                        if (empty ($passPercentConfig)) {
                            // throw new ProfessionalException ( ProfessionalException::PASS_PERCENT_CONFIG_NOT_DEFINED, "University marklist pass percent configuration not defined");
                            // return [];
                        }
                        if ($passPercentConfig->internalCutOff) {
                            $internalPassCriteria = $passPercentConfig->internalCutOff;
                        }
                        if ($passPercentConfig->semExamCutOff) {
                            $externalPassCriteria = $passPercentConfig->semExamCutOff;
                        }
                        if ($passPercentConfig->subjectCutOff) {
                            $overallPassCriteria = $passPercentConfig->subjectCutOff;
                        }
                        foreach ($subjectDetails as $details) {
                            $obtTotalMark = 0;
                            $totalMark = 0;
                            $failedStatus = 0;
                            $considerOverallPassCriteriaOnly = 0;
                            if ($details->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                                $details->subjectType == ExamSubjectTypeConstants::FOUNDATION_COURSE ||
                                $details->subjectType == ExamSubjectTypeConstants::TERM_PAPER) {
                                $considerOverallPassCriteriaOnly = 1;
                            }
                            if ($COLLEGE_CODE == "SJCC" || $COLLEGE_CODE == "SJC") {
                                $details->intMark = round($details->intMark);
                            }
                            if ($details->isInternal == 1) {
                                $internalPercent = $details->intTotalMark ? 100 * $details->intMark / $details->intTotalMark : 0;
                                $obtTotalMark += $details->intMark;
                                $totalMark += $details->intTotalMark;
                                if (!empty ($internalPassCriteria) && $considerOverallPassCriteriaOnly == 0) {
                                    $failedStatus = $internalPassCriteria <= $internalPercent ? $failedStatus : 1;
                                }
                            }
                            if ($details->isExternal == 1) {
                                if (!$currentStatus) {
                                    $studentExternalMarks = $details->previousMarks;
                                } else {
                                    $studentExternalMarks = $details->highestSupplyMark ? $details->highestSupplyMark : $details->extMark;
                                }
                                $studentExternalMarks = round($studentExternalMarks);
                                $externalPercent = $details->extTotalMark ? 100 * $studentExternalMarks / $details->extTotalMark : 0;
                                $obtTotalMark += $studentExternalMarks;
                                $totalMark += $details->extTotalMark;
                                if (!empty ($externalPassCriteria) && $considerOverallPassCriteriaOnly == 0) {
                                    $failedStatus = $externalPassCriteria <= $externalPercent ? $failedStatus : 1;
                                }
                            }
                            $overallPercent = $totalMark ? 100 * $obtTotalMark / $totalMark : 0;
                            if (!empty ($overallPassCriteria)) {
                                $failedStatus = $overallPassCriteria <= $overallPercent ? $failedStatus : 1;
                            }
                            $details->isFailed = $failedStatus;
                            if ($failedStatus == 1) {
                                $failedSubjects[$details->studentID]->examID[] = $details->examID;
                                $failedSubjects[$details->studentID]->details[$details->subjectID] = $details;
                            }
                        }
                    }
                }
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            $failedSubjectsList =$failedSubjects + $failedSubjectsList;
        }
        return $failedSubjectsList;
    }
    /**
     * Get exam registrations by request
     * @param int $REQUEST
     * @throws ProfessionalException
     */
    public function getDistinctSupplyExamRegisteredSubjectsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        $groupByCondition = "s.subjectID";
        $orderByCondition = "";
        if($request->examRegId){
            $condition .= " AND esss.exam_supplementary_id IN($request->examRegId";
        }
        if($request->subjectId){
            $condition .= " AND   ex.subjectID IN($request->subjectId";
            $groupByCondition = "esss.studentID ";
            $orderByCondition = "ORDER BY sa.rollNo";
        }
        $subjectList = [];
        $sql = "SELECT esss.exam_supplementary_id as examRegId,s.subjectID as subjectId,s.subjectName,s.subjectDesc,sa.studentID,sa.regNo,sa.studentName,sa.rollNo
            FROM 
                exam_supplementary_student_subjects esss 
            INNER JOIN 
                exam_supplementary_student_details essd ON (esss.exam_supplementary_id = essd.exam_supplementary_id )  
            INNER JOIN 
                exam ex ON (esss.examID = ex.examID )  
            INNER JOIN 
                subjects s ON (s.subjectID = ex.subjectID )  
            INNER JOIN 
                studentaccount sa ON (sa.studentID = esss.studentID )  
            INNER JOIN batches bt ON (bt.batchID = sa.batchID ) 
            WHERE 
                essd.paid = 1 $condition
                GROUP BY  $groupByCondition
                $orderByCondition";
        try {
            $subjectList =  $this->executeQueryForList($sql);
            return $subjectList;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
         /**
     * @param $studentId
     * @param $semId
     * get program result month and year
     */
    public function getExamRegistrationByStudentIdAndSemId($studentId, $semId)
    {
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT DISTINCT es.id, es.supplyDesc as name FROM exam_supplementary es INNER JOIN exam_supplementary_student_details essd ON essd.exam_supplementary_id = es.id WHERE es.semID = $semId AND essd.paid = 1 AND essd.studentID = $studentId";
        try {
            $result = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
        /**
     *getSubjectsByExamRegAndStudentId($studentDetails)
     * @param object $request
     * @return request
     * @throws ProfessionalException
     */
    public function getSupplySubjectsDetailsByStudentDetails($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "SELECT e.examID,e.batchID,e.semID,s.subjectID,s.subjectName,s.syllabusName,s.subjectDesc,ers.exam_supplementary_id as supplyRegId,gsm.marks as graceMark , gsm.remarks ,s.isTheory ,gsm.fianlize as finalize ,gsm.approve
                FROM 
                    exam_supplementary_student_subjects ers
                INNER JOIN 
                    exam e2 ON e2.examID = ers.examID
                INNER JOIN 
                    exam e ON e.subjectID = e2.subjectID AND e.supply_examreg_id = ers.exam_supplementary_id
                INNER JOIN 
                    subjects s ON s.subjectID = e.subjectID
                LEFT JOIN 
                    gracemarks_student_marks gsm ON gsm.studentID=ers.studentID 
                    AND gsm.subjectID = e.subjectID AND gsm.examID = e.examID
                where ers.exam_supplementary_id='$request->examRegId
                    and e.batchID='$request->batchId'
                    and e.semID='$request->semId'
                    and ers.studentID='$request->studentId'";
        try {
            $subjectDetails = $this->executeQueryForList($sql);;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
     /**
     * Get special exam marks by studentID and regular examID
     */
    public function getSpecialExamMarkDetailsByStudentAndRegularExamId($studentId, $examId, $type = NULL)
    {
        $examId = (int)$this->realEscapeString($examId);
        $studentId = (int)$this->realEscapeString($studentId);
        $type = $this->realEscapeString($type);
        $supplyMarks = [];
        $courseType = StudentService::getInstance()->getCourseTypeByStudentId($studentId);
        $batchCourseType = $courseType->courseType;
        $marksTable = 'exammarks_external';
        if ($batchCourseType == CourseTypeConstants::UG) {
            $marksTable = 'exammarks_external';
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD || $batchCourseType == CourseTypeConstants::PG_BLISC || $batchCourseType == CourseTypeConstants::MBA || $batchCourseType == CourseTypeConstants::MSW || $batchCourseType == CourseTypeConstants::LIB) {
            $marksTable = 'externalexammarks_finalized';
        }
        $orderBy = " ORDER BY e.examDate ASC ";
        if ($type == "HIGHEST") {
            $orderBy = " ORDER BY ee.mark DESC LIMIT 1";
        } else if ($type == "LATEST") {
            // $orderBy = " ORDER BY e.examDate DESC LIMIT 1";
            $orderBy = " ORDER BY CAST(es.examYear AS UNSIGNED) DESC, CAST(es.examMonth AS UNSIGNED) DESC LIMIT 1";
        }
        $sql = "SELECT
                ee.mark,
                es.examMonth,
                es.examYear,
                esss.exam_supplementary_id AS supplyRegId,
                essd.isSupply AS isSupply,
                e.examID AS examId
            FROM
                exam_supplementary_student_subjects esss
            INNER JOIN exam_supplementary_student_details essd ON
                esss.exam_supplementary_id = essd.exam_supplementary_id
                AND esss.studentID = essd.studentID
            INNER JOIN exam_supplementary es ON
                (es.id = esss.exam_supplementary_id)
            INNER JOIN exam e1 ON
                (e1.examID = esss.examID)
            INNER JOIN exam e ON
                (e.subjectID = e1.subjectID
                AND e.supply_examreg_id = esss.exam_supplementary_id)
            INNER JOIN studentaccount sa ON
                (sa.studentID = esss.studentID)
            INNER JOIN $marksTable ee ON
                (ee.studentID = sa.studentID
                AND ee.examID = e.examID)
            WHERE
                esss.studentID = '$studentId'
                AND esss.examID = '$examId
                AND es.isSpecialExam = 1
                GROUP BY e.examID
                $orderBy";
        try {
            if ($type) {
                $supplyMarks = $this->executeQueryForObject($sql);
            } else {
                $supplyMarks = $this->executeQueryForList($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyMarks;
    }
    
    /**
     * get supply students details
     * @param $examRegId
     * @param $batchId
     * @param $semId
     * @return request
     * @throws ProfessionalException
     */
    public function getSupplyExamRegisteredStudentList($examRegId, $batchId, $semId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT distinct t1.studentID, t2.studentName, t2.regNo, t2.rollNo 
                FROM 
                    exam_supplementary_student_details t1 
                INNER JOIN 
                    studentaccount t2 ON (t1.studentID=t2.studentID ) 
                WHERE 
                    t1.paid=1 and t1.exam_supplementary_id='$examRegId' and t2.batchID='$batchId
                UNION 
                SELECT sa.studentID, sa.studentName, sa.regNo,sa.rollNo FROM studentaccount sa 
                INNER JOIN 
                    failed_students fs ON fs.studentID = sa.studentID 
                INNER JOIN 
                    exam_supplementary_student_details essd ON essd.studentID = sa.studentID AND essd.studentID = fs.studentID 
                WHERE 
                    fs.previousBatch = '$batchId' and essd.exam_supplementary_id = '$examRegId' AND fs.failedInSemester > '$semId' AND FIND_IN_SET('$semId', fs.hisSemestersInThisbatch) order by regNo asc";
        try {
            $subjectDetails = $this->executeQueryForList($sql);;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    /**
     * Get supply publish details by batchId
     * @param int $batchId
     * @param string $fromDate
     * @param string $toDate
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSupplyPublishDetailsByBatch($studentId, $batchId, $fromDate = null, $toDate = null)
    {
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $fromDate = $this->realEscapeString($fromDate);
        $toDate = $this->realEscapeString($toDate);
        $toDate = $toDate ? date('Y-m-d', strtotime($toDate)) : null;
        $fromDate = $fromDate ? date('Y-m-d', strtotime($fromDate)) : null;
        $sql = "SELECT sep.exam_supplementary_id, sep.semID FROM supplyexam_publishresult sep INNER JOIN exam_supplementary_student_details essd ON (sep.exam_supplementary_id = essd.exam_supplementary_id) INNER JOIN studentaccount sa ON (sa.studentID = essd.studentID) WHERE sep.batchID=$batchId AND sep.publish = 1 AND sa.studentID = $studentId";
        if ($fromDate && $toDate) {
            $sql .= " AND sep.fromDate BETWEEN '$fromDate' AND '$toDate'";
        }
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Get supply reg students
     * @param  $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSupplyRegStudentsByDate($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if($request->examDate){
            $condition = "AND e.examDate = '$request->examDate'";
        }
        if($request->paid){
            $condition = "AND essd.paid = '1'";
        }
        $sql = "SELECT ess.studentID,sa.studentName,sa.regNo,sa.batchID,s.subjectName,s.subjectDesc, e.examDate,e.examStartTime,e.examEndTime ,ex.examID as regularExamId ,e.examID as supplyExamId, e.examTotalMarks FROM exam_supplementary_student_subjects ess
                INNER JOIN studentaccount sa ON sa.studentID = ess.studentID 
                INNER JOIN exam ex ON ex.examID = ess.examID 
                INNER JOIN subjects s ON s.subjectID = ex.subjectID
                INNER JOIN exam_supplementary_student_details essd ON essd.studentID = ess.studentID  AND essd.exam_supplementary_id = ess.exam_supplementary_id
                LEFT JOIN exam e ON e.batchID = ex.batchID AND e.semID = ex.semID AND e.subjectID = ex.subjectID AND e.supply_examreg_id = ess.exam_supplementary_id
                WHERE ess.exam_supplementary_id = '$request->supplyExamRegId'
                $condition 
                ORDER BY s.subjectName ,sa.regNo";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * @param $request
     * get student supply intrernal mark
     */
    public function getStudentSupplyInternalMark($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if ($request->studentId) {
            $condition .= " AND sim.studentId IN ($request->studentId)";
        }
        if ($request->subjectId) {
            $condition .= " AND sim.subjectId IN ($request->subjectId)";
        }
        if(!$request->supplyExamRegId && $request->supplyExamId){
            $request->supplyExamRegId = ExamService::getInstance()->getExamDetailsByExamId($request->supplyExamId)->supplyRegId;
        }
        if ($request->supplyExamRegId) {
            $condition .= " AND sim.supplyExamRegId IN ($request->supplyExamRegId)";
        }
        $sql = "SELECT sim.studentId,sim.subjectId,sim.supplyExamRegId,sim.marks,1 AS isSupplyIntMarks FROM  supply_internal_marks sim WHERE 1=1 $condition";
        try {
            $result = $this->executeQueryForObject($sql);
            if(!$result){
                //GET REGULAR INT MARKS IF NO SUPPLY INT MARKS FOUND
                if ($request->getRegularIntMarks) {
                    $condition = "";
                    if ($request->studentId) {
                        $condition .= " AND sim.studentID IN ($request->studentId)";
                    }
                    if ($request->subjectId) {
                        $condition .= " AND sim.subjectID IN ($request->subjectId)";
                    }
                    if ($request->semId) {
                        $condition .= " AND sim.semID IN ($request->semId)";
                    }
                    $sql = "SELECT sim.studentID as studentId,sim.subjectID as subjectId,sim.internalMarks as marks FROM  internal_marks sim WHERE 1=1 $condition";
                    $result = $this->executeQueryForObject($sql);
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * Get exam supplementary registration details
     * @param int $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamSupplyRegistrationDetailsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $sql ="SELECT 
                    es.id as examRegId,
                    es.supplyDesc as examRegName,
                    es.supplyDesc as examregName,
                    es.examMonth, 
                    es.examYear 
                FROM
                    exam_supplementary es
                WHERE 
                    es.id IN ($request->examRegId)
                ORDER BY 
                    es.examYear ASC, IF(CAST(es.examMonth AS SIGNED) = 0, 99999, CAST(es.examMonth AS SIGNED)) ASC";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get regular exam reg  details by supply reg
     * @param int $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getRegularExamRegistrationByExamSupplyRegRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if($request->examRegId){
            $condition .= " AND es.supply_examreg_id IN ($request->examRegId)";
        }
        if($request->examId){
            $condition .= " AND es.examID IN($request->examId)";
        }
        $sql = "SELECT er.examregID as examRegId,erg.examregName as examRegName,er.examID as regularExamId  from exam es
                    INNER JOIN  exam er ON er.semID = es.semID AND er.batchID=es.batchID AND er.subjectID = es.subjectID AND er.examregID IS NOT NULL
                    INNER JOIN exam_registration erg ON erg.examregID  = er.examregID 
                    WHERE 1=1  $condition GROUP BY er.examregID";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get supply / improvement registered student subject/false no details 
     * @param $request
     * @throws ProfessionalException
     * @author Sibin 
     */
    public function getSupplyImproveRegisteredStudentFalseNumbers($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $details = [];
        $condition = "";
        if ($request->getRegularExamFalseNumber) {
            $regularExamJoin = " INNER JOIN exam ex ON ex.semID = e.semID AND ex.subjectID = e.subjectID AND ex.batchID = e.batchID AND ex.supply_examreg_id = esss.exam_supplementary_id";
            $falseNoJoin = "LEFT JOIN examcontroller_false_number efn ON efn.studentID = esss.studentID AND efn.examID = e.examID";
        } else {
            $falseNoJoin = "LEFT JOIN examcontroller_false_number efn ON efn.studentID = esss.studentID AND efn.examID = esss.examID";
        }
        if($request->supplyRegId){
            $condition .= " AND esss.exam_supplementary_id IN ($request->supplyRegId)";
        }
        if ($request->studentId) {
            $condition .= " AND esss.studentID IN ($request->studentId)";
        }
        if ($request->examId) {
            $condition .= " AND ex.examID IN ($request->examId)";
        }
        $sql = "SELECT esss.exam_supplementary_id, esss.studentID, esss.examID, esss.approveImprovementMarkStatus, s.subjectID, s.subjectName, s.subjectDesc, s.syllabusName,e.batchID ,e.semID as semId,esc.isInternal,efn.false_number as falseNumber
                FROM exam_supplementary_student_subjects esss INNER JOIN exam e ON (e.examID = esss.examID) 
                INNER JOIN subjects s ON (e.subjectID = s.subjectID)  
                INNER JOIN exam_subjectcredit esc ON esc.subjectID = s.subjectID AND esc.batchID = e.batchID AND esc.semID = e.semID
                $regularExamJoin
                $falseNoJoin 
                WHERE 1=1 $condition order by esc.subjectOrder";
        try {
            $details = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $details;
    }
        /**
     * @param $request
     * get student supply intrernal marks
     */
    public function getStudentSupplyInternalMarks($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if ($request->subjectId) {
            $condition .= " AND sim.subjectId IN ($request->subjectId)";
        }
        $sql = "SELECT sim.studentId,sim.subjectId,sim.supplyExamRegId,sim.marks,1 AS isSupplyIntMarks FROM  supply_internal_marks sim WHERE 1=1 $condition";
        try {
            $supplyIntmarks = $this->executeQueryForList($sql);
            return $this->mapSupplyIntMarks($supplyIntmarks);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    private function mapSupplyIntMarks($supplyIntmarks){
        $supplyIntmarksResults =[];
        foreach($supplyIntmarks as $intMark){
            $supplyIntmarksResults[$intMark->studentId][$intMark->supplyExamRegId] = $intMark;
        }
        return $supplyIntmarksResults;
    }
        /**
     * Get regular exam reg  details by supply reg
     * @param int $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getRegularExamRegistrationByExamSupplyRegId($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        $sql = " SELECT es.id as supplyRegId ,es.semID ,sib.batchID,e.examregID as examRegId from exam_supplementary es
                    INNER JOIN supply_improve_batches sib ON sib.exam_supplementary_id = es.id  
                    INNER JOIN exam e ON e.batchID = sib.batchID AND e.semID = es.semID AND e.examregID IS NOT NULL 
                    INNER JOIN exam_registration er ON e.examregID = er.examregID AND er.shortCourse = 0
                    WHERE es.id IN ($request->examRegId) GROUP BY e.examregID";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
}
?>