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 / 441
CRAP
0.00% covered (danger)
0.00%
0 / 10973
ExamService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 441
3321506.00
0.00% covered (danger)
0.00%
0 / 10973
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 4
 __clone
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getFailedStudentRate
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 42
 getFailedStudentRateBySem
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 47
 getPercentage
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 4
 getFailedSubjectCount
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getExamCount
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getExamAttendedStudentIds
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 12
 getExamAttendedStudentIdsByBatchId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 12
 getExamTypeById
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 5
 getExamType
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 24
 checkExamTypeUsingOrNot
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getFailedRateStudentGradeWise
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 6
 getFailedRateSubjectGradeWise
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 6
 getUniversityExamCount
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 5
 getFaildGradeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getFailedStudentSubjectCount
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 45
 getFailedRateSubjects
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 24
 getExamEntryType
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentGradeListByStudentId
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 6
 getStudentGradeListByStudentIds
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 6
 getUniversityExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getStudentsAppearedCount
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getStudentsFailedCount
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getExamDetailsOfSubjectByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getAssignedExamHallsByGroupId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getHallDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamDetailsbyGroupId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentByExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getStudentCountByExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getSeatDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 assignStudentToExamHall
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 15
 getExamHallAssignedStudentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getExamHallAssignedStudentCount
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 deleteAssignStudentFromExamHall
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getCountOfAssignedStudents
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 saveExamHallArrangedStructure
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getExamHallArrangedStructure
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 deleteExamHallArrangedStructure
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamDetailsByExamType
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getFailedSubjectCountOfStudent
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getFailedStudentExamCount
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 24
 getUniversityMarksDefinedSem
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 21
 getTotalPercentage
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 getUniversityGradeDefinedSem
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 addStaffToExamHall
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 updateExamHallAssignedStaff
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 deleteExamHallAssignedStaff
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 checkExamHallAssigned
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 getExamGroupAssignedStaffs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamHallUnassignedStaffs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getCountOfExamHallAssignedStaffs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamHallSeatingAllotment
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 6
 getExamTimeAndDateByGroup
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamTypeBySubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getFailedStudentCountIncludeAbsentees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentsAppearedCountIncludeAbsentee
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getUniversityExamGrade
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 25
 getUniversityExamGrades
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getStudentUniversityExamDetailsByExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentsInCreditRange
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 38
 getStudentExamMarks
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 69
 getStudentsFailedCountByExamTypeId
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 30
 getStudentsFailedCountIncludeAbsenteesByExamType
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 32
 getStudentExamMarksBySubjectId
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 143
 getExamTypeDetailsBySubjectId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getUniversityExamBacklogCountByYear
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 23
 getUniversityBatchCourseType
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getUniversityExamBacklogCountDetailsByStudentIds
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamTypesByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamIdBySubjectId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getUniversityExamBySubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getUniversityGradeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 addSlowLearnerIdentification
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 updateSlowLearnerIdentification
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getSlowLearnerIdentification
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getSlowLearnerIdentificationByExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 removeSlowLearnerIdentificationByExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getExamFaildStudentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getExamDetailsBySubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamDetailsByExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getExamDetailsByBatchAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 22
 getExamDetailsByBatchAndSubjectIdAndExamType
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 26
 setCanShowExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamHallSeatingAllotmentByRegNo
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamHallAssignedStudentDetailsByHallId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamsUnDefinedSubjectsByExamTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 setCanShowExamType
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamEntryTypeByStudentId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 getStudentArrearsCount
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentUniversityExamFailedCountByMark
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 23
 getStudentUniversityExamFailedCountByGrade
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamHallAssignedStaffByDeptId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentUniversityExamMarks
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 40
 getUniversityExams
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentUniversityExamMarkDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 updateStudentUniversityMark
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 createStudentUniversityMark
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getSubjectCommunityQuestions
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getStudentUniversityResults
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 96
 getExamDetailsBySbsId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamDetailsBySBS
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getInternalExamDetailsBySBS
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getExamEnorollmentList
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 updateExamEnorollment
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 removeExamEnorollment
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 addExamEnorollment
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentExamEnorollmentList
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 addStudentExamEnorollment
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 removeStudentExamEnorollment
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamEnrollmentStudentList
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getStudentEnrollmentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentExamPercentage
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getSemWiseUniversitySgpa
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 29
 getExamTimeTables
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 68
 getStudentRegisteredExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getExamSemId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 22
 getConsiderExamType
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExternalMarks
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getTotalUniversityCreditByBatchId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getTotalUniversityCreditsByStudentId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 32
 getClassAvgBySubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 checkThisExamRegisSpecialExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 checkThisStudentHasSpecialExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getExamRegistrationDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 checkStudentPresentReAdmission
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 reAdmissionDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamSupplementaryDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 isSpecialExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getsupplyExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 checkThisStudentAssignedForSpecialExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getRegularExamIdForSuppExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getFeeDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamFeesHead
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getSemIdForExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getCommonFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getTotalFeesForAnExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 validateRevaluationFees
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 23
 calculateCommonFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getInstructions
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 18
 getMaxGradePoint
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentLastAttendedExam
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 22
 getSessionMarkSettings
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 isSessionalExamMarkSubmitted
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 normalizedMarkApproveStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 normalizedMarkApproveStatusPseudo
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamDetailsByExamDate
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 18
 getSubjectListExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getAllRegisteredSupplyExams
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 getAllRegisteredRegularExams
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 getSubjectListSupplyByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getSubjectListRegularByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getAllStudentRegBlockReason
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 blockStudentFromExamRegistrationSubjectWise
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 57
 getSupplyExamIdByRegularExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getSupplyExamIdBySubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentExamRegBlockedStatus
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 23
 checkIfExamExistsAndGetErrorMessage
0.00% covered (danger)
0.00%
0 / 1
342.00
0.00% covered (danger)
0.00%
0 / 80
 getAllExamsOfABatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamMarksOfAStudent
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getCombinedCoAndMarkReport
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 62
 getAllStudentExamRegBlockedStatus
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 54
 getStudentExamSubjectsForRegistration
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 64
 getStudentSupplySubjectsForRegistration
0.00% covered (danger)
0.00%
0 / 1
2652.00
0.00% covered (danger)
0.00%
0 / 200
 getExamSubjectCreditBySubjectBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentSupplyExamMarkDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 94
 getStudentFailedSubjectByExamregId
0.00% covered (danger)
0.00%
0 / 1
600.00
0.00% covered (danger)
0.00%
0 / 130
 getSupplyMarksByStudentAndRegularExamId
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 59
 getAllStudentBlockedAndUnblockedSubjects
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 19
 copyExamHallSeatArrangement
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 38
 pseudoNormalizedMarkNotApproveStatus
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 17
 getExternalValuationMarkDiff
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentsExternalMarksByStudentExamDetail
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getMarkFailedCriteriaByBatchId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentsRegisteredForSupplyExamination
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 addUniversityMarkListPassPercentConfigs
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 29
 getUniversityMarkListPassPercentConfig
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 25
 removeUniversityMarkListPassPercentConfig
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getRegisteredRegularExamSubjects
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 60
 getAllExamsByExamRegId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 getExamRegisteredStudentsByExamDateTime
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 calculatePassedStudentsInPassoutBatches
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 35
 addStudentPassoutYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getStudentLastAttendedExamYearByStudentId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 createStudentPassoutYearCalculatorSchedulerLog
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getExamOnlinePaymentTransactionDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getPreviousBatchExamMarkDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 47
 getInternalExamComponents
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getExamsByRequest
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 48
 getSupplyExamRegistrationsByCourseTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentSupplyExamMarkDetailsBySupplyStudentId
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 104
 getExamDetailsForABatch
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 18
 checkIsConfirmedMark
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 35
 getRegisteredRegularExamSubjectsByStudentIdAndRegId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 78
 getStudentRegisteredExamFeePaymentDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getAllExamFineTypes
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 updateStudentExamRegistrationPaidStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 updateStudentExamSupplementaryPaidStatus
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 getExamRegistrationMonthYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 26
 getExamRegisteredStudentDetailsWithExamDateTime
0.00% covered (danger)
0.00%
0 / 1
306.00
0.00% covered (danger)
0.00%
0 / 120
 assignExamTimeSlot
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 57
 getExamTimeSlotForStudentSubject
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 36
 updateExamTimeSlotForStudentSubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 21
 getRegularExamTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getSupplyExamTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 isEnableEditExamRegAfterStudentRegistration
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 21
 getCourseTypeOfRegularExamRegistration
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 24
 searchExamRegistrationBatches
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 26
 searchSupplyExamRegistrationBatches
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamRegStudentNotRegisteredBatches
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 23
 getExamRegistrationBatches
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 28
 getStudentsForExamRegistration
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 23
 studentBulkExamRegistration
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 34
 getExamRegistrationsByBatch
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 blockUnblockStudentBySemesterWiseReason
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 30
 getStudentExamRegBlockedStatusSemesterwise
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 getSubjectsForBulkExamDefinition
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 64
 defineExam
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 56
 searchExamTypes
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 36
 getFeeTypesForExamRegistration
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 49
 getFineTypesForExamRegistration
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 49
 getAssignedPaymentOptions
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 22
 deleteExcludedStudentsFromExam
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 18
 getExamTypeNameById
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 12
 getSubjectWiseStudentInternalMarks
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 68
 getBothUniversityAndInternalMarksForAllSemesters
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 8
 getSubjectWiseAttendanceDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 mergeAttendanceDetails
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 24
 getInternalMarkDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 7
 mergeUniversityAndInternal
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 25
 getSupplyAttemptCount
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 getStudentsInExamHall
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 89
 getInternalExamSubjectBatches
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamAbsenteesCount
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentExamBatchBySemester
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSessionalExamStudentDetails
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 116
 getExamRegistrationDetailsByExamTypeID
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 createRetestSessionalExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getSessionalExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getStudentsListExamHallwise
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 79
 isConfirmedAssessmentMark
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 checkAssessmentMarkByExamId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 checkInternalSubjectPresentInThatBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 createSessionalMarkSettings
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getTransactionDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 22
 getExamRegStudentSettings
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamsListForReport
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 57
 getRegularExamsOfStudent
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 26
 getSupplyExamsOfStudent
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 22
 isSessionalExamMarkSubmittedByExamType
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getStaffPseudoSubjectDetailsInRetestExams
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 28
 getStaffPseudoSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getSessionalExamSubbatchStudentMarks
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 25
 blockStudentFromExamRegistrationBySubject
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 42
 getExamRegistrationsByBatchAndSem
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 20
 addSessionalExamSettings
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 48
 getReglarExamPaymentDetails
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 64
 getSupplyExamPaymentDetails
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 63
 getSupplyChanceCount
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 29
 getExamTypeIdByExamId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getExamDetailsByBatchIdSemIdAndExamRegId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 26
 getRegularExamDetailsByRegIdSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamDetailsForSupplementaryBySubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getRegularSupplyExamMark
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 15
 addStudentMarkBeforeModeration
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 updateRegularSupplyExamMark
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 15
 getStudentMarkBeforeModeration
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 getExamBatchesForPublishingTimeTable
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 setExamTimeTablePublishFlag
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 74
 getRegularExamDetailsByBatchIdSemIdAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 markAbsentStatus
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 73
 getAbsentStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getExamsFromPublishExamTimeTable
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 41
 getPublishExamDetailsBySubjectId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 43
 getSupplyExamStudentSubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSupplyRegisteredStudentsForSubjects
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getSupplyStudentWiseReport
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSubjectCategoryCode
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getSubjectRegularExamDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 50
 getSubjectSupplyExamDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 50
 getStudentLastExamByStudentId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 getStudentLastAppearedExamByStudentId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 23
 getAllRegularExamRegistrationByCourseTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 blockStudentsExamReg
0.00% covered (danger)
0.00%
0 / 1
210.00
0.00% covered (danger)
0.00%
0 / 58
 getStudentBlockedStatus
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 21
 getExternalMarksFinalizedByStudentId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getFeeTypesForExamRegisterApplication
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 21
 getCommonFeeTypesForExamRegisterApplication
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 23
 getStudentRegisteredExamFine
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getSumOfExamFees
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentExternalMarksWithMaxMark
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 16
 getExternalMarksFinalizedByStudentIdWithMaxMark
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 22
 getExamRegisteredStudents
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 26
 getExamSubjectsByBatch
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 21
 getRegisteredExamsDetailsById
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 getRevaluationMarkFinalized
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 8
 updateModerationDetailsForRevaluation
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getStudentExternalMarks
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 23
 updateAttendanceOfStudentsWithMigratedExternalMarks
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 15
 saveMigratedExternalMarksAndMarkAttendance
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 26
 getStudentSupplyMarksOfRegularExam
0.00% covered (danger)
0.00%
0 / 1
756.00
0.00% covered (danger)
0.00%
0 / 106
 getSubjectCategoryCodeByBatchSemSubjectID
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getDistinctExamSubjectsByExamReg
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 54
 getExamRegisteredStudentsWithExternalMarks
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 84
 getExamRegisteredStudentsByBatchAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 23
 getAllExamMarksByRequest
0.00% covered (danger)
0.00%
0 / 1
182.00
0.00% covered (danger)
0.00%
0 / 105
 updateExamExternalMarks
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 27
 getStudentMarksExistByExamId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 saveProgramResultMonthAndYear
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 31
 getProgramResultMonthAndYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getSubjectTypeByBatchSemSubjectID
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 24
 getExamsByExamRegistrationAndSem
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 41
 getExamDetailsByRequest
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 28
 getDistinctExamRegistrationByBatchStartYear
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 getDistinctSemesteresFromExamRegId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getBatchesFromExamRegId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 15
 changeBatchesExamRegistration
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 24
 getSupplyAbsentStatusByStudentAndRegularExamId
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 62
 getSupplyRegistrationBybatchIdAndMonthYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 subjectSupplyAttemptCount
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 28
 saveExamExternalMarks
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 52
 getSupplyExamPublishDate
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getHallTicketDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 32
 getExamRegistrationsByBatchRequest
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 30
 getStudentExamSubjects
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getStudentExamRegPaidStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getStudentExamsInAttendanceMarked
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getExamDetailsForOEExamsByRequest
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 64
 saveOnlineExaminations
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 94
 lastRegisteredExamStudentsByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 studentInteranlMarksBySubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 saveAuditCouseDates
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 getAuditCouseDates
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamRegisteredStudentsByBatchIdAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 16
 saveAuditCoursePassDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 getAuditCoursePassDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getGraceMarkDetailsByStudentIdAndSemid
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getReserveCategoryExamFees
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 getExamsByExamRegIdAndExamDate
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 37
 getSupplyRegistrationByBatchId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getRegularExamDetailsByBatchIdAndSemId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getSupplyRegistrationByMonthAndYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 updateStudentExamRevaluationPaidStatus
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getExamRegReceiptDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 19
 getSupplyExamRegReceiptDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 assignAllInternalValuationDates
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 40
 getExamDatesByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamStudentAttendanceCount
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 29
 getExamsByExamRegistrationRequest
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 60
 getExamValuationStaffs
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 18
 getExamRegisteredStudentsDetailsForValuationByRequest
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 60
 getStudentDetailsForRegExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 48
 getStudentDetailsForSupplementaryExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 45
 editExamTotalMarkById
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 11
 getHallAsssignedSubjectDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 22
 getsupplyRegistrationBySemIddAndExamYear
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getStudentsSgpaPassCountByRequest
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 16
 saveExamQpCodes
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 21
 getExamQpCodes
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 16
 getExamsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 46
 getExamRegisteredStudentDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 29
 getExamAttendance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 insertStudentAttendanceInExam
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 saveExamMarkMigration
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 23
 getExamMarkEntryForExamRegistration
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 30
 getExamsDetailsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 65
 getStudentsForExamByExamDetails
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 33
 getResultPublishDate
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 getExamRegisteredStudentsWithHeldStatus
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getFinalCgpa
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getFinalCgpaStudentWise
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getRegularExamSubjectListByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getAllExamTypes
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentRanksForProgressReports
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 80
 getNominalRollRemarks
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 15
 getPseudoSubjectExamTypeList
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 saveNominalRollRemarks
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 27
 getDistinctExamSubjectsByExamRegistrationRequest
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 37
 getExamRegisteredStudentsDetailsBySubject
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 81
 getExamRegisteredUgStudentsWithMarksBySubject
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 32
 getExamTheorySubjectsByBatch
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 21
 getExamTimeByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 getExamSubjectsAndValuationDatesByExamRegistrationRequest
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 44
 assignAllInternalValuationDatesSubjectWise
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 32
 getExamRegisteredStudentsWithMarksBySubject
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 32
 getAbsentStudentListByExam
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 19
 getSupplyExamsFromPublishExamTimeTable
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 34
 getSupplyPublishExamDetailsBySubjectId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 41
 getExamByExamRegDetails
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 11
 getStudentsRegisteredForSupplyExaminationByBatchSem
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getStudentSupplySubjectsForRegistrationSupply
0.00% covered (danger)
0.00%
0 / 1
2256.00
0.00% covered (danger)
0.00%
0 / 195
 saveResultSheetFooter
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 30
 getResultSheetFooter
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getPublishedRegularExamRegistration
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getStudentPublishedSupplyMarksOfRegularExam
0.00% covered (danger)
0.00%
0 / 1
306.00
0.00% covered (danger)
0.00%
0 / 79
 getPublishedSupplyExamRegistration
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getPublishedSupplyExamRegistrationByStudentId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getPublishedRegularExamRegistrationOfFailedStudent
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getStudentExamRegBlockedStatusList
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 23
 getOeExamResult
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 106
 getStudentsAdditionalCreditsByBatch
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 26
 getStudentExamMarkEditLogs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 18
 getStudentInternalMarkEditLogs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 getRegularExamDate
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getExamDatesByRegularSupplyExamRegistration
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getRegularExamPublishDetailsByBatchIdAndSemId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 getExamTypes
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 24
 updateExamMaxMarkByExamTypeId
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 getExamTypeBySubjectExceptSupply
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 insertStudentMarks
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 46
 changeMarksConfirm
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 31
 confirmMarkSubmitted
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 31
 updateExamWithImportedExamdetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getStudentSupplyExamSubjectsForRegistration
0.00% covered (danger)
0.00%
0 / 1
1560.00
0.00% covered (danger)
0.00%
0 / 177
 getExamMarkDetailsOfAStudent
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getDistinctExamRegisterationSubjects
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamRegisteredStudentsByExamRegIdAndSubjectId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 15
 getBatchAssignedCGPAGradeSchemes
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getExamRegistrationDetailsByRequest
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 13
 getExamDatesByExamRegistrationByRequest
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 saveStudentAdditionalCredits
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 18
 getOnlineExams
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 20
 getInternalExamsByBatchIdAndSemId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 createNewExamsForBatch
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 30
 assignAttendanceEndDate
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 15
 getAllSlowLearnerIdentification
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 20
 getAllRegisteredExams
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getStudentExams
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getExamStudentsBySubject
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 57
 getExamRegisteredStudentsDetailsBySubjectForReviewer
0.00% covered (danger)
0.00%
0 / 1
90.00
0.00% covered (danger)
0.00%
0 / 58
 getExamsByStudentdAndExamDate
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 45
 getStudentExamMarksByArg
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 14
 getStudentAvgMarks
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 getAllExamDetailsWithBatchAndSubject
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 27
 getStatusOfWorkflowRequest
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 getExamDetailsByExamTypeForStudent
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 47
 getExamByExamTypeId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getStudentExamDetails
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 28
<?php
namespace com\linways\core\ams\professional\service;
use com\linways\base\util\SecurityUtils;
use com\linways\base\helper\ResultHandler;
use com\linways\core\ams\professional\dto\Subject;
use com\linways\core\ams\professional\dto\ExamType;
use com\linways\core\ams\professional\dto\ExamSubject;
use com\linways\core\ams\professional\util\CommonUtil;
use com\linways\core\ams\professional\service\BatchService;
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\core\ams\professional\dto\ExamEnrollmentFees;
use com\linways\core\ams\professional\dto\FailedStudentCount;
use com\linways\core\ams\professional\service\StudentService;
use com\linways\core\ams\professional\service\SubjectService;
use com\linways\core\ams\professional\constant\BatchConstants;
use com\linways\core\ams\professional\dto\UniversityExamMarks;
use com\linways\core\ams\professional\mapper\ExamServiceMapper;
use com\linways\core\ams\professional\service\nba\NbaCoService;
use com\linways\core\ams\professional\dto\StudentWiseFailedRate;
use com\linways\core\ams\professional\dto\SubjectWiseFailedRate;
use com\linways\core\ams\professional\mapper\InternalExamMapper;
use com\linways\core\ams\professional\service\AttendanceService;
use com\linways\core\ams\professional\service\CourseTypeService;
use com\linways\core\ams\professional\constant\SettingsConstants;
use com\linways\core\ams\professional\dto\SlowLearnerIdentification;
use com\linways\core\ams\professional\request\GetExamDetailsRequest;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\response\GetExamTimeTablesResponse;
use com\linways\core\ams\professional\response\GetYearOutStudentResponse;
use com\linways\core\ams\professional\request\AddStudentPassoutYearRequest;
use com\linways\core\ams\professional\request\DeleteExcludedStudentRequest;
use com\linways\core\ams\professional\constant\ExamType as ExamTypeConstant;
use com\linways\core\ams\professional\constant\examcontroller\CourseTypeConstants;
use com\linways\core\ams\professional\constant\examcontroller\ExamSubjectTypeConstants;
use com\linways\core\ams\professional\request\examcontroller\ConsolidatedMarkReportRequest;
use com\linways\core\ams\professional\dto\examcontroller\UniversityMarkListPassPercentConfig;
use com\linways\core\ams\professional\service\examcontroller\finalMarkList\ConsolidatedMarkReportService;
class ExamService 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 = ExamServiceMapper::getInstance()->getMapper();
        $this->internalExamMapper = InternalExamMapper::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;
    }
    /**
     * department analysis
     *
     * @param int $batchID
     * @param int $semID
     * @param int $examTypeID
     * @param float $passPercent
     */
    public function getFailedStudentRate($batchID, $semID, $examTypeID, $totalSubfailed, array $passPoint, $passPercent)
    {
        $batchService = BatchService::getInstance();
        $failed_subject_array = [];
        $faildRateResponse = [];
        $failedRate = NULL;
        // Get student count in a batch
        $nof_students = $batchService->getBatchStudentCount($batchID);
        if ($nof_students > 0) {
            // Get no of exams conducted in a batch and sem of given exam type
            $attendedStudentIds = $this->getExamAttendedStudentIds($batchID, $semID, $examTypeID);
            if ($attendedStudentIds != NULL && count($attendedStudentIds) > 0) {
                $no_of_exams = $this->getExamCount($batchID, $semID, $examTypeID);
                for ($i = $totalSubfailed; $i >= 0; $i--) {
                    $failed_subject_array[$i] = 0;
                }
                foreach ($attendedStudentIds as $studentId) {
                    $subjectFailedCount = $this->getFailedSubjectCount($batchID, $semID, $studentId, $examTypeID, $passPercent);
                    if ($subjectFailedCount <= $totalSubfailed) {
                        $failed_subject_array[$subjectFailedCount] = $failed_subject_array[$subjectFailedCount] + 1;
                    }
                }
                $totalpoints = 0;
                $faildRateOfBatch = new \stdClass();
                foreach ($failed_subject_array as $subjectFailed => $count) {
                    $failedRate = new \stdClass();
                    $percentage = $this->getPercentage($count, $nof_students, 2);
                    $failedRate->count = $count;
                    $failedRate->percentage = $percentage;
                    $failedRate->points = $percentage * $passPoint[$subjectFailed];
                    $faildRateResponse[$subjectFailed] = $failedRate;
                    $totalpoints += $percentage * $passPoint[$subjectFailed];
                }
                $batchDetails = $batchService->getBatchDetails($batchID);
                $faildRateOfBatch->rate = $faildRateResponse;
                $faildRateOfBatch->totalStudents = $nof_students;
                $faildRateOfBatch->totalPoint = $totalpoints;
                $faildRateOfBatch->deptName = $batchDetails->deptName;
                $faildRateOfBatch->semName = $batchDetails->semName;
                $faildRateOfBatch->batchStartYear = $batchDetails->batchStartYear;
                $faildRateOfBatch->batchEndYear = $batchDetails->batchEndYear;
            }
        }
        return $faildRateOfBatch;
    }
    /**
     * get faild student rate with faild subject by semester wise
     *
     * @param int $semID
     * @param int $examTypeID
     * @param int $totalSubfailed
     * @param array $passPoint
     * @param float $passPercent
     * @return $faildRateResponse
     */
    public function getFailedStudentRateBySem($semID, $examTypeID, $totalSubfailed, array $passPoint, $passPercent, $typeCode)
    {
        $faildRateResponse = [];
        $rankDept = [];
        $deptTotalPoint = [];
        $sqlBatch = "SELECT bt.batchID,bt.deptID FROM batches bt inner join batch_course_type bc on bc.id=bt.patternID WHERE bt.semID=$semID and bc.type_code='$typeCode'";
        $resBatch = sql_query($sqlBatch, $this->getConnection());
        if ($resBatch && sql_num_rows($resBatch) > 0) {
            while ($row = sql_fetch_array($resBatch)) {
                $batchID = $row[batchID];
                $deptID = $row[deptID];
                $faildRateOfBatch = $this->getFailedStudentRate($batchID, $semID, $examTypeID, $totalSubfailed, $passPoint, $passPercent);
                if ($faildRateOfBatch) {
                    if ($faildRateResponse[$deptID] != NULL) {
                        $totalStudents = $faildRateOfBatch->totalStudents + $faildRateResponse[$deptID]->totalStudents;
                        $rate = $faildRateOfBatch->rate;
                        $currentRate = $faildRateResponse[$deptID]->rate;
                        $totalpoints = 0;
                        for ($i = 0; $i <= $totalSubfailed; $i++) {
                            $count = $currentRate[$i]->count + $rate[$i]->count;
                            $percentage = $this->getPercentage($count, $totalStudents, 2);
                            $points = $percentage * $passPoint[$i];
                            $totalpoints += $points;
                            $currentRate[$i]->count = $count;
                            $currentRate[$i]->percentage = $percentage;
                            $currentRate[$i]->points = $points;
                        }
                        $faildRateResponse[$deptID]->rate = $currentRate;
                        $faildRateResponse[$deptID]->totalStudents = $totalStudents;
                        $faildRateResponse[$deptID]->totalPoint = $totalpoints;
                    } else {
                        $faildRateResponse[$deptID] = $faildRateOfBatch;
                    }
                    $deptTotalPoint[$deptID] = $faildRateResponse[$deptID]->totalPoint;
                }
            }
            arsort($deptTotalPoint);
            $rank = 1;
            foreach ($deptTotalPoint as $deptID => $point) {
                $rankDept[$deptID] = $rank;
                $rank++;
            }
            foreach ($faildRateResponse as $deptID => $deptRate) {
                $deptRate->rank = $rankDept[$deptID];
            }
        }
        return $faildRateResponse;
    }
    /**
     * get percentage
     *
     * @param int $count
     * @param int $total
     * @param int $round
     * @return $percentage
     */
    public function getPercentage($count, $total, $round)
    {
        $percentage = round(($count / $total) * 100, $round);
        return $percentage;
    }
    /**
     *
     * @param int $batchID
     * @param int $semID
     * @param int $studentID
     * @param int $examTypeID
     * @param float $passPercent
     */
    public function getFailedSubjectCount($batchID, $semID, $studentID, $examTypeID, $passPercent)
    {
        $sql = "SELECT COUNT(subjectID) as failedCount FROM student_marks WHERE semID=\"$semID\" AND batchID=\"$batchID\" AND studentID=\"$studentID\" AND examTypeID=\"$examTypeID\" AND percentage<$passPercent";
        $failed_countResp = $this->executeQueryForObject($sql);
        return $failed_countResp != null ? $failed_countResp->failedCount : 0;
    }
    /**
     *
     * @param int $batchID
     * @param int $semID
     * @param int $examTypeID
     * @return number
     */
    public function getExamCount($batchID, $semID, $examTypeID)
    {
        $sql = "SELECT COUNT(DISTINCT t2.examID) as examCount FROM exam t1,student_marks t2,subjects t3 WHERE t1.batchID=\"$batchID\" AND t1.semID=\"$semID\" AND t1.examTypeID=\"$examTypeID\" AND t1.examID=t2.examID AND t1.subjectID=t3.subjectID ORDER BY t3.subjectID";
        $examCountResp = $this->executeQueryForObject($sql);
        return $examCountResp != null ? $examCountResp->examCount : 0;
    }
    /**
     * get Students ids who attended in an exam
     *
     * @param int $batchID
     * @param int $semID
     * @param int $examTypeID
     * @return $attendedStudentIds
     */
    public function getExamAttendedStudentIds($batchID, $semID, $examTypeID)
    {
        $attendedStudentIds = [];
        $attendedStudentResult = [];
        $attendedStudentSql = "SELECT DISTINCT(studentID) as studentId FROM student_marks WHERE semID='$semID' AND batchID='$batchID' AND examTypeID='$examTypeID'";
        $attendedStudentResult = $this->executeQueryForList($attendedStudentSql);
        if ($attendedStudentResult && count($attendedStudentResult) > 0) {
            foreach ($attendedStudentResult as $student) {
                $attendedStudentIds[] = $student->studentId;
            }
        }
        return $attendedStudentIds;
    }
    public function getExamAttendedStudentIdsByBatchId($batchID, $semID, $examTypeID,$subjectId)
    {
        $attendedStudentIds = [];
        $attendedStudentResult = [];
        $attendedStudentSql = "SELECT DISTINCT(sm.studentID) as studentId FROM student_marks sm inner join studentaccount sa on  (sa.batchID = sm.batchID AND sm.studentID = sa.studentId )   WHERE sm.semID='$semID' AND sm.batchID='$batchID' AND sm.examTypeID='$examTypeID' AND sm.subjectID='$subjectId' AND sm.marksObtained <>-1";
        $attendedStudentResult = $this->executeQueryForList($attendedStudentSql);
        if ($attendedStudentResult && count($attendedStudentResult) > 0) {
            foreach ($attendedStudentResult as $student) {
                $attendedStudentIds[] = $student->studentId;
            }
        }
        return $attendedStudentIds;
    }
    /**
     * for get exam type by exam type id
     *
     * @param int $examTypeId
     * @return object $examType
     */
    public function getExamTypeById($examTypeId)
    {
        $sql = "SELECT * FROM exam_type WHERE typeID=$examTypeId";
        $examType = $this->executeQueryForObject($sql);
        return $examType;
    }
    /**
     * for get exam type ($canFacultyEdit flag if true fetch exam types which staff can create exams under them.)
     *
     * @return object $examType
     */
    public function getExamType($showHidden = false, $canFacultyEdit = false, $isInternal = TRUE, $hasParantExamTypeId = false, $isSupply = false)
    {
        $conditions = NULL;
        if ($showHidden) {
            $conditions = 'WHERE canShow IN(1,0) ';
        } else {
            $conditions = 'WHERE canShow = 1 ';
        }
        if ($canFacultyEdit) {
            $conditions .= ' AND can_faculty_create=1';
        }
        if ($isInternal) {
            $conditions .= " AND isInternal = 1";
        }
        if ($hasParantExamTypeId) {
            $conditions .= " AND parent_exam_typeID IS NOT NULL";
        }
        if ($isSupply) {
            $conditions .= " AND isSupply = 1";
        }
        $sql = "SELECT typeID, typeName, typeDesc, can_faculty_create, canShow, isInternal, isSupply, parent_exam_typeID, properties->>'$.finalMarkCalculation' as finalMarkCalculation
                FROM exam_type $conditions ORDER BY typeName ASC";
        $examType = $this->executeQueryForList($sql);
        return $examType;
    }
    /**
     * check exam type using any student mark
     *
     * @param int $examTypeId
     * @return $success
     */
    public function checkExamTypeUsingOrNot($examTypeId)
    {
        $sql = "SELECT markID FROM student_marks WHERE examTypeID=$examTypeId LIMIT 1";
        $result = $this->executeQueryForObject($sql);
        return $result == null ? false : true;
    }
    /**
     * get student failed rate grade wise
     * @param int $batchId
     * @param int $semId
     * @return \com\linways\core\ams\professional\dto\StudentWiseFailedRate
     */
    public function getFailedRateStudentGradeWise($batchId, $semId)
    {
        $studentWiseFailedRate = new StudentWiseFailedRate();
        $studentWiseFailedRate->totalNoSubjects = $this->getUniversityExamCount($batchId, $semId);
        $studentWiseFailedRate->failedStudentCountList = $this->getFailedStudentSubjectCount($batchId, $semId);
        return $studentWiseFailedRate;
    }
    /**
     * get subject failed rate grade wise
     * @param int $batchId
     * @param int $semId
     * @return \com\linways\core\ams\professional\dto\StudentWiseFailedRate
     */
    public function getFailedRateSubjectGradeWise($batchId, $semId)
    {
        $subjectWiseFailedRate = new SubjectWiseFailedRate();
        $subjectWiseFailedRate->totalNoSubjects = $this->getUniversityExamCount($batchId, $semId);
        $subjectWiseFailedRate->failedRateSubjectList = $this->getFailedRateSubjects($batchId, $semId);
        return $subjectWiseFailedRate;
    }
    /**
     * get total count of university exams
     * @param int $batchId
     * @param int $semId
     * @return int $count
     */
    public function getUniversityExamCount($batchId, $semId)
    {
        $sql = "SELECT COUNT(distinct examID) as total FROM universityExams WHERE batchID=\"$batchId\" AND semID=\"$semId\"";
        $count = $this->executeQueryForObject($sql)->total;
        return $count;
    }
    /**
     * get the id of failed grade
     * @param int $batchId
     * @return int $id
     */
    public function getFaildGradeId($batchId)
    {
        $ids = [];
        $sql = "select ug.gradeID as id FROM university_gradepoints ug INNER JOIN university_assignbatchcourse ua ON ua.typeID = ug.typeID WHERE ua.batchID=$batchId AND ug.gradePoint=0";
        $ids = $this->executeQueryForList($sql);
        $gradeId = "";
        foreach ($ids as $id) {
            $gradeId = $gradeId . $id->id . ', ';
        }
        $gradeId = rtrim($gradeId, ', ');
        return $gradeId;
    }
    /**
     * get the student failed count
     * @param int $batchId
     * @param int $semId
     * @return \com\linways\core\ams\professional\dto\FailedStudentCount[]|number[]
     * @throws ProfessionalException
     */
    public function getFailedStudentSubjectCount($batchId, $semId)
    {
        $failedStudentCount = [];
        $studentFailedCount = NULL;
        $failedCount = [];
        $failedStudent = [];
        $examCount = $this->getUniversityExamCount($batchId, $semId);
        $typeId = $this->getFaildGradeId($batchId);
        if ($isCurrentSem) {
            $sql = "SELECT us.studentID, count(CASE WHEN us.gradeObtained IN (" . $typeId . ") THEN 1 END )AS count FROM university_studentgrade us INNER JOIN studentaccount st ON st.studentID = us.studentID inner join semesters joinedSem on joinedSem.semID = st.joiningSemId inner join semesters sem on sem.semID = us.semID WHERE st.batchID=" . $batchId . " AND us.semID= " . $semId . " and joinedSem.orderNo <= sem.orderNo group by us.studentID";
        } else {
            $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
            $sql = "SELECT studentID, count FROM (select us.studentID, count(CASE WHEN us.gradeObtained IN (" . $typeId . ") THEN 1 END )AS count from university_studentgrade us INNER JOIN studentaccount st ON st.studentID = us.studentID inner join semesters joinedSem on joinedSem.semID = st.joiningSemId inner join semesters sem on sem.semID = us.semID WHERE st.batchID=" . $batchId . " AND us.semID= " . $semId . " and joinedSem.orderNo <= sem.orderNo group by us.studentID union select us.studentID, count(CASE WHEN us.gradeObtained IN (" . $typeId . ") THEN 1 END )AS count from university_studentgrade us INNER JOIN failed_students fs on fs.studentID = us.studentID inner join studentaccount st ON st.studentID = us.studentID inner join semesters joinedSem on joinedSem.semID = st.joiningSemId inner join semesters fsem on fsem.semID = fs.failedInSemester WHERE fs.previousBatch=" . $batchId . " AND us.semID= " . $semId . " and joinedSem.orderNo <= " . $semDetails->orderNo . " and fsem.orderNo > " . $semDetails->orderNo . " group by us.studentID) as students ;";
        }
        try {
            $studentFailedCount = $this->executeQueryForList($sql);
            if ($studentFailedCount != NULL && count($studentFailedCount) > 0) {
                for ($i = 0; $i <= $examCount; $i++) {
                    $failedCount[$i] = 0;
                    $failedStudent[$i] = [];
                }
                foreach ($studentFailedCount as $student) {
                    if (!$failedCount[$student->count]) {
                        $failedCount[$student->count] = 1;
                        $failedStudent[$student->count][] = $student->studentID;
                    } else {
                        $failedCount[$student->count]++;
                        $failedStudent[$student->count][] = $student->studentID;
                    }
                }
                if ($failedCount != NULL && count($failedCount) > 0) {
                    foreach ($failedCount as $failedSubjects => $count) {
                        $failedRate = new FailedStudentCount();
                        $failedRate->failedSubjectCount = $failedSubjects;
                        $failedRate->studentFailedCount = $count;
                        $failedRate->studentIds = $failedStudent[$failedSubjects];
                        $failedStudentCount[] = $failedRate;
                    }
                }
            }
            return $failedStudentCount;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $failedCount;
    }
    /**
     * get the subject failed rate
     * @param int $batchId
     * @param int $semId
     * @return $failedRateSubjectList
     */
    public function getFailedRateSubjects($batchId, $semId)
    {
        $failedRateSubjectList = [];
        $failedGradID = $this->getFaildGradeId($batchId);
        $currentSem = SemesterService::getInstance()->isCurrentSemester($batchId, $semId);
        if ($currentSem) {
            $sqlStudentCount = " select count( sa.studentID) from university_studentgrade usg inner join studentaccount sa on usg.studentID = sa.studentID inner join semesters joinSem on sa.joiningSemID = joinSem.semID inner join batches ba on sa.batchID = ba.batchID inner join semesters sem on sem.semID = ba.semID where  joinSem.orderNo <= sem.orderNo and usg.examID = ue.examID";
        } else {
            $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
            $sqlStudentCount = "select count(studentID)  as count from ( select  sa.studentID, examID from university_studentgrade usg inner join studentaccount sa on usg.studentID = sa.studentID inner join batches ba on sa.batchID =  ba.batchID inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID where ba.batchID = " . $batchId . " and joinedSem.orderNo <= " . $semDetails->orderNo . " union select sa.studentID, examID from university_studentgrade usg inner join failed_students fs on usg.studentID = fs.studentID left join studentaccount sa on fs.studentID= sa.studentID inner join semesters fsem on fsem.semID = fs.failedInSemester inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID where previousBatch = " . $batchId . " and fsem.orderNo > " . $semDetails->orderNo . " and joinedSem.orderNo <= " . $semDetails->orderNo . " ) as students where examID = ue.examID";
        }
        $sql = "select distinct ue.examID, sub.subjectID, sub.subjectName as subjectCode, sub.subjectDesc as subjectName,sa.staffID,sa.staffName,
( " . $sqlStudentCount . " ) as studentsAppeared ,
(select count(studentID) from university_studentgrade usg where usg.examID = ue.examID ";
        if ($failedGradID) {
            $sql .= "and usg.gradeObtained NOT IN ($failedGradID)";
        }
        $sql .= ") as studentsPassed
 from subjects sub INNER JOIN universityExams ue ON ue.subjectID=sub.subjectID
inner join sbs_relation sbs on sbs.subjectID = sub.subjectID and sbs.semID = ue.semID and sbs.batchID = ue.batchID
inner join staffaccounts sa on sa.staffID = sbs.staffID
WHERE ue.batchID=$batchId AND ue.semID=$semId";
        $failedRateSubjectList = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_FAILED_RATE_SUBJECTS]);
        return $failedRateSubjectList;
    }
    /**
     *
     * @param int $batchId
     * @return string $entryType
     */
    public function getExamEntryType($batchId)
    {
        $entryType = NULL;
        $sql = "SELECT t2.entryType FROM university_assignbatchcourse t1, university_coursetypegrading t2 where t1.batchID=\"" . $batchId . "\" and t1.typeID=t2.typeID";
        $type = $this->executeQueryForObject($sql)->entryType;
        if ($type == 1) {
            $entryType = "MARK";
        } elseif ($type == 2) {
            $entryType = "GRADE";
        }
        return $entryType;
    }
    /**
     * get details of student university exam grade wise
     * @param int $studentId
     * @param int $batchId
     * @param int $semId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function getStudentGradeListByStudentId($studentId, $batchId, $semId)
    {
        $studentExamDetails = NULL;
        $sql = "select sa.studentID, sa.studentName, sa.rollNo, sub.subjectID, sub.subjectName as subjectCode, sub.subjectDesc as subjectName, ug.letterGrade as gradeObtained FROM studentaccount sa INNER JOIN university_studentgrade usg ON usg.studentID = sa.studentID INNER JOIN subjects sub ON sub.subjectID=usg.subjectID INNER JOIN university_gradepoints ug ON ug.gradeID = usg.gradeObtained WHERE sa.batchID=$batchId AND usg.semID=$semId AND usg.studentID = $studentId order by  usg.studentID";
        $studentExamDetails = $this->executeQueryForObject($sql, false, $this->mapper[ExamServiceMapper::GET_STUDENT_GRADE_DETAILS]);
        return $studentExamDetails;
    }
    /**
     * get details of students university exam grade wise
     * @param array $studentIds
     * @param int $batchId
     * @param int $semId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     */
    public function getStudentGradeListByStudentIds($studentIds, $batchId, $semId)
    {
        $studentExamDetails = NULL;
        $sql = "select sa.studentID, sa.studentName, sa.rollNo,  sub.subjectID, sub.subjectName as subjectCode, sub.subjectDesc as subjectName, ug.letterGrade as gradeObtained FROM studentaccount sa INNER JOIN university_studentgrade usg ON usg.studentID = sa.studentID inner join universityExams ue on ue.examID = usg.examID  INNER JOIN subjects sub ON sub.subjectID=usg.subjectID INNER JOIN university_gradepoints ug ON ug.gradeID = usg.gradeObtained WHERE ue.batchID=$batchId AND usg.semID=$semId AND usg.studentID IN (" . implode(',', $studentIds) . ") order by  usg.studentID";
        $studentExamDetails = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_STUDENT_GRADE_DETAILS]);
        return $studentExamDetails;
    }
    /**
     * get details of university exams
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getUniversityExamDetails($batchId, $semId = 0)
    {
        $examDetails = NULL;
        $sql = "select ue.examID, ue.examName, sub.subjectID, sub.subjectName as subjectCode, sub.subjectDesc as subjectName FROM subjects sub INNER JOIN universityExams ue ON sub.subjectID=ue.subjectID WHERE ue.batchID=$batchId";
        if ($semId) {
            $sql .= " AND ue.semID=$semId";
        }
        $sql .= " order by  ue.examID";
        $examDetails = $this->executeQueryForList($sql);
        return $examDetails;
    }
    /**
     * Get count of students appeared for the exam
     * @param int $semId
     * @param int $examId
     * @param int $examTypeId
     * @param int $batchId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentsAppearedCount($semId, $examId, $examTypeId, $batchId)
    {
        $semId = $this->realEscapeString($semId);
        $examId = $this->realEscapeString($examId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT COUNT(distinct(t2.studentID)) as count FROM student_marks t1, studentaccount t2 WHERE t1.examID=$examId AND t1.examTypeID=$examTypeId  AND t1.marksObtained!=-1 AND t2.studentID=t1.studentID AND t1.semID=$semId  AND t2.batchID=$batchId";
        try {
            $studentsAppearedCount = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentsAppearedCount;
    }
    /**
     *
     * @param int $semID
     * @param int $examId
     * @param int $examTypeId
     * @param int $batchId
     * @param float $passPercent
     * @throws ProfessionalException
     */
    public function getStudentsFailedCount($semId, $examId, $examTypeId, $batchId, $passPercent)
    {
        $sql = "SELECT COUNT(distinct(t2.studentID)) as count FROM student_marks t1, studentaccount t2 WHERE t1.semID=$semId AND t1.examID=$examId AND t1.examTypeID=$examTypeId AND t1.percentage<$passPercent AND  t1.marksObtained!=-1 AND t2.studentID=t1.studentID AND  t2.batchID=$batchId";
        try {
            $studentsFailedCount = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentsFailedCount;
    }
    //     public function getStudentsFailedCount($semID,$examId,$examTypeId,$batchId,$passPercent)
    //     {
    //         $sql = "SELECT COUNT(distinct(t2.studentID)) as count FROM student_marks t1, studentaccount t2 WHERE  t1.semID=$semID AND t1.examID=$examId AND t1.examTypeID=$examTypeId AND t1.percentage<$passPercent AND  t1.marksObtained!=-1 AND t2.studentID=t1.studentID AND t2.batchID=t1.batchID AND  t2.batchID=$batchId";
    //         try {
    //             $studentsFailedCount = $this->executeQueryForObject($sql);
    //         } catch (\Exception $e) {
    //             throw new ProfessionalException($e->getMessage(),$e->getCode());
    //         }
    //         return $studentsFailedCount;
    //     }
    /**
     * Get exam details and subject details in a batch
     * @param int $batchId
     * @param int $examTypeId
     * @throws ProfessionalException
     */
    public function getExamDetailsOfSubjectByBatch($semId, $batchId, $examTypeId)
    {
        $sql = "SELECT DISTINCT(e.examID),e.examName,s.subjectID, s.subjectName,s.subjectDesc,subbatchID FROM exam e,subjects s WHERE e.semID=$semId AND e.batchID=$batchId AND e.examTypeID=$examTypeId AND e.subjectID=s.subjectID ORDER BY s.subjectID";
        try {
            $examDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examDetails;
    }
    /**
     * get assigned exam hall details by group id
     * @param int $groupId
     * @return $hallDetails
     * @throws ProfessionalException
     */
    public function getAssignedExamHallsByGroupId($groupId)
    {
        $hallDetails = NULL;
        $sql = "SELECT t1.hallID, t2.hallName, t1.noofseat, t1.studentperseat, t1.noofrows, t1.noofcolumn, t1.noofTeachers, t1.noofstudents FROM exam_group_halls t1, exam_halls t2 where t1.groupID = \"$groupId\" and t2.hallID = t1.hallID order by t2.hallprefNo asc";
        try {
            $hallDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $hallDetails;
    }
    /**
     * get hall details by hall id
     * @param int $groupId
     * @return $hallDetails
     * @throws ProfessionalException
     */
    public function getHallDetails($hallId)
    {
        $hallDetails = NULL;
        $sql = "SELECT hallID, hallName, noofseat, studentperseat, noofrows, noofcolumn, hallpattern, seatnoStart FROM exam_halls where hallID='$hallId'";
        try {
            $hallDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $hallDetails;
    }
    public function getExamDetailsbyGroupId($groupId)
    {
        $groupId = $this->realEscapeString($groupId);
        $examDetails = NULL;
        $sql = "select t1.examID, t1.examName, t1.subjectID, t1.examTotalMarks, t1.examStartTime, t1.examEndTime, t1.examDate, t1.semID, t1.examTypeID, t2.subjectName, t2.subjectDesc, t3.typeName, t3.typeDesc, t4.batchName, t4.batchDesc, t1.batchID, (select count(t6.studentID) from studentaccount t6, exam t7 where t6.batchID=t7.batchID and t7.examID=t1.examID and t6.studentID not in(select studentID from exam_excluded_students where examID=t1.examID)) as studentcount from exam t1, subjects t2, exam_type t3, batches t4, exam_group_exams t5 where t1.examID=t5.examID and t2.subjectID = t1.subjectID and t3.typeID = t1.examTypeID and t4.batchID = t1.batchID and t5.groupID = \"$groupId\" order by -t5.arrangement_order desc, studentcount desc";
        try {
            $examDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
    /**
     * get exam details using examid and group id
     * @param int $groupId
     * @param int $examId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetails($groupId, $examId)
    {
        $groupId = $this->realEscapeString($groupId);
        $examId = $this->realEscapeString($examId);
        $examDetails = NULL;
        $sql = "select t1.examID, t1.subjectID, t1.batchID, (select count(t3.studentID) from studentaccount t3, exam t4 where t3.batchID=t4.batchID and t4.examID=t1.examID and t3.studentID not in(select studentID from exam_excluded_students where examID=t1.examID)) as studentcount from exam t1, exam_group_exams t2 where t2.examID= t1.examID and t2.groupID=\"$groupId\" and t1.examID=$examId order by -t2.arrangement_order desc, studentcount desc";
        try {
            $examDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
    /**
     * get student details by exam
     * @param int $examId
     * @param int $groupId
     * @param int $limit
     * @param string $orderBy
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentByExam($examId, $groupId, $limit, $orderBy)
    {
        $studentDetails = NULL;
        $groupId = $this->realEscapeString($groupId);
        $examId = $this->realEscapeString($examId);
        $batchId = ExamService::getInstance()->getExamDetails($groupId, $examId)->batchID;
        $sql = "select studentID, rollNo, regNo from studentaccount where batchID =\"$batchId\" and studentID not in(select studentID from exam_excluded_students where batchID = \"$batchId\" and examID=\"$examId\") and studentID NOT IN(select studentID FROM exam_hall_arranged_students WHERE groupID=$groupId AND examID=$examId) order by $orderBy asc limit $limit";
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * get total count of student in an exam
     * @param int $examId
     * @param int $groupId
     * @return $studentCount
     * @throws ProfessionalException
     */
    public function getStudentCountByExam($examId, $groupId)
    {
        $studentCount = 0;
        $groupId = $this->realEscapeString($groupId);
        $examId = $this->realEscapeString($examId);
        $batchId = ExamService::getInstance()->getExamDetails($groupId, $examId)->batchID;
        $sql = "select count(studentID) as studentCount from studentaccount where batchID =\"$batchId\" and studentID not in(select studentID from exam_excluded_students where batchID = \"$batchId\" and examID=\"$examId\")";
        try {
            $studentCount = $this->executeQueryForObject($sql)->studentCount;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentCount;
    }
    public function getSeatDetails($groupId, $hallId, $col, $row, $seatPosition)
    {
        $seatDetails = NULL;
        $groupId = $this->realEscapeString($groupId);
        $hallId = $this->realEscapeString($hallId);
        $sql = "select studentperseat, seats, noofstudents, columnwiseseats from exam_group_hall_seating where groupID=\"$groupId\" and hallID=\"$hallId\" and rowNo=\"$row\" and columnNo=\"$col\" and FIND_IN_SET(" . $seatPosition . ", seats) and seats IS NOT NULL";
        try {
            $seatDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $seatDetails;
    }
    /**
     * assign students to hall
     * @param array of ExamHallArrangedStudents $examHallStudentList
     */
    public function assignStudentToExamHall($examHallStudentList)
    {
        if (count($examHallStudentList) > 0) {
            $sql = "insert into exam_hall_arranged_students(groupID, hallID, studentID, examID, seatNo, rowNo, columnNo, seat) values ";
            $values = [];
            foreach ($examHallStudentList as $student) {
                $values[] = "(\"$student->groupId\", \"$student->hallId\", \"$student->studentId\", \"$student->examId\", \"$student->seatNo\", \"$student->rowNo\", \"$student->columnNo\", \"$student->seat\")";
            }
            $sql .= implode(',', $values);
            try {
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
    }
    /**
     * get exam hall assigned student details
     * @param int $hallId
     * @param int $groupId
     * @param int $rowNo
     * @param int $columnNo
     * @param int $seat
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamHallAssignedStudentDetails($hallId, $groupId, $rowNo, $columnNo, $seat)
    {
        $studentDetails = NULL;
        $groupId = $this->realEscapeString($groupId);
        $hallId = $this->realEscapeString($hallId);
        $sql = "select eha.seatNo, sa.rollNo, sa.studentName, sa.regNo FROM exam_hall_arranged_students eha INNER JOIN studentaccount sa ON sa.studentID=eha.studentID WHERE eha.rowNo=$rowNo AND  eha.columnNo =$columnNo AND hallID=$hallId AND groupID=$groupId AND seat=$seat";
        try {
            $studentDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * get exam hall assigned student count
     * @param int $groupId
     * @param int $examId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamHallAssignedStudentCount($groupId, $examId)
    {
        $studentAssignedCount = 0;
        $examId = $this->realEscapeString($examId);
        $groupId = $this->realEscapeString($groupId);
        $batchId = ExamService::getInstance()->getExamDetails($groupId, $examId)->batchID;
        $sql = "select count(eha.studentID) as count FROM exam_hall_arranged_students eha INNER JOIN studentaccount sa ON sa.studentID=eha.studentID WHERE groupID=$groupId AND sa.batchID=$batchId";
        try {
            $studentAssignedCount = $this->executeQueryForObject($sql)->count;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentAssignedCount;
    }
    /**
     * delete assigned students from hall
     * @param array of ExamHallArrangedStudents $examHallStudentList
     */
    public function deleteAssignStudentFromExamHall($groupId, $hallId, $col)
    {
        $groupId = $this->realEscapeString($groupId);
        $hallId = $this->realEscapeString($hallId);
        $sql = "delete from exam_hall_arranged_students WHERE groupID=$groupId AND hallID=$hallId AND columnNo=$col";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     *
     * @param int $groupId
     * @param int $hallId
     * @param int $col
     * @param int $startRow
     * @param int $endRow
     * @param int $seat
     * @return int $count
     * @throws ProfessionalException
     */
    public function getCountOfAssignedStudents($groupId, $hallId, $col, $startRow, $endRow, $seat)
    {
        $count = 0;
        $sql = "select count(groupID) as count from exam_hall_arranged_students WHERE groupID=$groupId AND hallID=$hallId AND columnNo=$col AND rowNo BETWEEN $startRow AND $endRow AND seat=$seat";
        try {
            $count = $this->executeQueryForObject($sql)->count;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $count;
    }
    /* Save exam hall arranged structure of specific exam
     * @param ExamHallArrangedStructure $examHallArrangedStructure
     */
    public function saveExamHallArrangedStructure($examHallArrangedStructure)
    {
        $examHallArrangedStructure->hallId = $this->realEscapeString($examHallArrangedStructure->hallId);
        $examHallArrangedStructure->groupId = $this->realEscapeString($examHallArrangedStructure->groupId);
        $examHallArrangedStructure->examId = $this->realEscapeString($examHallArrangedStructure->examId);
        $examHallArrangedStructure->columnNo = $this->realEscapeString($examHallArrangedStructure->columnNo);
        $examHallArrangedStructure->seatStartNo = $this->realEscapeString($examHallArrangedStructure->seatStartNo);
        $examHallArrangedStructure->seatEndNo = $this->realEscapeString($examHallArrangedStructure->seatEndNo);
        $examHallArrangedStructure->seatLineNo = $this->realEscapeString($examHallArrangedStructure->seatLineNo);
        $examHallArrangedStructure->createdBy = $this->realEscapeString($examHallArrangedStructure->createdBy);
        $examHallArrangedStructure->updatedBy = $this->realEscapeString($examHallArrangedStructure->updatedBy);
        $sql = "insert into examHallArrangedStructure(groupId, examId, columnNo, seatStartNo, seatEndNo, hallId, seatLineNo,
             createdBy, createdDate, updatedBy, updatedDate) values('$examHallArrangedStructure->groupId', '$examHallArrangedStructure->examId', '$examHallArrangedStructure->columnNo', '$examHallArrangedStructure->seatStartNo', '$examHallArrangedStructure->seatEndNo', '$examHallArrangedStructure->hallId', '$examHallArrangedStructure->seatLineNo', $examHallArrangedStructure->createdBy, utc_timestamp(), $examHallArrangedStructure->updatedBy, utc_timestamp())";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get exam hall arranged structure of a specific column
     * @param int $hallId
     * @param int $groupId
     * @param int $columnNo
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamHallArrangedStructure($hallId, $groupId, $columnNo)
    {
        $examHallArrangedStructureList = NULL;
        $groupId = $this->realEscapeString($groupId);
        $hallId = $this->realEscapeString($hallId);
        $columnNo = $this->realEscapeString($columnNo);
        $sql = "select ehs.*, ex.* FROM examHallArrangedStructure ehs inner join exam ex on ehs.examId = ex.examID WHERE ehs.columnNo =$columnNo AND ehs.hallID=$hallId AND ehs.groupID=$groupId";
        try {
            $examHallArrangedStructureList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examHallArrangedStructureList;
    }
    /**
     * delete exam hall arranged structure of a specific column
     * @param int $hallId
     * @param int $groupId
     * @param int $columnNo
     * @throws ProfessionalException
     */
    public function deleteExamHallArrangedStructure($hallId, $groupId, $columnNo)
    {
        $groupId = $this->realEscapeString($groupId);
        $hallId = $this->realEscapeString($hallId);
        $columnNo = $this->realEscapeString($columnNo);
        $sql = "DELETE FROM examHallArrangedStructure WHERE columnNo =$columnNo AND hallID=$hallId AND groupID=$groupId";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getExamDetailsByExamType($batchID, $semID, $examTypeID)
    {
        $batchID = $this->realEscapeString($batchID);
        $semID = $this->realEscapeString($semID);
        $examTypeID = $this->realEscapeString($examTypeID);
        $sql = "select t1.examID, t1.examName, t1.examTotalMarks, t2.subjectName,t2.subjectID,t2.subjectDesc from exam t1, subjects t2 where t1.batchID=$batchID and t1.semID=$semID and t1.examTypeID=$examTypeID and t1.subjectID = t2.subjectID";
        try {
            $result = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * Get count of failed subjects of a student by grade
     * @param int $studentId
     * @param int $batchId
     * @param int $semId
     * @throws ProfessionalException
     */
    public function getFailedSubjectCountOfStudent($studentId, $batchId, $semId)
    {
        $typeId = 0;
        $typeId = $this->getFaildGradeId($batchId);
        if ($typeId) {
            $sql = "SELECT us.studentID, count(CASE WHEN us.gradeObtained IN ($typeId) THEN 1 END )AS count
            FROM university_studentgrade us INNER JOIN studentaccount st ON st.studentID = us.studentID WHERE st.batchID=$batchId AND us.semID=$semId and st.studentID = $studentId group by us.studentID";
            try {
                $failedSubjectCount = $this->executeQueryForObject($sql)->count;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        return $failedSubjectCount;
    }
    /**
     * Get count of failed subjects of a student by mark
     * @param int $batchId
     * @param int $semId
     * @param int $studentId
     * @throws ProfessionalException
     */
    public function getFailedStudentExamCount($batchId, $semId, $studentId)
    {
        $sql = "SELECT
                count(um.examID) as count
            FROM
                universityMarks um
                    INNER JOIN
                universityExams ue ON um.semID = ue.semID
                    AND um.examID = ue.examID
                    AND um.subjectID = ue.subjectID
                    INNER JOIN
                university_assignbatchcourse uab ON uab.batchID = ue.batchID
                    INNER JOIN
                university_coursetypegrading uct ON uct.typeID = uab.typeID
                    INNER JOIN
                mark_failed_criteria mfc ON mfc.typeID = uab.typeID
            WHERE
                uab.batchID = $batchId AND um.studentID = $studentId and um.semID=$semId and (um.percentage< external_percentage  or (um.percentage + um.internalPercentage) < total_percentage)";
        try {
            $failedExamCount = $this->executeQueryForObject($sql)->count;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $failedExamCount;
    }
    /**
     * get university mark defined semesters
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityMarksDefinedSem($batchId, $semID = null)
    {
        $entryType = $this->getExamEntryType($batchId);
        if ($entryType == "MARK") {
            $conditin = '';
            if ($semID) {
                $condition = "and sem.semID=$semID";
            }
            $sql = "select distinct(um.semID) as semID, semName  FROM universityMarks um INNER JOIN universityExams ue ON um.semID = ue.semID AND um.examID = ue.examID inner join semesters sem on sem.semID = ue.semID where ue.batchID=$batchId $condition order by um.semID ";
        } else {
            if ($semID) {
                $con = "and sem.semID=$semID";
            }
            $sql = "select distinct(ue.semID) as semID, semName from universityExams ue left join university_studentgrade us on ue.examID = us.examID left join semesters sem on sem.semID = ue.semID  where batchID = $batchId $con order by ue.semID";
        }
        try {
            $sem = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $sem;
    }
    /**
     * Get total marks percentage of a student for an exam
     * @param int $batchId
     * @param int $semId
     * @param int $studentId
     * @param int $examTypeId
     * @return number
     * @throws ProfessionalException
     */
    public function getTotalPercentage($batchId, $semId, $studentId, $examTypeId)
    {
        $sql = "select marksObtained,examTotalMarks from student_marks sm inner join exam ex on sm.examID=ex.examID where sm.semID=$semId and  sm.batchID=$batchId and studentID=$studentId and sm.examTypeID=$examTypeId";
        try {
            $marks = $this->executeQueryForList($sql);
            $totalMark = 0;
            $examTotalMarks = 0;
            foreach ($marks as $markObtained) {
                if ($markObtained->marksObtained > -1) {
                    $totalMark += $markObtained->marksObtained;
                }
                $examTotalMarks += $markObtained->examTotalMarks;
            }
            $percentage = round(($totalMark / $examTotalMarks) * 100, 2);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $percentage;
    }
    /**
     * Get university grade entered sem
     * @param int $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityGradeDefinedSem($studentId)
    {
        $sql = "SELECT distinct(semID) as semID FROM  university_studentgrade  where studentID = $studentId order by semID";
        try {
            $sem = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $sem;
    }
    /**
     * assign staff to exam hall
     * @param int $groupId
     * @param int $hallId
     * @param int $staffId
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function addStaffToExamHall($groupId, $hallId, $staffId)
    {
        $sql = "Insert into exam_hall_arranged_staffs(groupID, hallID, staffID) values(\"$groupId\", \"$hallId\", \"$staffId\")";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * update assigned staff exam hall
     * @param int $groupId
     * @param int $hallId
     * @param int $staffId
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function updateExamHallAssignedStaff($groupId, $hallId, $staffId)
    {
        $sql = "Update exam_hall_arranged_staffs set hallID =\"$hallId\" where staffID = \"$staffId\" and groupID=\"$groupId\"";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * delete or unassign staff from exam Hall
     * @param int $groupId
     * @param int $staffId
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function deleteExamHallAssignedStaff($groupId, $staffId)
    {
        $sql = "delete from exam_hall_arranged_staffs where staffID = \"$staffId\" and groupID=\"$groupId\"";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * check whether staff assigned to a hall or not
     * @param int $groupId
     * @param int $staffId
     * @return boolean
     * @throws ProfessionalException
     */
    public function checkExamHallAssigned($groupId, $staffId)
    {
        $flag = FALSE;
        $sql = "select hallID from exam_hall_arranged_staffs where groupID=$groupId AND staffID=$staffId";
        try {
            $hallId = $this->executeQueryForObject($sql)->hallID;
            if ($hallId) {
                $flag = TRUE;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $flag;
    }
    /**
     * get exam group assigned staff details
     * @param int $groupId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamGroupAssignedStaffs($groupId)
    {
        $assignedStaff = NULL;
        $sql = "SELECT t1.staffID,t2.staffName FROM exam_group_staffs t1, staffaccounts t2 WHERE t1.groupID = \"$groupId\" and t2.staffID = t1.staffID ORDER BY t2.staffName";
        try {
            $assignedStaff = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $assignedStaff;
    }
    /**
     * get unassigned staffs
     * @param int $groupId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamHallUnassignedStaffs($groupId)
    {
        $unassignedStaff = NULL;
        $sql = "SELECT egs.staffID, sa.staffName FROM exam_group_staffs egs INNER JOIN staffaccounts sa ON sa.staffID=egs.staffID LEFT JOIN exam_hall_arranged_staffs eas ON eas.staffID=egs.staffID AND eas.groupID=egs.groupID WHERE egs.groupID=$groupId AND eas.staffID is null ORDER BY sa.staffName";
        try {
            $unassignedStaff = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $unassignedStaff;
    }
    /**
     * get count of assigned staffs in a hall
     * @param int $groupId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getCountOfExamHallAssignedStaffs($groupId)
    {
        $hallAssignedCount = NULL;
        $sql = "select hallID,count(hallID) as count from exam_hall_arranged_staffs where groupID=$groupId group by hallID";
        try {
            $hallAssignedCount = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $hallAssignedCount;
    }
    /**
     * get exam hall seating allotment
     * @param int $groupId
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getExamHallSeatingAllotment($groupId)
    {
        $seatingAllotment = [];
        $sql = "select dept.deptID, dept.deptName, bth.batchID, bth.batchName,min(sa.rollNo) as rollNoMin,max(sa.rollNo) as rollNoMax, min(sa.regNo) as regNoMin ,max(sa.regNo) as regNoMax,sub.subjectName, count(ehas.studentID) as totalStudent, eh.hallID, eh.hallName  from exam_hall_arranged_students ehas INNER JOIN studentaccount sa ON sa.studentID=ehas.studentID INNER JOIN batches bth ON bth.batchID=sa.batchID INNER JOIN department dept ON dept.deptID=bth.deptID INNER JOIN exam ex ON ex.examID=ehas.examID INNER JOIN subjects sub ON sub.subjectID=ex.subjectID INNER JOIN exam_halls eh ON eh.hallID=ehas.hallID WHERE ehas.groupID=$groupId group by ex.examID,eh.hallID order by dept.deptName, bth.batchName, ex.examID, rollNoMin";
        $seatingAllotment = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_SEATING_ALLOTMENT]);
        return $seatingAllotment;
    }
    /**
     * get exam date and time by exam group
     * @param int $groupId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamTimeAndDateByGroup($groupId)
    {
        $dateTime = NULL;
        $sql = "select distinct examDate, examStartTime, examEndTime, t1.examTypeId from exam t1, exam_group_exams t2 where t1.examID = t2.examID and t2.groupID=$groupId";
        try {
            $dateTime = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $dateTime;
    }
    /**
     * Get examTypes defined for a subject
     * @param int $batchId
     * @param int $semId
     * @param int $subjectId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamTypeBySubject($batchId, $semId, $subjectId)
    {
        $sql = "select exty.typeID,exty.typeName,ex.examTotalMarks,exty.isInternal,exty.parent_exam_typeID from exam ex INNER JOIN exam_type exty ON ex.examTypeID = exty.typeID  where semID = $semId and batchID = $batchId and subjectID = $subjectId AND exty.canShow=1 group by exty.typeID";
        try {
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTypes;
    }
    /**
     * Get number of students failed including absentees
     * @param int $semId
     * @param int $examId
     * @param int $examTypeId
     * @param int $batchId
     * @param int $passPercent
     * @return number
     * @throws ProfessionalException
     */
    public function getFailedStudentCountIncludeAbsentees($semId, $examId, $examTypeId, $batchId, $passPercent)
    {
        $semId = $this->realEscapeString($semId);
        $examId = $this->realEscapeString($examId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $batchId = $this->realEscapeString($batchId);
        $passPercent = $this->realEscapeString($passPercent);
        $sql = "SELECT count(distinct(t2.studentID)) as count FROM student_marks t1, studentaccount t2 WHERE t1.semID= $semId AND t1.examID= $examId AND t1.examTypeID=$examTypeId AND t1.percentage < $passPercent AND(  t1.marksObtained!=-1 or t1.marksObtained!=0) AND t2.studentID=t1.studentID AND t2.batchID= $batchId";
        try {
            $studentsFailedCount = $this->executeQueryForObject($sql)->count;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentsFailedCount;
    }
    /**
     * Get count of students appeared for the exam including absentees
     * @param int $semId
     * @param int $examId
     * @param int $examTypeId
     * @param int $batchId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentsAppearedCountIncludeAbsentee($semId, $examId, $examTypeId, $batchId)
    {
        $semId = $this->realEscapeString($semId);
        $examId = $this->realEscapeString($examId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT COUNT(distinct(t2.studentID)) as count FROM student_marks t1, studentaccount t2 WHERE t1.examID=$examId AND t1.examTypeID=$examTypeId  AND t2.studentID=t1.studentID AND t1.semID=$semId AND t2.batchID=t1.batchID AND t2.batchID=$batchId";
        try {
            $studentsAppearedCount = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentsAppearedCount;
    }
    /**
     * Get university exam
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityExamGrade($batchId, $semId)
    {
        $semId = $this->realEscapeString($semId);
        $batchId = $this->realEscapeString($batchId);
        try {
            $sortByColumn = BatchService::getInstance()->getStudentSortByColumnOfABatch($batchId);
            if(empty(trim($sortByColumn))){
                $sortByColumn == 'regNo';
            }
        } catch (\Throwable $th) {
            $sortByColumn == 'regNo';
        }
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($batchId, $semId);
        if ($isCurrentSem) {
            $sql = "SELECT sa.studentID, sa.studentName, sa.regNo,sub.subjectID, sub.subjectName, sub.subjectDesc, gradeObtained, noOfChances, passType, ug.letterGrade, uec.credit, ue.examID FROM studentaccount sa inner join  batches bat on sa.batchID = bat.batchID inner join semesters sem on sem.semID = bat.semID inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID inner join universityExams ue on bat.batchID = ue.batchID LEFT JOIN subjects sub on ue.subjectID = sub.subjectID  LEFT JOIN university_examcredits uec ON uec.subjectID = sub.subjectID and uec.batchID = ue.batchID and ue.semID = uec.semID left join university_studentgrade us on ue.examID = us.examID and sa.studentID = us.studentID left join university_gradepoints ug on ug.gradeID = us.gradeObtained where joinedSem.orderNo <= sem.orderNo and ue.batchID = $batchId and ue.semID = $semId  ORDER BY sa.$sortByColumn ASC,examID ASC ";
        } else {
            $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
            $sql = "SELECT  sa.studentID, sa.studentName, sa.regNo,sub.subjectID, sub.subjectName, sub.subjectDesc, gradeObtained, noOfChances, passType, ug.letterGrade, uec.credit, ue.examID from studentaccount sa  inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID INNER JOIN universityExams ue ON ue.batchID = sa.batchID LEFT JOIN subjects sub on ue.subjectID = sub.subjectID  LEFT JOIN university_examcredits uec ON uec.subjectID = sub.subjectID and uec.batchID = ue.batchID and ue.semID = uec.semID left join university_studentgrade us on ue.examID = us.examID and sa.studentID = us.studentID left join university_gradepoints ug on ug.gradeID = us.gradeObtained where ue.batchID = " . $batchId . " and ue.semID = " . $semId . "  and joinedSem.orderNo <= " . $semDetails->orderNo . " union ( select  sa.studentID, sa.studentName, sa.regNo,sub.subjectID, sub.subjectName, sub.subjectDesc, gradeObtained, noOfChances, passType, ug.letterGrade, uec.credit, ue.examID from  failed_students fs inner join studentaccount sa on sa.studentID = fs.studentID inner join semesters sem on sem.semID = sa.joiningSemId left join semesters fsem on fsem.semID = fs.failedInSemester INNER JOIN universityExams ue ON ue.batchID = fs.previousBatch LEFT JOIN subjects sub on ue.subjectID = sub.subjectID  LEFT JOIN university_examcredits uec ON uec.subjectID = sub.subjectID and uec.batchID = ue.batchID and ue.semID = uec.semID left join university_studentgrade us on ue.examID = us.examID and sa.studentID = us.studentID left join university_gradepoints ug on ug.gradeID = us.gradeObtained where ue.batchID = " . $batchId . " and ue.semID = " . $semId . " and fsem.orderNo > " . $semDetails->orderNo . " and sem.orderNo <= " . $semDetails->orderNo . " ORDER BY sa.$sortByColumn ASC,examID ASC);";
        }
        try {
            $studentUniversityDetails = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_UNIVERSITY_STUDENT_GRADE]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentUniversityDetails;
    }
    /**
     * Get university exam grades
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityExamGrades($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = "select letterGrade as grade, gradeID, ug.percentFrom, ug.percentTo, performance from university_assignbatchcourse ua  inner join university_gradepoints ug on ua.typeID = ug.typeID where batchID = $batchId order by percentTO desc";
        try {
            $grades = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $grades;
    }
    /**
     * get student university exam details by examId
     * @param int $examId
     * @param int $studentId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentUniversityExamDetailsByExamId($examId, $studentId)
    {
        $examId = $this->realEscapeString($examId);
        $studentId = $this->realEscapeString($studentId);
        $sql = "select gradeObtained,noOfChances,passType, letterGrade, percentFrom, percentTo, gradePoint, performance from university_studentgrade us inner join university_gradepoints ug on ug.gradeID = us.gradeObtained where studentID = $studentId and examID = $examId";
        try {
            $examDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examDetails;
    }
    /**
     * Filter students by name or credit
     * @param string $semIds
     * @param int $batchId
     * @param string $studentName
     * @param int $frm_credit
     * @param int $to_credit
     */
    public function getStudentsInCreditRange($YearOutRequest)
    {
        $studentDetails = new GetYearOutStudentResponse();
        $semIds = $this->realEscapeString($YearOutRequest->semIds);
        $batchId = $this->realEscapeString($YearOutRequest->batchId);
        $studentName = $this->realEscapeString($YearOutRequest->studentName);
        $frm_credit = $this->realEscapeString($YearOutRequest->frm_credit);
        $to_credit = $this->realEscapeString($YearOutRequest->to_credit);
        $regNo = $this->realEscapeString($YearOutRequest->regNo);
        $startIndex = $this->realEscapeString($YearOutRequest->startIndex);
        $endIndex = $this->realEscapeString($YearOutRequest->endIndex);
        $failedGrade = $this->getFaildGradeId($batchId);
        $sql_credit = "";
        $sql_student = "";
        $sql_limit = "";
        $sql_regNo = "";
        if ($studentName) {
            $sql_student = " and studentName like ('" . $studentName . "%')";
        }
        if ($regNo) {
            $sql_regNo = " and regNo like ('" . $regNo . "%') ";
        }
        if ($to_credit) {
            $sql_credit = " and sum(credit) < $to_credit";
        }
        if ($endIndex) {
            $sql_limit = " limit $startIndex,$endIndex";
        }
        $sql_count = "select count(studentID) as count from (SELECT us.studentID FROM university_studentgrade us left join studentaccount sa on us.studentID = sa.studentID INNER JOIN university_gradepoints ug ON us.gradeObtained = ug.gradeID INNER JOIN university_examcredits ue ON ue.subjectID = us.subjectID and ue.semID = us.semID WHERE ue.semID IN ($semIds) and ue.batchID = $batchId AND gradeID NOT IN ($failedGrade$sql_student $sql_regNo GROUP BY us.studentID having (SUM(credit) > $frm_credit $sql_credit)) as searchResult";
        $sql = "SELECT SUM(credit) as total_credit,sa.studentName, sa.regNo FROM university_studentgrade us left join studentaccount sa on us.studentID = sa.studentID INNER JOIN university_gradepoints ug ON us.gradeObtained = ug.gradeID INNER JOIN university_examcredits ue ON ue.subjectID = us.subjectID and ue.semID = us.semID WHERE ue.semID IN ($semIds) and ue.batchID = $batchId AND gradeID NOT IN ($failedGrade$sql_student $sql_regNo GROUP BY us.studentID having (SUM(credit) > $frm_credit $sql_credit$sql_limit";
        try {
            $studentDetails->students = $this->executeQueryForList($sql);
            $totalRecords = $this->executeQueryForObject($sql_count)->count;
            $studentDetails->totalRecords = $totalRecords;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentDetails;
    }
    /**
     * get student exam details
     * @param int $studentId
     * @param int $semId
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentExamMarks($studentId, $semId, $batchId)
    {
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $batchId = $this->realEscapeString($batchId);
        $studentExamMarks = [];
        $sql = "SELECT studentID, studentName, batchName, semName, examTypeID, typeName, examID, examName, examTotalMarks, if(marksObtained=-1,'A',if(marksObtained<0,'MAL',marksObtained)) as marksObtained , totalMarksObtained, totalMaxMark, (totalMarksObtained/totalMaxMark)*100 as totalPercentage, weightedPercentage, subjectName, subjectCode, subjectID FROM ( SELECT
                sa.studentID,
                sa.studentName,
                bth.batchName,
                sem.semName,
                exm.examTypeID,
                exm.examID,
                exm.examName,
                exm.examTotalMarks,
                stm.marksObtained,
                stm.percentage,
                et.typeName,
                      (SELECT sum(percentage)/count(ex.examID) FROM exam ex INNER JOIN exam_type et ON
                        ex.examTypeID = et.typeID
                        LEFT JOIN student_marks sm ON sm.examID = ex.examID AND et.typeID = sm.examTypeID
                        AND ex.batchID = sm.batchID AND ex.semID = sm.semID
                             WHERE ex.examTypeID = exm.examTypeID and ex.batchID = $batchId
                            AND ex.semID = $semId
                            AND sm.studentID = $studentId ) as weightedPercentage,
                (SELECT
                        SUM(IF(sm.marksObtained < 0,
                                0,
                                sm.marksObtained))
                    FROM
                        student_marks sm INNER JOIN exam ex ON ex.examID=sm.examID
                    WHERE
                        ex.examTypeID = exm.examTypeID
                            AND ex.batchID = $batchId
                            AND ex.semID = $semId
                            AND sm.studentID = $studentId) AS totalMarksObtained,
                (SELECT
                        SUM(ex.examTotalMarks)
                    FROM
                        exam ex INNER JOIN student_marks sm ON sm.examTypeID=ex.examTypeID AND sm.examID=ex.examID
                    WHERE
                            ex.batchID = $batchId
                            AND ex.semID = $semId
                            AND sm.studentID = $studentId
                            AND ex.examTypeID=exm.examTypeID) AS totalMaxMark,
                (SELECT
                        SUM(examTotalMarks)
                    FROM
                        exam
                    WHERE
                        examTypeID = exm.examTypeID
                            AND batchID = $batchId
                            AND semID = $semId) AS weightedMaxMark,
            sub.subjectName as subjectCode, sub.subjectDesc as subjectName, sub.subjectID
            FROM
                exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID INNER JOIN studentaccount sa ON sa.batchID=exm.batchID AND sa.studentID=$studentId INNER JOIN batches bth ON bth.batchID=exm.batchID INNER JOIN semesters sem ON sem.semID=exm.semID
                    LEFT JOIN
                student_marks stm ON stm.examID = exm.examID
                    AND stm.examTypeID = exm.examTypeID left join subjects sub on sub.subjectID = exm.subjectID
            WHERE
                exm.batchID = $batchId AND exm.semID = $semId
                    AND stm.studentID = $studentId
            ORDER BY stm.examTypeID , stm.examID) as studentMarks";
        try {
            $studentExamMarks = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_STUDENT_EXAM_DETAILS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentExamMarks;
    }
    /**
     * Get count of students failed by examtype
     * @param int $batchId
     * @param int $semId
     * @param int $passPercent
     * @param int $examTypeId
     * @param number $isHosteler
     * @param string $gender
     * @return int
     * @throws ProfessionalException
     */
    public function getStudentsFailedCountByExamTypeId($batchId, $semId, $passPercent, $examTypeId, $isHosteler = null, $gender = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $passPercent = $this->realEscapeString($passPercent);
        $isHosteler = $this->realEscapeString($isHosteler);
        $gender = $this->realEscapeString($gender);
        $sql_hosteler = "";
        $sql_gender = "";
        $sql_hosteler_cond = "";
        if ($isHosteler != null) {
            $sql_hosteler = " left join student_hosteler sh on sa.studentID = sh.studentID";
            $sql_hosteler_cond = $isHosteler == 0 ? " and sh.studentID is null" : "  and sh.studentID is not null";
        }
        if ($gender != null) {
            $sql_gender = " and studentGender='" . $gender . "'";
        }
//         $sql = "select count(studentID) as count from (select count(sa.studentID) as studentID from studentaccount sa inner join student_marks sm on sa.studentID = sm.studentID and sa.batchID = sm.batchID $sql_hosteler where  semID = $semId AND sm.batchID = $batchId  AND examTypeID = $examTypeId AND percentage < $passPercent and marksObtained!= -1 $sql_gender $sql_hosteler_cond  group by  sa.studentID) as count";
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($batchId, $semId);
        $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
        if ($isCurrentSem) {
            $sql = "select count(studentID) as count from (select COUNT(distinct(sa.studentID)) as studentID from student_marks sm inner join studentaccount sa on sm.studentID = sa.studentID and sm.batchID = sa.batchID inner join semesters sem on sem.semID = sa.joiningSemId " . $sql_hosteler . " where sm.batchID = " . $batchId . " and sm.semID = " . $semId . " and sm.examTypeID = " . $examTypeId . " and sm.marksObtained != -1 and sem.orderNo <= " . $semDetails->orderNo . " AND sm.percentage < " . $passPercent . " $sql_gender $sql_hosteler_cond  group by  sa.studentID) as count ";
        } else {
            $sql = "select COUNT(distinct(studentID)) as count from (select sm.studentID from student_marks sm inner join studentaccount sa on sm.studentID = sa.studentID and sm.batchID = sa.batchID inner join semesters sem on sem.semID = sa.joiningSemId " . $sql_hosteler . " where sm.batchID = " . $batchId . " and sm.semID = " . $semId . " and sm.examTypeID = " . $examTypeId . " and sm.marksObtained != -1 and sem.orderNo <= " . $semDetails->orderNo . " AND sm.percentage < " . $passPercent . " $sql_gender $sql_hosteler_cond  group by  sa.studentID union select sm.studentID from student_marks sm inner join  studentaccount sa on sa.studentID = sm.studentID inner join failed_students fs on sa.studentID = fs.studentID and fs.previousBatch = sm.batchID inner join semesters sem on sem.semID = sa.joiningSemId inner join semesters fsem on fsem.semID = fs.failedInSemester " . $sql_hosteler . " where sm.batchID = " . $batchId . " and sm.semID = " . $semId . " and sm.examTypeID = " . $examTypeId . " and sm.marksObtained != -1 and sem.orderNo <= " . $semDetails->orderNo . " and fsem.orderNo > " . $semDetails->orderNo . " AND sm.percentage < " . $passPercent . " $sql_gender $sql_hosteler_cond  group by  sa.studentID) as count;";
        }
        try {
            $count = $this->executeQueryForObject($sql)->count;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $count;
    }
    /**
     *
     * @param int $batchId
     * @param int $semId
     * @param int $passPercent
     * @param int $examTypeId
     * @param number $isHosteler
     * @param string $gender
     * @return int
     * @throws ProfessionalException
     */
    public function getStudentsFailedCountIncludeAbsenteesByExamType($batchId, $semId, $passPercent, $examTypeId, $isHosteler = null, $gender = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $passPercent = $this->realEscapeString($passPercent);
        $examTypeId = $this->realEscapeString($examTypeId);
        $isHosteler = $this->realEscapeString($isHosteler);
        $gender = $this->realEscapeString($gender);
        $sql_hosteler = "";
        $sql_gender = "";
        $sql_hosteler_cond = "";
        if ($isHosteler != null) {
            $sql_hosteler = " left join student_hosteler sh on sa.studentID = sh.studentID";
            $sql_hosteler_cond = $isHosteler == 0 ? " and sh.studentID is null" : "  and sh.studentID is not null";
        }
        if ($gender != null) {
            $sql_gender = " and studentGender='" . $gender . "'";
        }
        $sql = "select count(studentID) as count from (select count(sa.studentID) as studentID from studentaccount sa inner join student_marks sm on sa.studentID = sm.studentID and sa.batchID = sm.batchID $sql_hosteler where  semID = $semId AND sm.batchID = $batchId  AND examTypeID = $examTypeId AND percentage < $passPercent and (marksObtained!= -1 or  marksObtained!=0) $sql_gender $sql_hosteler_cond  group by  sa.studentID) as count";
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($batchId, $semId);
        $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
        if ($isCurrentSem) {
            $sql = "select count(studentID) as count from (select COUNT(distinct(sa.studentID)) as studentID from student_marks sm inner join studentaccount sa on sm.studentID = sa.studentID and sm.batchID = sa.batchID inner join semesters sem on sem.semID = sa.joiningSemId " . $sql_hosteler . " where sm.batchID = " . $batchId . " and sm.examTypeID = " . $examTypeId . " and (marksObtained!= -1 or  marksObtained!=0) and sm.semID = " . $semId . " and sem.orderNo <= " . $semDetails->orderNo . " AND sm.percentage < " . $passPercent . " $sql_gender $sql_hosteler_cond  group by  sa.studentID) as count ";
        } else {
            $sql = "select COUNT(distinct(studentID)) as count from (select sm.studentID from student_marks sm inner join studentaccount sa on sm.studentID = sa.studentID and sm.batchID = sa.batchID inner join semesters sem on sem.semID = sa.joiningSemId " . $sql_hosteler . " where sm.batchID = " . $batchId . " and sm.examTypeID = " . $examTypeId . " and (marksObtained!= -1 or  marksObtained!=0) and sm.semID = " . $semId . " and sem.orderNo <= " . $semDetails->orderNo . " AND sm.percentage < " . $passPercent . " $sql_gender $sql_hosteler_cond  group by  sa.studentID union select sm.studentID from student_marks sm inner join  studentaccount sa on sa.studentID = sm.studentID inner join failed_students fs on sa.studentID = fs.studentID and fs.previousBatch = sm.batchID inner join semesters sem on sem.semID = sa.joiningSemId inner join semesters fsem on fsem.semID = fs.failedInSemester " . $sql_hosteler . " where sm.batchID = " . $batchId . " and sm.examTypeID = " . $examTypeId . " and (marksObtained!= -1 or  marksObtained!=0) and sm.semID = " . $semId . " and sem.orderNo <= " . $semDetails->orderNo . " and fsem.orderNo > " . $semDetails->orderNo . " AND sm.percentage < " . $passPercent . " $sql_gender $sql_hosteler_cond  group by  sa.studentID) as count;";
        }
        try {
            $count = $this->executeQueryForObject($sql)->count;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $count;
    }
    /**
     * get student exam details
     * @param int $studentId
     * @param int $semId
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentExamMarksBySubjectId($subjectId, $batchId, $subbatchId, $semId, $sortBy = 'rollNo')
    {
        $subjectId = $this->realEscapeString($subjectId);
        $batchId = $this->realEscapeString($batchId);
        $subbatchId = $this->realEscapeString($subbatchId);
        $semId = $this->realEscapeString($semId);
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($batchId, $semId);
        $studentExamMarks = [];
        if ($isCurrentSem) {
            if ($subbatchId) {
                $sql = "SELECT
                sa.studentID,
                sa.studentName,
                sa.rollNo,
                sa.regNo,
                bth.batchName,
                sem.semName,
                exm.examTypeID,
                exm.examID,
                exm.examName,
                exm.examTotalMarks,
                if(stm.marksObtained=-1,'A',if(stm.marksObtained<0,'MAL',stm.marksObtained)) as marksObtained,
                stm.percentage,
                et.typeName
                FROM
                exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID AND et.canShow=1 INNER JOIN batches bth ON bth.batchID=exm.batchID INNER JOIN studentaccount sa ON sa.batchID=exm.batchID INNER JOIN subbatch_student subs ON subs.studentID=sa.studentID AND subs.subbatchID=$subbatchId INNER JOIN semesters sem ON sem.semID=exm.semID inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID
                    LEFT JOIN
                student_marks stm ON stm.examID = exm.examID
                    AND stm.examTypeID = exm.examTypeID AND stm.studentID=sa.studentID
            WHERE
                exm.batchID = $batchId
                    AND exm.subjectID = $subjectId AND exm.semID = $semId AND exm.subbatchID = $subbatchId and joinedSem.orderNo <= sem.orderNo ORDER BY exm.examTypeID , exm.examID, sa." . $sortBy . "";
            } else {
                $sql = " SELECT
                sa.studentID,
                sa.studentName,
                sa.rollNo,
                sa.regNo,
                bth.batchName,
                sem.semName,
                exm.examTypeID,
                exm.examID,
                exm.examName,
                exm.examTotalMarks,
                if(stm.marksObtained=-1,'A',if(stm.marksObtained<0,'MAL',stm.marksObtained)) as marksObtained,
                stm.percentage,
                et.typeName
                FROM
                exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID AND et.canShow=1 INNER JOIN batches bth ON bth.batchID=exm.batchID INNER JOIN studentaccount sa ON sa.batchID=exm.batchID INNER JOIN semesters sem ON sem.semID=exm.semID inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID
                    LEFT JOIN
                student_marks stm ON stm.examID = exm.examID
                    AND stm.examTypeID = exm.examTypeID AND stm.studentID=sa.studentID
            WHERE
                exm.batchID = $batchId
                    AND exm.subjectID = $subjectId AND exm.semID = $semId AND exm.subbatchID = $subbatchId  and joinedSem.orderNo <= sem.orderNo
            ORDER BY exm.examTypeID , exm.examID, sa." . $sortBy . "";
            }
        } else {
            $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
            if ($subbatchId) {
                $sql = "SELECT
                sa.studentID,
                sa.studentName,
                sa.rollNo,
                sa.regNo,
                bth.batchName,
                sem.semName,
                exm.examTypeID,
                exm.examID,
                exm.examName,
                exm.examTotalMarks,
                if(stm.marksObtained=-1,'A',if(stm.marksObtained<0,'MAL',stm.marksObtained)) as marksObtained,
                stm.percentage,
                et.typeName
                FROM
                    studentaccount sa
                        LEFT JOIN
                    failed_students fs ON sa.studentID = fs.studentID and fs.reason <> 'BATCH_SHUFFLE'
                    left join semesters fsem on fsem.semID = fs.failedInSemester inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID
                        INNER JOIN
                    subbatch_student subs ON subs.studentID=sa.studentID
                        INNER JOIN
                    exam exm ON (exm.batchID = sa.batchID or exm.batchID = fs.previousBatch)
                        INNER JOIN
                    exam_type et ON et.typeID = exm.examTypeID AND et.canShow=1
                        INNER JOIN
                        batches bth on exm.batchID = bth.batchID
                        INNER JOIN
                        semesters sem on  sem.semID = exm.semID
                        LEFT JOIN
                    student_marks stm ON stm.studentID = sa.studentID
                        AND exm.examID = stm.examID and stm.examTypeID = exm.examTypeID
                WHERE
                    exm.batchID = $batchId
                        AND (fsem.orderNo > $semDetails->orderNo
                        OR fsem.orderNo IS NULL) and joinedSem.orderNo <= $semDetails->orderNo
                        AND  exm.subjectID = $subjectId AND exm.semID = $semId AND exm.subbatchID = $subbatchId
                            ORDER BY exm.examTypeID , exm.examID, sa." . $sortBy . "";
            } else {
                $sql = "SELECT
                sa.studentID,
                sa.studentName,
                sa.rollNo,
                sa.regNo,
                bth.batchName,
                sem.semName,
                exm.examTypeID,
                exm.examID,
                exm.examName,
                exm.examTotalMarks,
                if(stm.marksObtained=-1,'A',if(stm.marksObtained<0,'MAL',stm.marksObtained)) as marksObtained,
                stm.percentage,
                et.typeName
                FROM
                    studentaccount sa
                        LEFT JOIN
                    failed_students fs ON sa.studentID = fs.studentID and fs.reason <> 'BATCH_SHUFFLE'
                    left join semesters fsem on fsem.semID = fs.failedInSemester inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID
                        INNER JOIN
                    exam exm ON (exm.batchID = sa.batchID or exm.batchID = fs.previousBatch)
                        INNER JOIN
                    exam_type et ON et.typeID = exm.examTypeID AND et.canShow=1
                        INNER JOIN
                        batches bth on exm.batchID = bth.batchID
                        INNER JOIN
                        semesters sem on  sem.semID = exm.semID
                        LEFT JOIN
                    student_marks stm ON stm.studentID = sa.studentID
                        AND exm.examID = stm.examID and stm.examTypeID = exm.examTypeID
                WHERE
                    exm.batchID = $batchId
                        AND (fsem.orderNo > $semDetails->orderNo
                        OR fsem.orderNo IS NULL) and joinedSem.orderNo <= $semDetails->orderNo
                        AND  exm.subjectID = $subjectId AND exm.semID = $semId AND exm.subbatchID = $subbatchId
                            ORDER BY exm.examTypeID , exm.examID, sa." . $sortBy . "";
            }
        }
        try {
            $studentExamMarks = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_STUDENT_EXAM_DETAILS_BY_SUBJECT]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentExamMarks;
    }
    /**
     * Get exam type details by subjectId
     * @param int $subjectId
     * @param int $batchId
     * @param int $subbatchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamTypeDetailsBySubjectId($subjectId, $batchId, $subbatchId = 0,$semId = NULL)
    {
        $subjectId = $this->realEscapeString($subjectId);
        $batchId = $this->realEscapeString($batchId);
        $subbatchId = $this->realEscapeString($subbatchId);
        $semId = $this->realEscapeString($semId);
        $examTypeList = [];
        $semCond = !empty($semId)? " AND t1.semID = $semId " : "";
        $sql = "SELECT t2.typeID, t2.typeName, t1.semID, t1.examTotalMarks from exam t1, exam_type t2 WHERE t1.subjectID=$subjectId AND t1.batchID=$batchId AND t1.examTypeID=t2.typeID  AND t1.subbatchID=$subbatchId AND t2.canShow=1 $semCond";
        $sql .= " ORDER BY t1.examTypeID , t1.examID";
        try {
            $examTypeList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examTypeList;
    }
    /**
     * get university exam backlog count by year
     * @param int $batchId
     * @param int $courseTypeId
     * @param string $years
     * @param int $backlogs
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityExamBacklogCountByYear($batchId, $courseTypeId, $years = null, $backlogs = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $years = $this->realEscapeString($years);
        $backlogs = $this->realEscapeString($backlogs);
        $sql_backlog = "";
        $sql_years = "";
        if ($backlogs != null) {
            $sql_backlog = " HAVING (backpapers = $backlogs)";
        } else {
            $sql_backlog = " HAVING (backpapers > 0)";
        }
        if ($years != null) {
            $sql_years = " AND year IN ($years)";
        }
        $sql = "SELECT sa.studentID, sa.regNo,sa.studentName ,year, SUM(CASE WHEN (us.gradeObtained IN (SELECT gradeID FROM university_gradepoints WHERE gradePoint = 0 AND typeID = $courseTypeId)) THEN 1 ELSE 0 END) AS backpapers FROM studentaccount sa LEFT JOIN department dep ON sa.deptID = dep.deptID LEFT JOIN batches bat ON sa.batchID = bat.batchID LEFT JOIN university_studentgrade us ON us.studentID = sa.studentID AND gradeObtained != 0 LEFT JOIN semesters sem ON us.semID = sem.semID INNER JOIN university_gradepoints ugp ON us.gradeObtained = ugp.gradeID LEFT JOIN university_examcredits ue ON ue.subjectID = us.subjectID  AND sa.batchID = ue.batchID WHERE sa.batchID = $batchId $sql_years GROUP BY sa.studentID $sql_backlog";
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentDetails;
    }
    /**
     * get university coursetype by batchId
     * @param int $batchId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityBatchCourseType($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = "select typeID from university_assignbatchcourse where batchID = $batchId";
        try {
            $courseType = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $courseType;
    }
    /**
     * Get university exam backlog count by studentIds
     * @param string $studentIds
     * @param int $batchId
     * @param int $courseTypeId
     * @param string $years
     */
    public function getUniversityExamBacklogCountDetailsByStudentIds($studentIds, $batchId, $courseTypeId, $years)
    {
        $studentIds = $this->realEscapeString($studentIds);
        $batchId = $this->realEscapeString($batchId);
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $years = $this->realEscapeString($years);
        $sql = "select sa.studentID,sa.studentName,regNo,s.semID,year, SUM(CASE WHEN (us.gradeObtained IN (SELECT gradeID FROM university_gradepoints WHERE gradePoint = 0 AND typeID = $courseTypeId)) THEN 1 ELSE 0 END) AS backlog  from studentaccount sa inner join batches ba on ba.batchID = sa.batchID left join semesters s on (s.semID = ba.semID or year <= (select year from batches b inner join semesters s on b.semID = s.semID where b.batchID = $batchId )) left join university_studentgrade us on sa.studentID = us.studentID and s.semID = us.semID AND gradeObtained != 0 where ba.batchID = $batchId AND year IN ($years) and sa.studentID in ($studentIds) GROUP BY sa.studentID,s.year";
        try {
            $studentDetails = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_STUDENT_UNIVERSITY_EXAM_YEARWISE]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentDetails;
    }
    /**
     * get exam types defined for a batch
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamTypesByBatch($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "select distinct(examTypeID), typeName from exam ex inner join exam_type ext on  ex.examTypeID = ext.typeID where batchID = $batchId and semID = $semId";
        try {
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examTypes;
    }
    /**
     * Get examId by subjectId
     * @param int $subjectId
     * @param int $batchId
     * @param int $semId
     * @param int $examTypeId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamIdBySubjectId($subjectId, $batchId, $semId, $examTypeId, $subbatchId = NULL)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $subbatchId = $this->realEscapeString($subbatchId);
        $whereCondition = "";
        if ($subbatchId) {
            $whereCondition .= "AND subbatchID IN ( $subbatchId )";
        }
        $sql = "SELECT examID, examTotalMarks FROM exam WHERE subjectID = $subjectId AND batchID = $batchId AND semID = $semId and examTypeID = $examTypeId $whereCondition";
        try {
            $examId = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examId;
    }
    /**
     * Get university exam by subjectId
     * @param int $batchId
     * @param int $semId
     * @param int $subjectId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getUniversityExamBySubjectId($batchId, $semId, $subjectId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "select ue.examID, ue.examName, ue.examTotalMarks, sub.subjectID, sub.subjectName as subjectCode, sub.subjectDesc as subjectName FROM subjects sub INNER JOIN universityExams ue ON sub.subjectID=ue.subjectID WHERE ue.batchID=$batchId and ue.subjectID = $subjectId and ue.semID = $semId";
        try {
            $examDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examDetails;
    }
    /**
     * Get  the gradeID by letter grade
     * @param int $batchId
     * @param string $letterGrade
     * @throws ProfessionalException
     */
    public function getUniversityGradeId($batchId, $letterGrade)
    {
        $batchId = $this->realEscapeString($batchId);
        $letterGrade = $this->realEscapeString($letterGrade);
        $sql = "select gradeID, ug.gradePoint from university_gradepoints ug inner join university_assignbatchcourse ua on  ua.typeID= ug.typeID where batchID = $batchId and letterGrade = \"$letterGrade\"";
        try {
            $gradeId = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $gradeId;
    }
    /**
     * add slow learner identification
     * @param SlowLearnerIdentification $slowLearnerIdentification
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function addSlowLearnerIdentification($slowLearnerIdentification)
    {
        $slowLearnerIdentification = $this->realEscapeObject($slowLearnerIdentification);
        $sql = "INSERT INTO slowLearnerIdentification (examId, percentage, weakStudentIds, attendedStudentsIds, remedialMeasure, remedialActionEffectivenes, createdBy, createdDate, updatedBy, updatedDate) VALUES ('$slowLearnerIdentification->examId', $slowLearnerIdentification->percentage, '$slowLearnerIdentification->weakStudentIds', '$slowLearnerIdentification->attendedStudentsIds', '$slowLearnerIdentification->remedialMeasure', '$slowLearnerIdentification->remedialActionEffectivenes', $slowLearnerIdentification->createdBy, utc_timestamp(), $slowLearnerIdentification->updatedBy, utc_timestamp())";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * update slow learner identification
     * @param SlowLearnerIdentification $slowLearnerIdentification
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function updateSlowLearnerIdentification($slowLearnerIdentification)
    {
        $slowLearnerIdentification = $this->realEscapeObject($slowLearnerIdentification);
        $sql = "UPDATE slowLearnerIdentification SET percentage=$slowLearnerIdentification->percentage, weakStudentIds='$slowLearnerIdentification->weakStudentIds', attendedStudentsIds='$slowLearnerIdentification->attendedStudentsIds', remedialMeasure='$slowLearnerIdentification->remedialMeasure', remedialActionEffectivenes='$slowLearnerIdentification->remedialActionEffectivenes', updatedBy=$slowLearnerIdentification->updatedBy, updatedDate=utc_timestamp() WHERE examId=$slowLearnerIdentification->examId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get slow learner identification
     * @param int $examTypeId
     * @param in $batchId
     * @param int $subjectId
     * @param float $percenatge
     * @param int $semId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSlowLearnerIdentification($examTypeId, $subjectId, $percentage, $semId, $batchId)
    {
        $examTypeId = $this->realEscapeString($examTypeId);
        $subjectId = $this->realEscapeString($subjectId);
        $percentage = $this->realEscapeString($percentage);
        $semId = $this->realEscapeString($semId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT sld.*, sub.subjectID, exm.examId, exm.examTypeID FROM slowLearnerIdentification sld INNER JOIN exam exm ON exm.examID=sld.examId INNER JOIN subjects sub ON sub.subjectID=exm.subjectID WHERE exm.examTypeID=$examTypeId AND exm.subjectID=$subjectId  AND exm.semId = $semId AND exm.batchID=$batchId ";
        if ($percentage) {
            $sql .= "AND sld.percentage=$percentage";
        }
        try {
            return $this->executeQueryForObject($sql, false, $this->mapper[ExamServiceMapper::GET_SLOW_LEARNER_IDENTIFICATION]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get slow learner identification by examId
     * @param int $examId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSlowLearnerIdentificationByExamId($examId)
    {
        $examId = $this->realEscapeString($examId);
        $sql = "SELECT sld.*, sub.subjectID, exm.examId, exm.examTypeID FROM slowLearnerIdentification sld INNER JOIN exam exm ON exm.examID=sld.examId INNER JOIN subjects sub ON sub.subjectID=exm.subjectID WHERE exm.examID=$examId";
        try {
            return $this->executeQueryForObject($sql, false, $this->mapper[ExamServiceMapper::GET_SLOW_LEARNER_IDENTIFICATION]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get slow learner identification by examId
     * @param int $examId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function removeSlowLearnerIdentificationByExamId($examId)
    {
        $examId = $this->realEscapeString($examId);
        $sql = "DELETE FROM slowLearnerIdentification WHERE examId=$examId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get exam faild student details
     * @param int $examTypeId
     * @param int $subjectId
     * @param int $batchId
     * @param float $percenatge
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamFaildStudentDetails($examTypeId, $subjectId, $percentage, $batchId)
    {
        $examTypeId = $this->realEscapeString($examTypeId);
        $subjectId = $this->realEscapeString($subjectId);
        $batchId = $this->realEscapeString($batchId);
        $percentage = $this->realEscapeString($percentage);
        $sql = "SELECT sa.studentID as id, sa.myImage, sa.rollNo, sa.studentName as name, exm.examID, exm.batchID, exm.semID, exm.subjectID, sm.marksObtained, exm.examTotalMarks FROM student_marks sm INNER JOIN exam exm ON exm.examID=sm.examID AND exm.batchID=sm.batchID AND exm.semID=sm.semID INNER JOIN studentaccount sa ON sm.studentID=sa.studentID inner join semesters sem on sem.semID = sm.semID inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID WHERE sm.examTypeID=$examTypeId AND sm.percentage< '$percentage' AND sm.subjectID=$subjectId AND exm.batchID=$batchId and joinedSem.orderNo <= sem.orderNo";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get exam  details
     * @param int $examTypeId
     * @param int $subjectId
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsBySubjectId($examTypeId, $subjectId, $batchId)
    {
        $examTypeId = $this->realEscapeString($examTypeId);
        $subjectId = $this->realEscapeString($subjectId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT distinct exm.examID, exm.examName FROM student_marks sm INNER JOIN exam exm ON exm.examID=sm.examID AND exm.batchID=sm.batchID AND exm.semID=sm.semID WHERE sm.examTypeID=$examTypeId AND sm.subjectID=$subjectId AND exm.batchID=$batchId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get exam details by exam id
     * @param int $examId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsByExamId($examId)
    {
        $examId = $this->realEscapeString($examId);
        $sql = "SELECT exm.examID, exm.examName, et.typeName, et.typeDesc, sub.subjectID, exm.examDate, exm.examStartTime, exm.examEndTime, sub.subjectName, sub.subjectDesc, exm.examTotalMarks,exm.batchID, exm.semID, exm.examTypeID, exm.subbatchID,exm.examregID, exm.isRoundOff,et.isInternal,exm.examregID,exm.supply_examreg_id as supplyRegId  FROM exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID INNER JOIN subjects sub ON sub.subjectID = exm.subjectID WHERE exm.examID=$examId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Get examId by subjectId
     * @param int $subjectId
     * @param int $batchId
     * @param int $semId
     * @param string $fromDate
     * @param string $toDate
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsByBatchAndSubjectId($subjectId, $batchId, $semId, $fromDate = null, $toDate = null, $subbatchId = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $fromDate = $this->realEscapeString($fromDate);
        $toDate = $this->realEscapeString($toDate);
        $subbatchId = $this->realEscapeString($subbatchId);
        $toDate = $toDate ? date('Y-m-d', strtotime($toDate)) : null;
        $fromDate = $fromDate ? date('Y-m-d', strtotime($fromDate)) : null;
        $sql = "SELECT exm.examID, exm.examDate, et.typeName,exm.examTotalMarks, et.typeID  FROM exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID WHERE exm.batchID=$batchId AND exm.semID=$semId AND exm.subjectID=$subjectId ";
        if ($fromDate && $toDate) {
            $sql .= "AND examDate BETWEEN '$fromDate' AND '$toDate'";
        }
        if ($subbatchId) {
            $sql .= "AND subbatchID IN (0,$subbatchId)";
        }
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Get examId by subjectId
     * @param int $subjectId
     * @param int $batchId
     * @param int $semId
     * @param string $fromDate
     * @param string $toDate
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsByBatchAndSubjectIdAndExamType($subjectId, $batchId, $semId, $fromDate = null, $toDate = null, $subbatchId = null, $examTypeID = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $fromDate = $this->realEscapeString($fromDate);
        $toDate = $this->realEscapeString($toDate);
        $subbatchId = $this->realEscapeString($subbatchId);
        $toDate = $toDate ? date('Y-m-d', strtotime($toDate)) : null;
        $fromDate = $fromDate ? date('Y-m-d', strtotime($fromDate)) : null;
        $sql = "SELECT exm.examID, exm.examDate, et.typeName,exm.examTotalMarks, et.typeID  FROM exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID WHERE exm.batchID='$batchId' AND exm.semID='$semId' AND exm.subjectID='$subjectId";
        if ($fromDate && $toDate) {
            $sql .= " AND examDate BETWEEN '$fromDate' AND '$toDate'";
        }
        if ($subbatchId) {
            $sql .= " AND subbatchID IN (0,$subbatchId)";
        }
        if(!empty($examTypeID))
        {
            $sql .=" AND et.TypeID = '$examTypeID'";
        }
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Show or hide exams
     * @param int $examID
     * @param int $value
     */
    public function setCanShowExam($examId, $value)
    {
        $examId = $this->realEscapeString($examId);
        $value = $this->realEscapeString($value);
        $sql = "update exam set canShow = $value where examID = $examId";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * get exam hall seating allotment in order of regno
     * @param int $groupId
     * @return object|array|\com\linways\base\util\$objectList[]
     */
    public function getExamHallSeatingAllotmentByRegNo($groupId)
    {
        $groupId = $this->realEscapeString($groupId);
        $seatingAllotment = [];
        $sql = "select dept.deptID, dept.deptName, bth.batchID, bth.batchName,min(sa.rollNo) as rollNoMin,max(sa.rollNo) as rollNoMax, min(sa.regNo) as regNoMin ,max(sa.regNo) as regNoMax,sub.subjectName, count(ehas.studentID) as totalStudent, eh.hallID, eh.hallName  from exam_hall_arranged_students ehas INNER JOIN studentaccount sa ON sa.studentID=ehas.studentID INNER JOIN batches bth ON bth.batchID=sa.batchID INNER JOIN department dept ON dept.deptID=bth.deptID INNER JOIN exam ex ON ex.examID=ehas.examID INNER JOIN subjects sub ON sub.subjectID=ex.subjectID INNER JOIN exam_halls eh ON eh.hallID=ehas.hallID WHERE ehas.groupID=$groupId group by ex.examID,eh.hallID order by dept.deptName, bth.batchName, ex.examID, regNoMin";
        try {
            $seatingAllotment = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_SEATING_ALLOTMENT]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $seatingAllotment;
    }
    /**
     * Get exam hall arranged students details
     * @param int $groupId
     * @param int $hallId
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamHallAssignedStudentDetailsByHallId($groupId, $hallId, $batchId, $orderBy = 'rollNo')
    {
        $groupId = $this->realEscapeString($groupId);
        $hallId = $this->realEscapeString($hallId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT sa.studentID, sa.studentName, sa.rollNo, sa.regNo FROM exam_hall_arranged_students ehas INNER JOIN studentaccount sa ON sa.studentID = ehas.studentID
WHERE ehas.groupID = $groupId and ehas.hallID = $hallId and sa.batchID = $batchId ORDER BY  ehas.examID , $orderBy";
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentDetails;
    }
    /**
     * Get exam undefined subjects by examTYpeId
     * @param int $batchId
     * @param int $semId
     * @param int $examTypeId
     * @throws ProfessionalException
     */
    public function getExamsUnDefinedSubjectsByExamTypeId($batchId, $semId, $examTypeId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $sql = "SELECT distinct sr.subjectID, sub.subjectName, sub.subjectDesc FROM sbs_relation sr inner join subjects sub on  sub.subjectID=sr.subjectID
left join exam ex on ex.subjectID = sub.subjectID and ex.batchID = sr.batchID and ex.semID = sr.semID and examTypeID = '$examTypeId' where sr.batchID=$batchId and sr.semID= $semId and sr.subjectID not in(select subjectID from exam where batchID=$batchId and semID=$semId and examTypeID='$examTypeId') order by sub.subjectID asc";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $subjectDetails;
    }
    /**
     * Update exam type to show or hide examtype
     * @param int $examTypeId
     * @param int $value
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function setCanShowExamType($examTypeId, $value)
    {
        $examTypeId = $this->realEscapeString($examTypeId);
        $value = $this->realEscapeString($value);
        $sql = "update exam_type set canShow = $value where typeID = $examTypeId";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Get university exam entry type by studentId
     * @param int $studentId
     * @return NULL|string
     */
    public function getExamEntryTypeByStudentId($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        $entryType = NULL;
        $sql = "select entryType from university_assignbatchcourse ua inner join university_coursetypegrading uc on ua.typeID = uc.typeID inner join studentaccount sa on sa.batchID = ua.batchID where sa.studentID = $studentId";
        try {
            $type = $this->executeQueryForObject($sql)->entryType;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        if ($type == 1) {
            $entryType = "MARK";
        } elseif ($type == 2) {
            $entryType = "GRADE";
        }
        return $entryType;
    }
    /**
     * Get student arrears count
     * @param int $studentId
     * @throws ProfessionalException
     */
    public function getStudentArrearsCount($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        try {
            $entryType = $this->getExamEntryTypeByStudentId($studentId);
            if ($entryType == "MARK") {
                $count = $this->getStudentUniversityExamFailedCountByMark($studentId)->count;
            } else if ($entryType == "GRADE") {
                $count = $this->getStudentUniversityExamFailedCountByGrade($studentId)->count;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $count;
    }
    /**
     * Get count of failed university exams by mark
     * @param int $studentId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentUniversityExamFailedCountByMark($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        $sql = "SELECT count(um.examID) as count FROM
                universityMarks um
                    INNER JOIN
                universityExams ue ON um.semID = ue.semID
                    AND um.examID = ue.examID
                    AND um.subjectID = ue.subjectID
                    INNER JOIN
                university_assignbatchcourse uab ON uab.batchID = ue.batchID
                    INNER JOIN
                university_coursetypegrading uct ON uct.typeID = uab.typeID
                    INNER JOIN
                mark_failed_criteria mfc ON mfc.typeID = uab.typeID
            WHERE
                 um.studentID = $studentId and (um.percentage< external_percentage  or (um.percentage + um.internalPercentage) < total_percentage)";
        try {
            $count = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $count;
    }
    /**
     * Get count of failed university exams by grade
     * @param int $studentId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentUniversityExamFailedCountByGrade($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        $sql = "SELECT us.studentID, count(CASE WHEN us.gradeObtained IN (select ug.gradeID FROM university_gradepoints ug INNER JOIN university_assignbatchcourse ua ON ua.typeID = ug.typeID WHERE ua.batchID= st.batchID AND ug.gradePoint=0) THEN 1 END )AS count FROM university_studentgrade us INNER JOIN studentaccount st ON st.studentID = us.studentID WHERE st.studentID = $studentId";
        try {
            $count = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $count;
    }
    /**
     * Get exam hall assigned staff details
     * @param int $deptId
     * @param string $startDate
     * @param string $endDate
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamHallAssignedStaffByDeptId($deptId, $startDate, $endDate)
    {
        $deptId = $this->realEscapeString($deptId);
        $startDate = $this->realEscapeString($startDate);
        $endDate = $this->realEscapeString($endDate);
        $sql = "SELECT DISTINCT ex.examID, ex.examDate, et.typeName, eh.hallID, eh.hallName, ex.examStartTime, ex.examEndTime, sa.staffID,  staffName, sa.deptID, concat(examDate, examStartTime) as examDateTime FROM exam ex INNER JOIN exam_type et ON ex.examTypeID = et.typeID INNER JOIN exam_group_exams  ege ON ege.examID = ex.examID INNER JOIN exam_hall_arranged_staffs eha ON eha.groupID = ege.groupID INNER JOIN exam_halls eh ON eh.hallID = eha.hallID inner join staffaccounts sa on sa.staffID = eha.staffID where sa.deptID = $deptId and ex.examDate between '$startDate' and '$endDate' ORDER BY examDate, examStartTime, staffname";
        try {
            $examHallDetails = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_INVIGILATION_STAFF_DETAILS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examHallDetails;
    }
    /**
     * Get student university marks in mark scheme
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentUniversityExamMarks($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        try {
            $sortByColumn = BatchService::getInstance()->getStudentSortByColumnOfABatch($batchId);
            if(empty(trim($sortByColumn))){
                $sortByColumn == 'regNo';
            }
        } catch (\Throwable $th) {
            $sortByColumn == 'regNo';
        }
        $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($batchId, $semId);
        if ($isCurrentSem) {
            $sql = "select sa.studentID, studentName, studentAccount, admissionNo, rollNo, regNo, ue.examID, ue.examName, ue.examTotalMarks, ue.maxInternal, sub.subjectID, sub.subjectName, sub.subjectDesc, um.internalMark, um.marksObtained, um.chances, um.internalPercentage, um.percentage, bat.batchID, um.semID, uec.creditID, uec.credit, examTotalMarks, isInternal, maxInternal, case when passType=0 then 'Rg'  when passType=1 then 'Su' when passType=2 then 'Im' end as passType from studentaccount sa inner join batches bat on bat.batchID = sa.batchID left join universityExams ue on ue.batchID = bat.batchID and ue.semID = $semId left join universityMarks um on um.examID = ue.examID and ue.semID = um.semID and sa.studentID = um.studentID
LEFT JOIN
            subjects sub ON sub.subjectID = ue.subjectID
                LEFT JOIN
            university_examcredits uec ON uec.subjectID = ue.subjectID
                AND ue.batchID = uec.batchID
                AND ue.semID = uec.semID
 where bat.batchID =$batchId
        ORDER BY sa.$sortByColumn , sub.subjectID";
        } else {
            $sql = "select sa.studentID, studentName, studentAccount, admissionNo, rollNo, regNo, ue.examID, ue.examName, ue.examTotalMarks, ue.maxInternal, sub.subjectID, sub.subjectName, sub.subjectDesc, um.internalMark, um.marksObtained, um.chances, um.internalPercentage, um.percentage, ue.batchID, um.semID, uec.creditID, uec.credit, examTotalMarks, isInternal, maxInternal, case when passType=0 then 'Rg'  when passType=1 then 'Su' when passType=2 then 'Im' end as passType from studentaccount sa left join failed_students fs on fs.studentID = sa.studentID  left join  universityExams ue on (ue.batchID = sa.batchID or ue.batchID = fs.previousBatch) and ue.semID = $semId left join universityMarks um on um.examID = ue.examID and ue.semID = um.semID and sa.studentID = um.studentID
LEFT JOIN
            subjects sub ON sub.subjectID = ue.subjectID
                LEFT JOIN
            university_examcredits uec ON uec.subjectID = ue.subjectID
                AND ue.batchID = uec.batchID
                AND ue.semID = uec.semID
 where ue.batchID =$batchId
        ORDER BY sa.$sortByColumn , sub.subjectID";
        }
        try {
            $studentList = $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_STUDENT_UNIVERSITY_MARKS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $studentList;
    }
    /**
     * Get university exams defined by mark scheme
     * @param int $batchId
     * @param int $semId
     * @throws ProfessionalException
     */
    public function getUniversityExams($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "select ue.examID, ue.examName, ue.examTotalMarks, ue.batchID, ue.semID, ue.isInternal, ue.maxInternal, sub.subjectID, sub.subjectName, sub.subjectDesc, sub.deptID, sub.syllabusName, sub.subjectPriority, sub.hdl_deptID, spt.paperTypeName, sc.subjectCatName from universityExams ue inner join subjects sub on ue.subjectID = sub.subjectID left join subject_category sc on sc.subjectcatID = sub.subjectcatID left join subjectPaperType spt on spt.id = sub.paperTypeId where ue.batchID = $batchId and ue.semID =  $semId order by sub.subjectID, sub.subjectPriority;";
        try {
            $examDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examDetails;
    }
    /**
     * get student university exam mark details
     * @param int $studentId
     * @param int $examId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentUniversityExamMarkDetails($studentId, $examId)
    {
        $studentId = $this->realEscapeString($studentId);
        $examId = $this->realEscapeString($examId);
        $sql = "select examID, subjectID, marksObtained, percentage, internalMark, internalPercentage, semID, studentID, chances, passType, cg from universityMarks where examID = $examId and studentID = $studentId";
        try {
            $examDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examDetails;
    }
    /**
     * update student university mark
     * @param UniversityExamMarks $universityExamMark
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function updateStudentUniversityMark($universityExamMark)
    {
        $universityExamMark = $this->realEscapeObject($universityExamMark);
        $sql = "update universityMarks set marksObtained = $universityExamMark->marksObtained, percentage=$universityExamMark->percentage, internalMark = $universityExamMark->internalMark, internalPercentage = $universityExamMark->internalPercentage, chances = $universityExamMark->chances, passType = $universityExamMark->passType, cg = '$universityExamMark->cg' where examID = $universityExamMark->examId and studentID = $universityExamMark->studentId";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * create student university mark
     * @param UniversityExamMarks $universityExamMark
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function createStudentUniversityMark($universityExamMark)
    {
        $universityExamMark = $this->realEscapeObject($universityExamMark);
        $sql = "insert into universityMarks (examID, subjectID, marksObtained, percentage, internalMark, internalPercentage, semID, studentID, chances, passType, cg) value ($universityExamMark->examId$universityExamMark->subjectId$universityExamMark->marksObtained, '$universityExamMark->percentage', '$universityExamMark->internalMark', '$universityExamMark->internalPercentage', $universityExamMark->semId$universityExamMark->studentId, '$universityExamMark->chances', '$universityExamMark->passType', '$universityExamMark->credit')";
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    public function getSubjectCommunityQuestions($subjectId, $sbsId)
    {
        $subjectId = $this->realEscapeString($subjectId);
        $sbsId = $this->realEscapeString($sbsId);
        $questions = NULL;
        $sql = "SELECT qst.id, qst.question, qst.mark as marks, qst.public_question, cpyInfo.copiedQuestionId, cpyInfo.newQuestionId, stff.staffName as author
                    FROM assessment_questions qst
                        INNER JOIN sbs_relation sbs ON qst.sbs_id = sbs.sbsID
                        INNER JOIN staffaccounts stff ON sbs.staffID = stff.staffID
                        LEFT JOIN copied_assessment_question_info cpyInfo ON qst.id = cpyInfo.copiedQuestionId AND cpyInfo.sbsId = $sbsId
                    WHERE qst.subjectID = " . $subjectId . " AND qst.public_question = 1 AND qst.sbs_id != " . $sbsId . "
                        ORDER BY qst.id DESC";
        try {
            $questions = $this->executeQueryForList($sql, $this->mapper [ExamServiceMapper::GET_EXAM_QUESTIONS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $questions;
    }
    public function getStudentUniversityResults($studentId, $batchId, $semId = NULL, $previousResults = FALSE)
    {
        $entryType = ExamService::getInstance()->getExamEntryType($batchId);
        if ($entryType == "GRADE") {
            $sql = "SELECT
                sa.studentID,
                sa.studentName,
                sa.rollNo,
                sa.admissionNo,
                sa.studentEmail,
                sa.studentPhone,
                sa.parentPhone,
                sa.regNo,
                dep.deptID,
                dep.deptName,
                dep.departmentDesc,
                sub.subjectID,
                sub.subjectName,
                sub.subjectDesc,
                ug.letterGrade AS gradeObtained,
                if(ug.gradePoint = 0, 0, ue.credit) as credit,
                sem.semID, sem.semName, sem.year, sem.orderNo, sem.type,
                ba.batchId, ba.batchName
            FROM
                studentaccount sa
                inner join department dep on dep.deptID = sa.deptID
                    INNER JOIN
                    batches ba on ba.batchID = sa.batchID
                    inner join
                university_studentgrade usg ON usg.studentID = sa.studentID
                    INNER JOIN
                subjects sub ON sub.subjectID = usg.subjectID
                    INNER JOIN
                university_gradepoints ug ON ug.gradeID = usg.gradeObtained
                inner join university_examcredits ue on ue.batchID = sa.batchID and ue.semID = usg.semID and usg.subjectID = ue.subjectID
                left join semesters sem on sem.semID = ue.semID
            WHERE
                 usg.studentID = $studentId";
            if (!empty($semId))
                $sql .= " AND ue.semID = $semId";
            elseif ($previousResults)
                $sql .= " and sem.semID < ba.semID";
            $sql .= "  ORDER BY ue.semID , sub.subjectID";
        } else {
            $sql = "SELECT
                        sa.studentID,
                        sa.studentName,
                        sa.rollNo,
                        sa.admissionNo,
                        sa.studentEmail,
                        sa.studentPhone,
                        sa.parentPhone,
                        sa.regNo,
                        ue.examID,
                        sub.subjectID,
                        sub.subjectName,
                        sub.subjectDesc,
                        (if(um.internalMark, um.internalMark, 0) + if(um.marksObtained, um.marksObtained, 0)) AS gradeObtained,
                        um.internalPercentage,
                        um.percentage,
                        bat.batchID,
                        sem.semID, sem.semName, sem.year, sem.orderNo, sem.type,
                        uec.creditID,
                        uec.credit,
                        bat.batchId, bat.batchName
                    FROM
                        studentaccount sa
                            INNER JOIN
                        batches bat ON bat.batchID = sa.batchID
                            LEFT JOIN
                        universityExams ue ON ue.batchID = bat.batchID
                            LEFT JOIN
                        universityMarks um ON um.examID = ue.examID
                            AND ue.semID = um.semID
                            AND sa.studentID = um.studentID
                            LEFT JOIN
                        subjects sub ON sub.subjectID = ue.subjectID
                            LEFT JOIN
                        university_examcredits uec ON uec.subjectID = ue.subjectID
                            AND ue.batchID = uec.batchID
                            AND ue.semID = uec.semID
                        left join semesters sem on sem.semID = ue.semID
                    WHERE
                        bat.batchID = $batchId AND um.studentID = $studentId";
            if (!empty($semId))
                $sql .= " AND ue.semID = $semId";
            elseif ($previousResults)
                $sql .= " and sem.semID < bat.semID";
            $sql .= "  ORDER BY ue.semID , sub.subjectID";
        }
        try {
            $studentDetails = $this->executeQueryForObject($sql, false, $this->mapper[ExamServiceMapper::GET_STUDENT_UNIVERSITY_RESULT]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * Get exam passed and failed student count
     * @param int $sbsId
     * @param string $fromDate
     * @param string $toDate
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsBySbsId($sbsId, $fromDate, $toDate)
    {
        $sbsId = $this->realEscapeString($sbsId);
        $fromDate = $this->realEscapeString($fromDate);
        $toDate = $this->realEscapeString($toDate);
        $sql = "select noOfExams, count(failed) as studentsFailed, sum(case when failed is null then 1 end) as studentsPassed from (SELECT count(ex.examID) as noOfExams,studentID, sum(case when percentage< 40 then 1 end) as failed FROM exam ex inner join sbs_relation sr on ex.batchID = sr.batchID and ex.semID = sr.semID and ex.subjectID = sr.subjectID left join student_marks sm on ex.examID= sm.examID where sbsID = $sbsId and examDate between '$fromDate' and '$toDate' group by studentID) as examDet";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getExamDetailsBySBS($batchId, $subjectId, $semId)
    {
        $sql = "SELECT distinct examTypeID, typeName from exam ex inner join exam_type et on ex.examTypeID = et.typeID where subjectID = $subjectId AND batchID = $batchId AND semID = $semId AND ex.canShow = 1 and et.canShow= 1";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getInternalExamDetailsBySBS($batchId, $subjectId, $semId)
    {
        $sql = "SELECT distinct examTypeID, typeName from exam ex inner join exam_type et on ex.examTypeID = et.typeID where subjectID = $subjectId AND batchID = $batchId AND semID = $semId AND ex.canShow = 1 and et.canShow= 1 and et.isInternal = 1";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get exam enrollment list by sem and batch
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamEnorollmentList($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "select sr.subjectID, sub.subjectName,sub.subjectDesc, ef.fees, if(esf.examEnrollmentFeeId,'assigned','') as status, ef.id from sbs_relation sr inner join subjects sub  on sub.subjectID = sr.subjectID left join examEnrollmentFees ef ON ef.batchId=sr.batchID AND ef.semId=sr.semID AND ef.subjectId = sr.subjectID left join examEnrollmentStudentFees esf ON esf.examEnrollmentFeeId=ef.id where  sr.batchID = $batchId and sr.semID=$semId and sub.subjectName not in (\"" . Subject::TUTOR_SUBJECT . "\") group by sr.subjectID order by sr.subjectID";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * update exam enrollment by id
     * @param ExamEnrollmentFees $examEnrollmentFee
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    function updateExamEnorollment($examEnrollmentFee)
    {
        $examEnrollmentFee = $this->realEscapeObject($examEnrollmentFee);
        $sql = "UPDATE examEnrollmentFees set fees='$examEnrollmentFee->fees', updatedBy=$examEnrollmentFee->updatedBy, updatedDate=utc_timestamp() WHERE id=$examEnrollmentFee->id";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * delete exam enrollment by id
     * @param int $id
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    function removeExamEnorollment($id)
    {
        $id = $this->realEscapeString($id);
        $sql = "DELETE FROM examEnrollmentFees WHERE id=$id";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * add exam enrollment fees
     * @param array $examEnrollmentFeeList
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function addExamEnorollment($examEnrollmentFeeList)
    {
        $examEnrollmentFeeList = $this->realEscapeArray($examEnrollmentFeeList);
        $value = [];
        $sql = "INSERT INTO examEnrollmentFees (subjectId, batchId, semId, fees, createdBy, createdDate, updatedBy, updatedDate) VALUES";
        foreach ($examEnrollmentFeeList as $examEnrollmentFee) {
            $value[] = "($examEnrollmentFee->subjectId$examEnrollmentFee->batchId$examEnrollmentFee->semId, '$examEnrollmentFee->fees', $examEnrollmentFee->createdBy, utc_timestamp(), $examEnrollmentFee->updatedBy, utc_timestamp())";
        }
        try {
            $sql .= implode(', ', $value);
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get exam enrollment list by student
     * @param int $batchId
     * @param int $semId
     * @param int $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentExamEnorollmentList($batchId, $studentId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $studentId = $this->realEscapeString($studentId);
        $sql = "select distinct sub.subjectID, sub.subjectName,sub.subjectDesc, ef.fees, if(esf.examEnrollmentFeeId,'assigned','') as status, ef.id from sbs_relation sr inner join subjects sub  on sub.subjectID = sr.subjectID inner join examEnrollmentFees ef ON ef.batchId=sr.batchID AND ef.semId=sr.semID AND ef.subjectId = sr.subjectID left join examEnrollmentStudentFees esf ON esf.examEnrollmentFeeId=ef.id and esf.studentID=$studentId where  sr.batchID = $batchId and sr.semID=$semId order by sr.subjectID";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * add student exam enrollment fees
     * @param array $examEnrollmentFeeList
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function addStudentExamEnorollment($examEnrollmentFeeList)
    {
        $examEnrollmentFeeList = $this->realEscapeArray($examEnrollmentFeeList);
        $value = [];
        $sql = "INSERT INTO examEnrollmentStudentFees (studentId, examEnrollmentFeeId, createdBy, createdDate, updatedBy, updatedDate) VALUES";
        foreach ($examEnrollmentFeeList as $examEnrollmentFee) {
            $value[] = "($examEnrollmentFee->studentId$examEnrollmentFee->examEnrollmentFeeId$examEnrollmentFee->createdBy, utc_timestamp(), $examEnrollmentFee->updatedBy, utc_timestamp())";
        }
        try {
            $sql .= implode(', ', $value);
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * remove student assigned exam enrollment
     * @param int $batchId
     * @param int $semId
     * @param int $studentId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function removeStudentExamEnorollment($batchId, $semId, $studentId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $studentId = $this->realEscapeString($studentId);
        $sql = "DELETE esf.* FROM examEnrollmentStudentFees esf INNER JOIN examEnrollmentFees ef ON ef.id=esf.examEnrollmentFeeId WHERE esf.studentID=$studentId AND ef.batchId = $batchId AND ef.semId=$semId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get exam enrolled student list by batch and sem;
     * @param int $batchId
     * @param int $semId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamEnrollmentStudentList($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "select sa.studentID, sa.studentName, sa.rollNo, (select sum(fees) from examEnrollmentFees ef1 INNER JOIN examEnrollmentStudentFees esf1 ON esf1.examEnrollmentFeeId=ef1.id WHERE ef1.batchId=ef.batchId AND ef1.semId=ef.semId and esf1.studentId=esf.studentId) as totalFee from examEnrollmentStudentFees esf INNER JOIN examEnrollmentFees ef ON ef.id=esf.examEnrollmentFeeId INNER JOIN studentaccount sa ON sa.studentID=esf.studentID AND sa.batchID=ef.batchId inner join batches ba on ba.batchID = sa.batchID inner join semesters sem on sem.semID = ba.semID inner join semesters joinedSem on sa.joiningSemId = joinedSem.semID WHERE ef.batchId=$batchId AND ef.semId=$semId and joinedSem.orderNo <= sem.orderNo group by esf.studentId order by esf.studentId";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get student exam enrollment details by student id
     * @param int $batchId
     * @param int $semId
     * @param int $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentEnrollmentDetails($batchId, $semId, $studentId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $studentId = $this->realEscapeString($studentId);
        $sql = "select distinct sub.subjectID, sub.subjectName,sub.subjectDesc, ef.fees, ef.id from sbs_relation sr inner join subjects sub  on sub.subjectID = sr.subjectID inner join examEnrollmentFees ef ON ef.batchId=sr.batchID AND ef.semId=sr.semID AND ef.subjectId = sr.subjectID INNER join examEnrollmentStudentFees esf ON esf.examEnrollmentFeeId=ef.id where  sr.batchID = $batchId AND sr.semID=$semId AND esf.studentID=$studentId order by sr.subjectID";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get student exam percentage
     * @param int $batchId
     * @param int $semId
     * @param int $examTypeId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentExamPercentage($batchId, $semId, $examTypeId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semId);
        $sql = "select sa.studentID, sa.studentName ,sum(percentage)/(select count(examID) as percentage from exam where batchID=$batchId  and semID=$semId and examTypeID=$examTypeId) as studentpercent from student_marks sm inner join studentaccount sa on sm.studentID = sa.studentID inner join semesters joinedSem on joinedSem.semID = sa.joiningSemId left join failed_students fs on fs.studentID = sa.studentID left join semesters fsem on fsem.semID = fs.failedInSemester  where sm.batchID=$batchId and examTypeID=$examTypeId and  sm.semID=$semId AND ( fsem.orderNo > $semDetails->orderNo or fsem.orderNo is null ) and joinedSem.orderNo <= $semDetails->orderNo group by sm.studentID order by rollNo;";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get sem wise university credit details
     * @param int $batchId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSemWiseUniversitySgpa($batchId, $semID = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $entryType = $this->getExamEntryType($batchId);
        $semID = $this->realEscapeString($semID);
        $considerFailedSubjCredit = MarkService::getInstance()->checkIfFailedSubjCreditConsidered($batchId);
        $credit_sql = " sum(credit)";
        if ($entryType == "GRADE") {
            $condition = '';
            if ($semID) {
                $condition = "and sem.semID=$semID";
            }
            if (!$considerFailedSubjCredit)
                $credit_sql = " sum(case when ugp.gradePoint != 0 then credit else 0 end)";
            $sql = "select us.studentID, studentName, rollNo,regNo, us.semID,sem.semName ,concat(us.studentID,us.semID) as id,sum(ugp.gradePoint * credit) as creditGained, group_concat(if(ugp.gradePoint = 0, sub.subjectName, null) separator ', ') as failedSubjects, $credit_sql  as creditSum, sum(case when ugp.gradePoint = 0 then 1 else 0 end) as noOfArrers, sum(case when ugp.gradePoint != 0 then credit else 0 end) as studentCredit from studentaccount sa left join university_studentgrade us on sa.studentID = us.studentID inner join universityExams ue on ue.examID = us.examID and ue.subjectID = us.subjectID and ue.semID= us.semID inner join batches ba on ba.batchID = ue.batchID inner join semesters sem on sem.semID = ue.semID left join university_examcredits uec on uec.batchID = ue.batchID and uec.semID = ue.semID and uec.subjectID = ue.subjectID left join university_gradepoints ugp on ugp.gradeID = us.gradeObtained LEFT JOIN subjects sub on sub.subjectID= us.subjectID where ue.batchID = $batchId $condition group by us.studentID, ue.batchID, us.semID ;";
        } else {
            $con = '';
            if ($semID) {
                $con = "and exmSem.semID=$semID";
            }
            if (!$considerFailedSubjCredit)
                $credit_sql = " sum(case when (SELECT ug.gradePoint FROM university_gradepoints ug INNER JOIN university_assignbatchcourse uab on uab.typeID = ug.typeID WHERE ((if(marksObtained is null, 0, marksObtained) +  internalMark) / (examTotalMarks + maxInternal) * 100) between percentFrom and percentTo AND uab.batchID=$batchId) != 0 then credit else 0 end) ";
            $sql = "select um.studentID, studentName, rollNo,regNo, sa.batchID,concat(um.studentID,um.semID) as id,  um.semID,exmSem.semName, sum((if(marksObtained is null, 0, marksObtained) +  internalMark)) as total, $credit_sql as creditSum ,sum(credit * (SELECT ug.gradePoint FROM university_gradepoints ug INNER JOIN university_assignbatchcourse uab on uab.typeID = ug.typeID WHERE ((if(marksObtained is null, 0, marksObtained) +  internalMark) / (examTotalMarks + maxInternal) * 100) between percentFrom and percentTo AND uab.batchID=$batchId)) as creditGained , sum(case when (SELECT ug.gradePoint FROM university_gradepoints ug INNER JOIN university_assignbatchcourse uab on uab.typeID = ug.typeID WHERE ((if(marksObtained is null, 0, marksObtained) +  internalMark) / (examTotalMarks + maxInternal) * 100) between percentFrom and percentTo AND uab.batchID=$batchId)= 0 then 1 else 0 end) as noOfArrers from universityExams ue left join universityMarks um on ue.examID = um.examID and ue.subjectID = um.subjectID and ue.semID= um.semID left join studentaccount sa on sa.studentID = um.studentID inner join batches ba on ba.batchID = ue.batchID inner join semesters exmSem on exmSem.semID = ue.semID left join university_examcredits uec on uec.batchID = ue.batchID and uec.semID = ue.semID and uec.subjectID = ue.subjectID where ue.batchID = $batchId $con group by um.studentID, ue.batchID, um.semID ;";
        }
        try {
            return $this->executeQueryForList($sql, $this->mapper[ExamServiceMapper::GET_STUDENT_SEMWISE_UNIVERSITY_RESULT]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getExamTimeTables($getExamTimeTablesRequest)
    {
        $response = new GetExamTimeTablesResponse();
        $criteria = NULL;
        if (!empty($getExamTimeTablesRequest)) {
            $sqlCount = "SELECT distinct count(distinct ex.examTypeID) as totalRecords ";
            $sqlTimeTable = "SELECT ex.examID,ex.examName,ex.subjectID,ex.examTotalMarks, ex.examStartTime,ex.examEndTime,ex.examDate,sub.subjectName,ex.examTypeID,et.typeName ,sub.subjectDesc,ex.attendanceEndDate,ex.subbatchID";
            $fromCondition = " FROM exam ex INNER JOIN subjects sub ON ex.subjectID = sub.subjectID INNER JOIN semesters sem ON ex.semID = sem.semID INNER JOIN batches b ON b.batchID = ex.batchID LEFT JOIN exam_type et ON et.typeID = ex.examTypeID WHERE ex.examID IS NOT NULL ";
            $sqlCount .= $fromCondition;
            $sqlTimeTable .= $fromCondition;
            // Batch ID
            if (!empty($getExamTimeTablesRequest->batchId)) {
                $criteria .= " AND ex.batchID = $getExamTimeTablesRequest->batchId";
            }
            // Sem ID
            if (!empty($getExamTimeTablesRequest->semId)) {
                $criteria .= " AND ex.semID = $getExamTimeTablesRequest->semId";
            } else {
                $criteria .= " and ex.semID = b.semID ";
            }
            // Exam Type ID
            if (!empty($getExamTimeTablesRequest->examTypeId)) {
                $criteria .= " AND ex.examTypeID = $getExamTimeTablesRequest->examTypeId";
            }
            // $criteria .= "  GROUP BY ex.subjectID";
            // set criteria to count
            $sqlCount .= $criteria;
            // Adding sort condition
            if (!empty($getExamTimeTablesRequest->sortBy)) {
                $criteria .= " ORDER BY $getExamTimeTablesRequest->sortBy $getExamTimeTablesRequest->sortOrder";
            }
            // Adding Pagination
            if (!$getExamTimeTablesRequest->isExport) {
                $pagination = " LIMIT $getExamTimeTablesRequest->startIndex$getExamTimeTablesRequest->endIndex";
            }
            $sqlTimeTable .= $criteria . $pagination;
            try {
                $response->totalRecords = $this->executeQueryForObject($sqlCount)->totalRecords;
                $response->examTimeTable = $this->executeQueryForList($sqlTimeTable);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        } else {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "GetExamTimeTableRequest is null");
        }
        $examType = null;
        $examSubject = null;
        $examTypeArr = array();
        foreach ($response->examTimeTable as $examTimeTable) {
            if ($examTypeArr[$examTimeTable->examTypeID] != null) {
                // $examTypeArr[] = $examTimeTable->examTypeID;
                $examType = $examTypeArr[$examTimeTable->examTypeID];
            } else {
                $examType = new ExamType();
                $examType->typeID = $examTimeTable->examTypeID;
                $examType->typeName = $examTimeTable->typeName;
            }
            $examSubject = new ExamSubject();
            $examSubject->examID = $examTimeTable->examID;
            $examSubject->examName = $examTimeTable->examName;
            $examSubject->subjectID = $examTimeTable->subjectID;
            $examSubject->examTotalMarks = $examTimeTable->examTotalMarks;
            $examSubject->examStartTime = $examTimeTable->examStartTime;
            $examSubject->examEndTime = $examTimeTable->examEndTime;
            $examSubject->examDate = $examTimeTable->examDate;
            $examSubject->attendanceEndDate = $examTimeTable->attendanceEndDate;
            $examSubject->subjectName = $examTimeTable->subjectName;
            $examSubject->subjectDesc = $examTimeTable->subjectDesc;
            $examSubject->subbatchID = $examTimeTable->subbatchID;
            $examType->examSubject[] = $examSubject;
            $examTypeArr[$examTimeTable->examTypeID] = $examType;
            unset($examSubject);
            unset($examType);
        }
        $response->examTimeTable = $examTypeArr;
        // $examTypeArr = $response->totalRecords;
        return $response;
    }
    /**
     * Get student registered exam details
     * @param int $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentRegisteredExamDetails($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        try {
            $sql = "SELECT er.examMonth, er.examYear,er.examregID FROM exam_registration er INNER JOIN exam_reg_studentchallan ers ON er.examregID = ers.examregID WHERE ers.studentID = $studentId AND ers.paid = 1 AND er.shortCourse = 0";
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get exam semId by examRegId
     * @param int $examRegId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getExamSemId($examRegId, $batchId = NULL)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $whereCondition = "";
        $semId = null;
        if ($batchId) {
            $whereCondition = " AND batchID = $batchId";
        }
        try {
            $sql = "SELECT
                t1.semID AS semId
            FROM
                exam_registration_batches t1
            WHERE
                t1.examregID = $examRegId
                $whereCondition";
            $semId = $this->executeQueryForObject($sql)->semId;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $semId;
    }
    /**
     * Method for checking whether internal , external or both to be considered while combining exams
     * @param unknown $examId
     * @param unknown $batchId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getConsiderExamType($examId, $batchId)
    {
        $sql = '';
        $examId = $this->realEscapeObject($examId);
        $batchId = $this->realEscapeObject($batchId);
        $considerExamType = null;
        try {
            $sql = "SELECT considerExamType AS examType FROM exam_combineInternals WHERE examID = $examId AND batchID = $batchId";
            $considerExamType = $this->executeQueryForObject($sql)->examType;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $considerExamType;
    }
    /**
     * Method for getting student external mark for an exam
     * @param unknown $studentId
     * @param unknown $examId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getExternalMarks($studentId, $examId)
    {
        $sql = '';
        $studentId = $this->realEscapeObject($studentId);
        $examId = $this->realEscapeObject($examId);
        $studentExternalMark = null;
        try {
            $sql = "SELECT ee.mark AS studentExternalMark, e.examTotalMarks AS examTotalMark FROM exammarks_external ee INNER JOIN exam e ON ee.examID = e.examID WHERE ee.studentID = $studentId AND e.examID = $examId";
            $studentExternalMark = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentExternalMark;
    }
    /**
     * get total credits of university exams by batchId
     * @param int $batchId
     * @return int
     * @throws ProfessionalException
     */
    public function getTotalUniversityCreditByBatchId($batchId)
    {
        $sql = "SELECT SUM(uec.credit) AS totalCredit FROM universityExams ue INNER JOIN university_examcredits uec ON uec.subjectID=ue.subjectID AND uec.batchID=ue.batchID AND ue.semID=uec.semID WHERE ue.batchID=$batchId";
        try {
            return $this->executeQueryForObject($sql)->totalCredit;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get total university credits sum by studentId
     * @param int $studentId
     * @return int
     * @throws ProfessionalException
     */
    public function getTotalUniversityCreditsByStudentId($studentId, $batchId)
    {
        $typeId = 0;
        $typeId = $this->getFaildGradeId($batchId);
        $entryType = $this->getExamEntryType($batchId);
        if ($entryType == 'MARK') {
            $sql = "SELECT
               sum(uec.credit) AS totalCredit
            FROM
                universityMarks um
                    INNER JOIN
                universityExams ue ON um.semID = ue.semID
                    AND um.examID = ue.examID
                    AND um.subjectID = ue.subjectID
                    INNER JOIN
                university_assignbatchcourse uab ON uab.batchID = ue.batchID
                    INNER JOIN
                university_coursetypegrading uct ON uct.typeID = uab.typeID
                    INNER JOIN
                mark_failed_criteria mfc ON mfc.typeID = uab.typeID
                    INNER JOIN
                university_examcredits uec ON uec.subjectID=um.subjectID AND uec.semID = um.semID AND ue.batchID=uec.batchID
            WHERE
                uab.batchID = $batchId AND um.studentID = $studentId and (um.percentage >= external_percentage  or (um.percentage + um.internalPercentage) >= total_percentage)";
        } else {
            $sql = "SELECT sum(ue.credit) AS totalCredit FROM university_studentgrade us left join studentaccount sa on us.studentID = sa.studentID INNER JOIN university_gradepoints ug ON us.gradeObtained = ug.gradeID INNER JOIN university_examcredits ue ON ue.subjectID = us.subjectID and ue.semID = us.semID AND ue.batchID=sa.batchID WHERE sa.batchID=$batchId and sa.studentID = $studentId AND us.gradeObtained NOT IN ($typeId)";
        }
        try {
            return $this->executeQueryForObject($sql)->totalCredit;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getClassAvgBySubject($batchId, $semId, $examTypeId, $subjectId)
    {
        $sql = "select sum(if(t1.marksObtained != '-.001' AND t1.marksObtained !='-1',t1.marksObtained,0)) as totalObtained from student_marks t1,exam t2 where t1.examID=t2.examID and t1.semID=$semId and t1.batchID=$batchId and t1.examTypeID=$examTypeId AND t1.subjectID=$subjectId";
        try {
            return $this->executeQueryForObject($sql)->totalObtained;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     *
     * @param int $supplyExamRegId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function checkThisExamRegisSpecialExam($supplyExamRegId)
    {
        $sql = '';
        $supplyExamRegId = $this->realEscapeObject($supplyExamRegId);
        $isSpecialExam = null;
        try {
            $sql = "SELECT isSpecialExam AS isSpecialExam,considerFlag AS considerFlag FROM exam_supplementary WHERE id = $supplyExamRegId";
            $isSpecialExam = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $isSpecialExam;
    }
    /**
     *
     * @param int $supplyExamRegId
     * @param int $supplyExamId
     * @param int $studentId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function checkThisStudentHasSpecialExam($supplyExamRegId, $supplyExamId, $studentId)
    {
        $supplyExamRegId = $this->realEscapeObject($supplyExamRegId);
        $supplyExamId = $this->realEscapeObject($supplyExamId);
        $studentId = $this->realEscapeObject($studentId);
        $sql = '';
        $studentSpecialExamPresent = null;
        try {
            $sql = "SELECT studentaccount_id AS studentId,regularExamId AS regularExamId FROM student_reverted_special_exam_mark_details WHERE special_exam_id = $supplyExamRegId AND supplyExamId = $supplyExamId AND studentaccount_id = $studentId";
            $studentSpecialExamPresent = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentSpecialExamPresent;
    }
    /**
     * Get exam registration details
     * @param int $examRegId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamRegistrationDetails($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $sql = "SELECT examregID, examregName, examregDesc, enable_hlticket, examDate, lastAPC, regStartDate, rgstnWithoutFine, examMonth, examYear, min_att_percent, attClosingDate, shortCourse, simage, pimage, concat(examYear,'-', examMonth,'-','01') as examdate from exam_registration where examregID = " . $examRegId . "";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Check if the student present re admission
     * @param unknown $studentId
     * @param unknown $semId
     * @return unknown
     * @throws ProfessionalException
     */
    public function checkStudentPresentReAdmission($studentId, $semId)
    {
        $sql = '';
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $studentPresent = null;
        try {
            $sql = "SELECT studentaccount_id AS studentId FROM tokenRegistrationReAdmission WHERE semesters_id = $semId AND studentaccount_id = $studentId";
            $studentPresent = $this->executeQueryForObject($sql)->studentId;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentPresent;
    }
    /**
     * Get readmission details
     * @param unknown $studentId
     * @param unknown $semId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function reAdmissionDetails($studentId, $semId)
    {
        $sql = '';
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $reAdmissionDetails = null;
        try {
            $sql = "SELECT exam_registration_id AS examRegId, batches_id AS batchId FROM tokenRegistrationReAdmission WHERE semesters_id = $semId AND studentaccount_id = $studentId";
            $reAdmissionDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $reAdmissionDetails;
    }
//    /**
//     * Get exam subject details
//     * @param unknown $semId
//     * @param unknown $batchId
//     * @param unknown $examRegId
//     * @return object|array|\com\linways\base\util\$objectList[]
//     * @throws ProfessionalException
//     */
//    public function getExamSubjectDetails($semId, $batchId, $examRegId)
//    {
//        $sql = '';
//        $semId = $this->realEscapeString($semId);
//        $batchId = $this->realEscapeString($batchId);
//        $examRegId = $this->realEscapeString($examRegId);
//
//        $examSubjectDetails = [];
//
//        try {
//            $sql = "SELECT examID,subjectID FROM exam WHERE semID = $semId AND batchID = $batchId AND examregID = $examRegId";
//            $examSubjectDetails = $this->executeQueryForList($sql);
//
//        } catch (\Exception $e) {
//            throw new ProfessionalException($e->getCode(), $e->getMessage());
//        }
//
//        return $examSubjectDetails;
//    }
    /**
     * Get exam supplimentary details
     * @param unknown $examRegId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamSupplementaryDetails($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $sql = "SELECT supplyDesc, examDate, startDate, endDate, subjectLimit, semID, valuation_startDate, valuation_endDate, patternID, enable_hlticket, publishFromDate, publishToDate, examMonth, examYear, pimage, simage, isSpecialExam, considerFlag, concat(examYear,'-', examMonth,'-','01') as examdate, supplyDescription FROM exam_supplementary WHERE id = " . $examRegId . "";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Method for checking whether supply exam defined is special exam or not
     *
     * @param int $supplyExamId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function isSpecialExam($supplyExamId)
    {
        $sql = '';
        $supplyExamId = $this->realEscapeString($supplyExamId);
        $isSpecialExam = null;
        try {
            $sql = "SELECT es.isSpecialExam as specialExam FROM exam_supplementary es WHERE es.id = $supplyExamId";
            $isSpecialExam = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $isSpecialExam;
    }
    /**
     * Method for getting supply registrations for a supply Id
     *
     * @param unknown $supplyExamId
     * @return unknown
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getsupplyExamDetails($supplyExamId)
    {
        $sql = '';
        $supplyExamId = $this->realEscapeString($supplyExamId);
        $getsupplyExamDetails = null;
        $sql = "SELECT es.id as supplyExamId, es.supplyDesc as supplyDesc, publishFromDate, publishToDate FROM exam_supplementary es WHERE es.id = $supplyExamId";
        try {
            $getsupplyExamDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $getsupplyExamDetails;
    }
    /**
     * Method for checking whether this student is assigned for a particular batch and exam for special exam
     *
     * @param unknown $suppExamId
     * @param unknown $batchId
     * @param unknown $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function checkThisStudentAssignedForSpecialExam($suppExamId, $batchId, $studentId)
    {
        $sql = '';
        $thisStudentAssignedOrNot = null;
        $suppExamId = $this->realEscapeString($suppExamId);
        $batchId = $this->realEscapeString($batchId);
        $studentId = $this->realEscapeString($studentId);
        try {
            $sql = "SELECT seas.studentaccount_id as studentId FROM special_exam_assigned_students seas WHERE seas.batches_id = $batchId AND seas.exam_supplementary_id = $suppExamId AND seas.studentaccount_id = $studentId";
            $thisStudentAssignedOrNot = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $thisStudentAssignedOrNot;
    }
    /**
     * Method for getting regular examId corresponding to selected supplyExamRegId
     *
     * @param unknown $suppExamId
     * @param unknown $studentId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getRegularExamIdForSuppExam($suppExamId, $studentId)
    {
        $sql = '';
        $regExamId = [];
        $suppExamId = $this->realEscapeString($suppExamId);
        $studentId = $this->realEscapeString($studentId);
        try {
            $sql = "SELECT exam_registration_id,exam_id FROM special_exam_assigned_students WHERE exam_supplementary_id = $suppExamId AND studentaccount_id = $studentId";
            $regExamId = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $regExamId;
    }
    /**
     * Method for getting subjectId
     *
     * @param unknown $examId
     * @param unknown $batchId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSubjectId($examId, $batchId)
    {
        $sql = '';
        $subjectId = null;
        $examId = $this->realEscapeString($examId);
        $batchId = $this->realEscapeString($batchId);
        try {
            $sql = "SELECT e.subjectID as subjectId FROM exam e WHERE e.examID = $examId AND e.batchID = $batchId";
            $subjectId = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectId;
    }
    /**
     * Method for getting fee details
     *
     * @param unknown $supplyExamId
     * @param unknown $examId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getFeeDetails($supplyExamId, $examId)
    {
        $sql = '';
        $feeDetails = [];
        $supplyExamId = $this->realEscapeString($supplyExamId);
        $examId = $this->realEscapeString($examId);
        try {
            $sql = "SELECT t1.examfeesID, t1.supply_subject_amount, t1.improve_subject_amount FROM supply_improve_subject_fees t1 INNER JOIN exam_feestype t2 ON t2.examfeesID = t1.examfeesID WHERE t2.everySubject = 1 AND exam_supplementary_id = $supplyExamId AND examID = $examId";
            $feeDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $feeDetails;
    }
    /**
     * Method for getting exam fees head name
     *
     * @param unknown $examFeesId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getExamFeesHead($examFeesId)
    {
        $sql = '';
        $examFeesHead = null;
        $examFeesId = $this->realEscapeString($examFeesId);
        try {
            $sql = "SELECT ef.examfeesName as examFeeName FROM exam_feestype ef WHERE ef.examfeesID = $examFeesId";
            $examFeesHead = $this->executeQueryForObject($sql)->examFeeName;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examFeesHead;
    }
    /**
     * Get exam semId for batch
     * @param int $examId
     * @param int $batchId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getSemIdForExamId($examId, $batchId)
    {
        $examId = $this->realEscapeString($examId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT erb.semID FROM exam_registration_batches erb INNER JOIN exam e ON e.examregID = erb.examregID AND e.batchID = erb.batchID AND e.semID = erb.semID WHERE e.examID = $examId AND erb.batchID = $batchId";
        try {
            return $this->executeQueryForObject($sql)->semID;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Method for getting common fees for an exam
     * @param int $examSuppId
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getCommonFees($examSuppId)
    {
        $sql = '';
        $commonFees = [];
        $examSuppId = $this->realEscapeObject($examSuppId);
        try {
            $sql = "SELECT DISTINCT t1.examfeesID AS examFeeId,t1.supply_subject_amount AS supplyAmount FROM supply_improve_subject_fees t1, exam_feestype t2 WHERE t1.examfeesID = t2.examfeesID and  t1.exam_supplementary_id = $examSuppId and t2.everySubject = 0";
            $commonFees = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $commonFees;
    }
    public function getTotalFeesForAnExam($supplyExamId, $examIds)
    {
        $sql = '';
        $totalFees = null;
        $supplyExamId = $this->realEscapeString($supplyExamId);
        $examIds = $this->realEscapeString($examIds);
        try {
            $sql = "SELECT sum(sisf.supply_subject_amount) as totalFees FROM supply_improve_exam_fees sief INNER JOIN supply_improve_subject_fees sisf ON sief.exam_supplementary_id = sisf.exam_supplementary_id AND sief.examfeesID = sisf.examfeesID INNER JOIN exam_feestype ef ON ef.examfeesID = sief.examfeesID WHERE sief.exam_supplementary_id = $supplyExamId AND sisf.examID IN ($examIds) AND ef.everySubject = 1";
            $totalFees = $this->executeQueryForObject($sql)->totalFees;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $totalFees;
    }
    /**
     * Method for validating total fees of revaluation while applying
     * @input fee_id array , total_fees, reval Id
     *
     * @author Kishan Suresh
     *         output : false if not equal and true if the total fees is equal to calculated fees
     */
    public function validateRevaluationFees($totalFees, $feeIdArr, $revalId)
    {
        $sql = '';
        $totalFees = $this->realEscapeString($totalFees);
        $revalId = $this->realEscapeString($revalId);
        $totalFeesCalculated = 0;
        foreach ($feeIdArr as $examId => $feeId) {
            $fee = null;
            $sql = "select id, exam_fees_amount, exam_fees_name, isCommon from exam_revaluation_fees where exam_revaluation_id = " . $revalId . " and id = '$feeId'";
            try {
                $fee = $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            $totalFeesCalculated = $totalFeesCalculated + $fee->exam_fees_amount;
        }
        $commonFeesAmt = ExamService::getInstance()->calculateCommonFees($revalId);
        $totalFeesCalculated = $totalFeesCalculated + $commonFeesAmt->totalCommonFee;
        if ($totalFees == $totalFeesCalculated) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * Method for calculating common fee amount
     * @input revalId
     *
     * @author Kishan Suresh
     *         output : totalCommonFeeAmt
     */
    public function calculateCommonFees($revalId)
    {
        $commonFeeAmt = null;
        $sql = null;
        $sql = "SELECT sum(exam_fees_amount) as totalCommonFee from exam_revaluation_fees where isCommon = 1 and exam_revaluation_id = '$revalId'";
        try {
            $commonFeeAmt = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $commonFeeAmt;
    }
    public function getInstructions($examRegID, $notificationType)
    {
        $examRegID = $this->realEscapeString($examRegID);
        $notificationType = $this->realEscapeString($notificationType);
        $query = "SELECT * FROM exam_notification";
        if ($notificationType == "1") {
            $query .= " WHERE examRegId='$examRegID'";
        } else if ($notificationType == "2") {
            $query .= " WHERE examSupplyId='$examRegID'";
        } else if ($notificationType == "3") {
            $query .= " WHERE examRevalId='$examRegID'";
        }
        try {
            $response = $this->executeQueryForObject($query);
            return $response;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Method for getting max grade point
     *
     * @param unknown $courseTypeId
     * @return unknown
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getMaxGradePoint($courseTypeId)
    {
        $sql = '';
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $maxGP = null;
        try {
            $sql = "SELECT MAX(egp.percentTo) as maxGP FROM exam_gradepoints egp INNER JOIN exam_gradingscheme egs ON egs.schemeID = egp.schemeID WHERE egs.courseTypeID = $courseTypeId";
            $maxGP = $this->executeQueryForObject($sql)->maxGP;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $maxGP;
    }
    /**
     * Method for getting student last attended exam
     * @param int $studentId
     * @return array
     * @throws ProfessionalException
     * @author Ranjith Balachandran
     */
    public function getStudentLastAttendedExam($studentId,$batchId = NULL)
    {
        $sql = '';
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $studentDetails = null;
        try {
            if($studentId){
                $sql = "SELECT DISTINCT t2.examregID AS examRegId,t2.semID AS semId,t5.examMonth AS examMonth,t5.examYear AS examYear ,t5.examregName as examName,t5.examregDesc as examDesc,DATE_FORMAT(concat(t5.examYear,'-',t5.examMonth,'-01'), '%Y-%m-%d') as examDate
                    FROM exam_reg_studentchallan t1,exam_registration_batches t2, exam_registration t5,studentaccount t6
                    WHERE t6.studentID = '$studentId' AND t1.examregID = t2.examregID AND t1.studentID = t6.studentID
                    AND t2.semID = (SELECT DISTINCT MAX(t4.semID) FROM exam_reg_studentchallan t3,exam_registration_batches t4,exam_registration t8,studentaccount t7 WHERE t7.studentID = '$studentId' AND t7.studentID = t3.studentID AND t3.examregID = t4.examregID AND t3.examregID = t8.examregID AND t8.shortCourse = 0) AND t1.examregID = t5.examregID AND t5.shortCourse = 0";
            }
            else{
                $sql = "SELECT DISTINCT erb.examregID AS examRegId,erb.semID AS semId,er.examMonth AS examMonth,er.examYear AS examYear ,er.examregName as examName,er.examregDesc as examDesc,DATE_FORMAT(concat(er.examYear,'-',er.examMonth,'-01'), '%Y-%m-%d') as examDate
                    FROM exam_registration_batches erb INNER JOIN exam_registration er ON er.examregID = erb.examregID INNER JOIN batches bth ON bth.final_semester = erb.semID and bth.batchID = erb.batchID WHERE bth.batchID = $batchId";
            }
            $studentDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     *  Get sessional marks settings
     * @param int $examTypeId
     * @param int $batchId
     * @param int $semId
     * @param int $subjectId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSessionMarkSettings($examTypeId, $batchId, $semId, $subjectId)
    {
        $examTypeId = $this->realEscapeString($examTypeId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "select fromDate, toDate from sessional_marks_settings where examTypeID=" . $examTypeId . " and batchID=" . $batchId . " and subjectID=" . $subjectId . " and semId = " . $semId . "";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Is sessional exam mark submitted
     * @param int $examId
     * @return boolean
     * @throws ProfessionalException
     */
    public function isSessionalExamMarkSubmitted($examId,$subBatchId = null)
    {
        $examId = $this->realEscapeString($examId);
        $sql = "SELECT isAproved FROM aprove_exam_marks WHERE examID = " . $examId . "";
        if($subBatchId){
            $sql .= " AND subbatchID in (null,'$subBatchId') ";
        }
        try {
            $confirmed = $this->executeQueryForObject($sql)->isAproved;
            if ($confirmed) {
                return true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return false;
    }
    /**
     * Method to check whether normalized mark of normal subject is approved or not
     *
     * @author Ranjith Balachandran
     */
    public function normalizedMarkApproveStatus($subjectId, $batchId)
    {
        $subjectId = $this->realEscapeString($subjectId);
        $batchId = $this->realEscapeString($batchId);
        $normalizedMarkApproveStatus = null;
        $sql = "SELECT anm.isAproved as isAproved FROM aprove_normalise_mark anm WHERE anm.subjectID = $subjectId AND anm.batchID = $batchId";
        try {
            $normalizedMarkApproveStatus = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $normalizedMarkApproveStatus;
    }
    /**
     * Method to check whether normalized mark of pseudosubject is approved or not
     *
     * @author Ranjith Balachandran
     */
    public function normalizedMarkApproveStatusPseudo($subjectId)
    {
        $subjectId = $this->realEscapeString($subjectId);
        $normalizedMarkApproveStatus = null;
        $sql = "SELECT anm.isAproved as isAproved FROM aprove_normalise_mark anm WHERE anm.pseudosubjectID = $subjectId";
        try {
            $normalizedMarkApproveStatus = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $normalizedMarkApproveStatus;
    }
    /**
     * Get exam details by exam date
     * @param int $examDate
     * @param int $batchId
     * @param int $deptId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsByExamDate($examDate, $deptId = '', $batchId = '')
    {
        $batchId = $this->realEscapeString($batchId);
        $deptId = $this->realEscapeString($deptId);
        $examDate = $this->realEscapeString($examDate);
        $examDate = $examDate ? date('Y-m-d', strtotime($examDate)) : null;
        $sql = "SELECT bt.batchID, exm.examID, exm.examName, exm.examDate, bt.batchName, et.typeName, exm.subbatchID, if(exm.subbatchID=0, 'All', subb.subbatchName) AS subbatchName, exm.subjectID, exm.semID  FROM exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID INNER JOIN batches bt ON bt.batchID=exm.batchID AND bt.semID=exm.semID LEFT JOIN subbatches subb ON exm.subbatchID=subb.subbatchID WHERE exm.examDate='$examDate";
        if ($batchId) {
            $sql .= "AND exm.batchID=$batchId ";
        }
        if ($deptId) {
            $sql .= "AND bt.deptID=$deptId ";
        }
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Method to get subject List of student appeared in exam
     * @param unknown $batchId
     * @param unknown $semId
     * @param unknown $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSubjectListExam($batchId, $semId, $studentId)
    {
        $examDetails = null;
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $studentId = $this->realEscapeString($studentId);
        $sql = "SELECT t1.examName,t1.examID, t1.subjectID,t2.marksObtained,t1.examTotalMarks,t2.examTypeID FROM exam t1, student_marks t2 WHERE t1.batchID = t2.batchID AND t1.semID = t2.semID AND t1.examID = t2.examID AND t1.batchID= $batchId AND t1.semID = $semId AND t2.studentID = $studentId";
        try {
            $examDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
    /**
     * @author Vishnu M
     */
    public function getAllRegisteredSupplyExams($showFutureExamsOnly = FALSE)
    {
        $sql = "SELECT id, supplyDesc as name, semID AS semId FROM exam_supplementary";
        if ($showFutureExamsOnly) {
            $month = (int)date("m");
            $year = (int)date("Y") - 1;
            $sql .= " WHERE examMonth >= " . $month . " AND examYear >= " . $year;
        }
        $sql .= " ORDER BY examYear DESC";
        try {
            $supply = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supply;
    }
    /**
     * @author Vishnu M
     */
    public function getAllRegisteredRegularExams($showFutureExamsOnly = FALSE)
    {
        $sql = "SELECT examregID AS id, examregName AS name,examMonth,examYear FROM exam_registration ";
        if ($showFutureExamsOnly) {
            $month = (int)date("m");
            $year = (int)date("Y") - 1;
            $sql .= " WHERE examYear >= $year";
        }
        $sql .= " ORDER BY examregID DESC";
        try {
            $regExam = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $regExam;
    }
    /**
     * @author Vishnu M
     */
    public function getSubjectListSupplyByBatch($examSuppId, $batchId)
    {
        $examSuppId = $this->realEscapeString($examSuppId);
        $batchId = $this->realEscapeString($batchId);
        $subjectDetails = null;
        $sql = "SELECT s.subjectID, s.subjectName, s.subjectDesc  FROM supply_improve_subject_fees sisf INNER JOIN exam e ON (e.examID = sisf.examID) INNER JOIN subjects s ON (e.subjectID = s.subjectID)  WHERE sisf.exam_supplementary_id = '$examSuppId' AND e.batchID = '$batchId' ORDER BY s.subjectName ASC ";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    /**
     * @author Vishnu M
     */
    public function getSubjectListRegularByBatch($examRegId, $batchId)
    {
        $examRegId = (int)$this->realEscapeString($examRegId);
        $batchId = (int)$this->realEscapeString($batchId);
        $subjectDetails = null;
        $sql = "SELECT s.subjectID, s.subjectName, s.subjectDesc FROM exam_registration_subject_fees ersf INNER JOIN subjects s ON (s.subjectID = ersf.subjectID) INNER JOIN batches b ON (ersf.batchID = b.batchID) WHERE ersf.batchID = '$batchId' AND ersf.examregID = '$examRegId' ORDER BY s.subjectName ASC";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    /**
     * @author Vishnu M
     */
    public function getAllStudentRegBlockReason($reasonType = NULL)
    {
        $reasonType = $this->realEscapeString($reasonType);
        $condition = null;
        if ($reasonType) {
            $condition .= " AND reason_type = '$reasonType";
        }
        $sql = "SELECT id, reason FROM exam_reg_block_reason WHERE reason IS NOT NULL $condition ORDER BY id ASC";
        try {
            $reasons = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $reasons;
    }
    /**
     * @author Vishnu M
     */
    public function blockStudentFromExamRegistrationSubjectWise($studentId, $examregId, $subjectId, $reasonId, $isSupply)
    {
        global $COLLEGE_CODE;
        $studentId = (int)$this->realEscapeString($studentId);
        $examregId = (int)$this->realEscapeString($examregId);
        $subjectId = (int)$this->realEscapeString($subjectId);
        $reasonId = (int)$this->realEscapeString($reasonId);
        $isSupply = (int)$this->realEscapeString($isSupply);
        if ($isSupply === 0) { //Regular Exam
            $examreg_id = $examregId;
            $supplyreg_id = 'NULL';
        } else if ($isSupply === 1) {
            $supplyreg_id = $examregId;
            $examreg_id = 'NULL';
        }
        $response = null;
        $reasonType = "SUBJECT_WISE";
        $condition = $isSupply ? " AND erbs.supplyreg_id = '$examregId" : " AND erbs.examreg_id = '$examregId";
        if ($reasonId === 0) {
            $sql = "DELETE erbs.* FROM exam_reg_blocked_student erbs INNER JOIN exam_reg_block_reason erbr ON (erbr.id = erbs.reason_id) WHERE erbs.student_id = '$studentId' AND erbs.subject_id = '$subjectId' AND erbr.reason_type = '$reasonType$condition ";
        } else {
            $sql_check = "SELECT erbs.id FROM exam_reg_blocked_student erbs INNER JOIN exam_reg_block_reason erbr ON (erbs.reason_id = erbr.id) WHERE erbs.student_id = $studentId AND erbs.subject_id = $subjectId AND erbr.reason_type = '$reasonType$condition ";
            $id = $this->executeQueryForObject($sql_check)->id;
            if ($id) {
                $sql = "UPDATE exam_reg_blocked_student SET reason_id = $reasonId WHERE id = $id ";
            } else {
                $sql = "INSERT INTO exam_reg_blocked_student (student_id, subject_id, examreg_id, supplyreg_id, reason_id) VALUES ('$studentId', '$subjectId', $examreg_id$supplyreg_id, '$reasonId') ON DUPLICATE KEY UPDATE reason_id = VALUES(reason_id)";
            }
        }
        try {
            $response = $this->executeQuery($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        if ($COLLEGE_CODE != "SJCC" && $COLLEGE_CODE != "SJC") {
            // check if student has one or more entries in exam block student table for an exam registration
            try {
                $getAllSubjects = ExamService::getInstance()->getAllStudentBlockedAndUnblockedSubjects($studentId, $examregId, $isSupply);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            if (count($getAllSubjects) <= 1) {
                if ($isSupply == 0) {
                    $sql = "UPDATE exam_reg_studentchallan SET paid = 1 WHERE examregID = $examregId AND studentID = $studentId";
                } elseif ($isSupply == 1) {
                    $sql = "UPDATE exam_supplementary_student_details SET paid = 1 , approved = 1 WHERE exam_supplementary_id = $examregId AND studentID = $studentId";
                }
                $this->executeQuery($sql);
            } else {
                if ($isSupply == 0) {
                    $sql = "UPDATE exam_reg_studentchallan SET paid = 0 WHERE examregID = $examregId AND studentID = $studentId";
                } elseif ($isSupply == 1) {
                    $sql = "UPDATE exam_supplementary_student_details SET paid = 0 , approved = 0 WHERE exam_supplementary_id = $examregId AND studentID = $studentId";
                }
                $this->executeQuery($sql);
            }
        }
        return $response;
    }
    /**
     * @author Vishnu M
     */
    public function getSupplyExamIdByRegularExamId($regularExamId, $supplyRegId, $batchId)
    {
        $regularExamId = (int)$this->realEscapeString($regularExamId);
        $supplyRegId = (int)$this->realEscapeString($supplyRegId);
        $batchId = (int)$this->realEscapeString($batchId);
        $examId = null;
        $sql = "SELECT t2.examID FROM exam t1 INNER JOIN exam t2 ON (t1.subjectID = t2.subjectID) WHERE t1.examID = '$regularExamId' AND t2.batchID = '$batchId' AND t2.supply_examreg_id = '$supplyRegId'";
        try {
            $exam = $this->executeQueryForObject($sql);
            $examId = $exam->examID;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examId;
    }
    /**
     * @author Vishnu M
     */
    public function getSupplyExamIdBySubjectId($subjectId, $supplyRegId, $batchId)
    {
        $subjectId = (int)$this->realEscapeString($subjectId);
        $supplyRegId = (int)$this->realEscapeString($supplyRegId);
        $batchId = (int)$this->realEscapeString($batchId);
        $examId = null;
        $sql = "SELECT examID FROM exam WHERE subjectID = $subjectId AND batchID = '$batchId' AND supply_examreg_id = '$supplyRegId'";
        try {
            $exam = $this->executeQueryForObject($sql);
            $examId = $exam->examID;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examId;
    }
    /**
     * @author Vishnu M
     */
    public function getStudentExamRegBlockedStatus($studentId, $examregId, $subjectId, $isSupply)
    {
        $studentId = (int)$this->realEscapeString($studentId);
        $examregId = (int)$this->realEscapeString($examregId);
        $subjectId = (int)$this->realEscapeString($subjectId);
        $isSupply = (int)$this->realEscapeString($isSupply);
        $condition = null;
        if ($isSupply == 1) {
            $condition = " AND erbs.supplyreg_id = '$examregId";
        } else {
            $condition = " AND erbs.examreg_id = '$examregId";
        }
        $blockStatus = null;
        $sql = "SELECT erbr.id, erbr.reason, erbr.contact_person_id, erbr.reason_type,sa.staffName FROM exam_reg_blocked_student erbs
                INNER JOIN exam_reg_block_reason erbr ON (erbs.reason_id = erbr.id)
                LEFT JOIN staffaccounts sa ON sa.staffID = erbr.contact_person_id
                WHERE erbs.student_id = '$studentId' AND erbs.subject_id = '$subjectId$condition ORDER BY FIELD(erbr.reason_type, 'SUBJECT_WISE') DESC";
        try {
            $blockStatus = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $blockStatus;
    }
    /**
     * Undocumented function
     *
     * @param [type] $batchID
     * @param [type] $semID
     * @param [type] $typeID
     * @param [type] $subjectID
     * @param [type] $subbatchID
     * @return void
     */
    public function checkIfExamExistsAndGetErrorMessage($batchID, $semID, $typeID, $subjectID, $subbatchID, $examID = NULL)
    {
        $batchID = $this->realEscapeString($batchID);
        $semID = $this->realEscapeString($semID);
        $typeID = $this->realEscapeString($typeID);
        $subjectID = $this->realEscapeString($subjectID);
        $subbatchID = $this->realEscapeString($subbatchID);
        $examID = $this->realEscapeString($examID);
        //if the operation is for updation
        if (!empty($examID)) {
            $sql = "select examID from exam where  batchID=\"$batchID\" and semID=\"$semID\" and examTypeID=\"$typeID\" and subjectID = \"$subjectID\";";
            try {
                $examCount = sizeof($this->executeQueryForList($sql));
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            if ($examCount <= 1) {
                return null;
            }
            $examDetails = $this->getExamDetailsByExamId($examID);
            if ($examDetails->subbatchID == $subbatchID) {
                return null;
            }
        }
        $errorMessageForDuplicateEntry = NULL;
        //this is the case when all batch is selected
        if ($subbatchID == 0) {
            $sql = "select examID, created_by as createdBy from exam where  batchID=\"$batchID\" and semID=\"$semID\" and examTypeID=\"$typeID\" and subjectID = \"$subjectID\" and subbatchID = 0";
            try {
                $examObject = $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            if (!empty($examObject)) {
                $errorMessageForDuplicateEntry = "Exam Already Created For All Batch";
                if ($examObject->createdBy == 0) {
                    $errorMessageForDuplicateEntry .= " By Admin";
                }
            } else {
                $examObject = NULL;
                $sql = "select examID, created_by as createdBy from exam where  batchID=\"$batchID\" and semID=\"$semID\" and examTypeID=\"$typeID\" and subjectID = \"$subjectID\" and subbatchID != 0";
                try {
                    $examObject = $this->executeQueryForObject($sql);
                } catch (\Exception $e) {
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
                if (!empty($examObject)) {
                    $errorMessageForDuplicateEntry = "Exam Already Created For Sub Batches";
                    if ($examObject->createdBy == 0) {
                        $errorMessageForDuplicateEntry .= " By Admin";
                    }
                }
            }
        } else {
            $sql = "select examID, created_by as createdBy from exam where  batchID=\"$batchID\" and semID=\"$semID\" and examTypeID=\"$typeID\" and subjectID = \"$subjectID\" and subbatchID = 0";
            try {
                $examObject = $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            if (!empty($examObject)) {
                $errorMessageForDuplicateEntry = "Exam Already Created For All Batch";
                if ($examObject->createdBy == 0) {
                    $errorMessageForDuplicateEntry .= " By Admin";
                }
            } else {
                $examObject = NULL;
                $sql = "select examID, created_by as createdBy from exam where  batchID=\"$batchID\" and semID=\"$semID\" and examTypeID=\"$typeID\" and subjectID = \"$subjectID\" and subbatchID = $subbatchID";
                try {
                    $examObject = $this->executeQueryForObject($sql);
                } catch (\Exception $e) {
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
                if (!empty($examObject)) {
                    $errorMessageForDuplicateEntry = "Exam Already Created For This SubBatch";
                    if ($examObject->createdBy == 0) {
                        $errorMessageForDuplicateEntry .= " By Admin";
                    }
                }
            }
        }
        return $errorMessageForDuplicateEntry;
    }
    public function getAllExamsOfABatch($batchId, $semId, $examTypeId, $subjectId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $sql = "SELECT examID as id, examTotalMarks as totalMarks,examName as name FROM exam WHERE examTypeID = '$examTypeId' AND semID = '$semId' AND batchID = '$batchId' AND subjectID = '$subjectId'";
        try {
            $examList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examList;
    }
    public function getExamMarksOfAStudent($studentId, $batchId, $semId, $subjectId, $examId, $examTypeId)
    {
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examId = $this->realEscapeString($examId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $sql = "select marksObtained from student_marks WHERE batchID =$batchId  AND semID=$semId AND examID =$examId AND examTypeID=$examTypeId AND subjectID = $subjectId AND studentID = $studentId  ";
        try {
            return $this->executeQueryForObject($sql)->marksObtained;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Undocumented function
     *
     * @param [type] $batchID
     * @param [type] $semID
     * @param [type] $subjectId
     * @param [type] $examTypeID
     * @return void
     */
    public function getCombinedCoAndMarkReport($batchID, $semID, $examTypeID, $subjectId = null, $subBatchID)
    {
        $batchID = $this->realEscapeString($batchID);
        $semID = $this->realEscapeString($semID);
        $subjectID = $this->realEscapeString($subjectId);
        $examTypeID = $this->realEscapeString($examTypeID);
        $subBatchID = $this->realEscapeString($subBatchID);
        $sortByColumn = "rollNo";
        if (empty($examTypeID)) {
            return null;
        }
        try {
            $studentList = StudentService::getInstance()->getAllStudentsOfABatchByBatchIdSemIdAndSubbatchId($batchID, $semID, $subBatchID, $sortByColumn);
        } catch (\Exception $e) {
            $studentList = null;
        }
        if (empty($studentList)) {
            return null;
        }
        foreach ($studentList as $student) {
            $studentID = $student->studentID;
            $studentName = $student->studentName;
            $rollNo = $student->rollNo;
            $condition = $examTypeID ? " and t2.examTypeID = \"" . $examTypeID . "\"" : "";
            $sql_type = "SELECT t1.assessment_id as examID from assessment_student_marks t1,exam t2 WHERE t1.assessment_id = t2.examID
            AND t1.assessment_type = 'EXAM' AND t1.studentID = \"" . $studentID . "\" AND t2.subjectID = \"" . $subjectID . "\" " . $condition . " GROUP BY examID";
            $examIdList = $this->executeQueryForList($sql_type);
            $student->exams = [];
            foreach ($examIdList as $row_type) {
                $examID = $row_type->examID;
                $student->exams[$examID] = new \StdClass();
                $student->exams[$examID]->coList = [];
                $studentMarkList = NbaCoService::getInstance()->getCOReportOfInternalExam($examID, $studentID, $subjectID);
                $validStudentQuestionIds = NbaCoService::getInstance()->getSectionWiseValidQuestionIdsForCoCalculationOfAStudent($examID, $studentID);
                // $result_mark = sql_query($sql_mark, $connect);
                if (!empty($studentMarkList)) {
                    //Assumption that all marks have same question paper id
                    $questionPaperId = $studentMarkList[0]->id;
                    $totalCoPercentList = NbaCoService::getInstance()->calculateTotalCOPercents($validStudentQuestionIds->nbaCourseOutcomeQuestionsIdList, $questionPaperId);
                    foreach ($studentMarkList as $row_mark) {
                        $row_mark = (array)$row_mark;
                        if (!in_array($row_mark['assessment_structure_questions_id'], $validStudentQuestionIds->nbaCourseOutcomeQuestionPaperQuestionsIdList) || !in_array($row_mark['assessment_questions_id'], $validStudentQuestionIds->nbaCourseOutcomeQuestionsIdList)) {
                            continue;
                        }
                        $assessment_structure_questions_id = $row_mark['assessment_structure_questions_id'];
                        $mark_obtained = $row_mark['mark_obtained'];
                        $maxMark = $row_mark['mark'];
                        $assessment_questions_id = $row_mark['assessment_questions_id'];
                        $nba_course_outcome_id = $row_mark['nba_course_outcome_id'];
                        $course_outcome_value = $row_mark['course_outcome_value'];
                        $course_outcome_question_paper_id = $row_mark['id'];
                        $course_outcome_value = $course_outcome_value / 100;
                        //1.Take distinct sections
                        //2.Calculate Individual Section co total
                        $per_percent = $totalCoPercentList[$nba_course_outcome_id] / 100;
                        $percentage = ($mark_obtained / $maxMark) * ($course_outcome_value);
                        $exactValue = ($percentage / $per_percent) * 100;
                        $student->exams[$examID]->marksObtained = $this->getExamMarksOfAStudent($studentID, $batchID, $semID, $subjectID, $examID, $examTypeID);
                        $student->exams[$examID]->coList[$nba_course_outcome_id] += $exactValue;
                    }
                }
            }
            unset($values);
            unset($totalValue);
        }
        return $studentList;
    }
    /**
     * @param $examregId
     * @param int $isSupply
     * @param string $reportType
     * @return array|Object
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getAllStudentExamRegBlockedStatus($examregId, $isSupply = 0, $reportType = "SUBJECTWISE")
    {
        $examregId = (int)$this->realEscapeString($examregId);
        $isSupply = (int)$this->realEscapeString($isSupply);
        $studentBlockStatus = [];
        $condition = ($isSupply === 1) ? " erbs.supplyreg_id = '$examregId" : " erbs.examreg_id = '$examregId";
        $reasonConcat = "GROUP_CONCAT(CONCAT(erbr.id, ':', erbr.reason)) AS studentReasons, COUNT(s.subjectID) AS blockedSubjectCount, ";
        if ($reportType == "SUBJECTWISE") {
            $condition .= " GROUP BY erbs.student_id, erbs.subject_id, erbs.examreg_id, erbs.supplyreg_id ";
        } else if ($reportType == "BATCHWISE") {
            $condition .= " GROUP BY erbs.student_id, erbs.examreg_id, erbs.supplyreg_id  ";
        } else if ($reportType == "STUDENTWISE") {
            $reasonConcat = null;
        }
        $sql = "SELECT
                    sa.studentID,
                    sa.studentName,
                    sa.regNo,
                    s.subjectID,
                    s.subjectName,
                    s.subjectDesc,
                    erbr.id AS reasonId,
                    erbr.reason,
                    erbr.reason_type AS reasonType,
                    sta.staffName AS contactPerson,
                    erbr.reason,
                    $reasonConcat
                    b.batchID,
                    b.batchName,
                    pdc.patterncourseID,
                    pdc.patterncourseName
                FROM
                    exam_reg_blocked_student erbs
                        INNER JOIN
                    studentaccount sa ON (erbs.student_id = sa.studentID)
                        INNER JOIN
                    subjects s ON (s.subjectID = erbs.subject_id)
                        INNER JOIN
                    exam_reg_block_reason erbr ON (erbr.id = erbs.reason_id)
                        INNER JOIN
                    batches b ON (sa.batchID = b.batchID)
                        INNER JOIN
                    pattern_deptcourses pdc ON (pdc.patterncourseID = b.patterncourseID)
                        LEFT JOIN
                    staffaccounts sta ON (erbr.contact_person_id = sta.staffID)
                WHERE
                    $condition
                ORDER BY sa.regNo ASC , sa.batchID ASC, FIELD(erbr.reason_type, 'SUBJECT_WISE') DESC";
        try {
            $studentBlockStatus = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentBlockStatus;
    }
    /**
     * Get all subjects that student need to register for exam
     * @param Integer $studentID
     * @param Integer $batchID
     * @param Integer $examregID
     * @return Array Exam subject list
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getStudentExamSubjectsForRegistration($examregID, $batchID, $studentID = NULL)
    {
        $examregID = (int)$this->realEscapeString($examregID);
        $batchID = (int)$this->realEscapeString($batchID);
        $studentID = (int)$this->realEscapeString($studentID);
        $subjects = [];
        $studentCondition = null;
        if ($studentID) {
            $studentCondition = " AND sa.studentID = '$studentID";
        }
        $sql = "SELECT
                    sa.studentID, s.subjectID, s.subjectName, s.subjectDesc,ersf.examfeesAmount as examFees
                FROM
                    subjects s
                        INNER JOIN
                    sbs_relation sbs ON s.subjectID = sbs.subjectID
                        INNER JOIN
                    exam_registration_subject_fees ersf ON sbs.subjectID = ersf.subjectID
                        AND ersf.batchID = sbs.batchID
                        AND ersf.semID = sbs.semID
                        INNER JOIN
                    exam_registration_batches erb ON ersf.examregID = erb.examregID
                        AND ersf.batchID = erb.batchID
                        AND ersf.semID = erb.semID
                        INNER JOIN
                    studentaccount sa ON sa.batchID = erb.batchID
                WHERE
                    ersf.examregID = '$examregID'
                        AND ersf.batchID = '$batchID'
                        AND (
                                sbs.sbsID IN (
                                    SELECT
                                        psbs.sbsID
                                    FROM
                                        pseudosubjects_sbs psbs
                                            INNER JOIN
                                        pseudosubjects_students ps ON (ps.pseudosubjectID = psbs.pseudosubjectID)
                                    WHERE
                                        psbs.sbsID = sbs.sbsID
                                            AND ps.studentID = sa.studentID UNION SELECT
                                        ssbs.sbsID
                                    FROM
                                        subbatch_sbs ssbs
                                            INNER JOIN
                                        subbatch_student ss ON ssbs.subbatchID = ss.subbatchID
                                    WHERE
                                        ss.studentID = sa.studentID
                                            AND ssbs.sbsID = sbs.sbsID
                                )
                                OR sbs.sbsID NOT IN (
                                    SELECT
                                        sbsID
                                    FROM
                                        subbatch_sbs
                                ) AND sbs.isPseudosubject = 0
                            )
                        $studentCondition
                GROUP BY sa.studentID, sbs.subjectID";
        try {
            $subjects = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    /**
     * 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
     * @author Vishnu M
     */
    public function getStudentSupplySubjectsForRegistration($supplyregID, $batchID, $studentID = NULL, $currentStatus = TRUE, $isMarksCardRequest = FALSE,$considerHighestSupplymark = 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 );
        $oderByLatestSupplyMark = "";
        if($considerHighestSupplymark && count($studentIds) === 1){
            $considerHighestSupplymark = true;
            $oderByLatestSupplyMark = "ee2.mark DESC,";
        }
        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 = $this->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;
        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 || $batchCourseType == CourseTypeConstants::MBA || $batchCourseType == CourseTypeConstants::MCA || $batchCourseType == CourseTypeConstants::MTECH) {
                    $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 IN('$foundationCourse','$termPaper')";
                }
                $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,
                            e2.examID as supplyExamId
                        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 $oderByLatestSupplyMark 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 = $this->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) {
                            if($details->supplyExamId){
                                //START get supply exam int mark if exist
                                $supplyIntMarkRequest = new \stdClass();
                                $supplyIntMarkRequest->supplyExamId = $details->supplyExamId;
                                $supplyIntMarkRequest->studentId = $details->studentID;
                                $supplyIntMarkRequest->subjectId = $details->subjectID;
                                $studentSupplyInternalMark = ExamSupplementaryService::getInstance()->getStudentSupplyInternalMark($supplyIntMarkRequest)->marks;
                                $details->intMark = $studentSupplyInternalMark  ? $studentSupplyInternalMark  : $details->intMark;
                                //END get supply exam int mark if exist
                            }
                            $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) {
                                if($considerHighestSupplymark){
                                    $studentExternalMarks = ($details->extMark > $details->previousMarks) ? $details->extMark : $details->previousMarks;
                                }else{
                                    $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 exam subject credit by subjectId
     * @param Integer $subjectId
     * @param Integer $batchID
     * @return Object $examSubjectCredit
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getExamSubjectCreditBySubjectBatch($subjectId, $batchId)
    {
        $subjectId = (int)$this->realEscapeString($subjectId);
        $batchId = (int)$this->realEscapeString($batchId);
        $examSubjectCredit = null;
        $sql = "SELECT batchID, semID, subjectID, credit, isInternal, isExternal, hideGrade, excludeSubjectFromTotal, subjectType, subjectOrder FROM exam_subjectcredit WHERE subjectID = '$subjectId' AND batchID = '$batchId";
        try {
            $examSubjectCredit = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examSubjectCredit;
    }
    /**
     * Get exam subject credit by subjectId
     * @param Integer $supplyRegId
     * @param Integer $studentId
     * @return Object $examSubjectCredit
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getStudentSupplyExamMarkDetails($supplyRegId, $studentId)
    {
        $supplyRegId = (int)$this->realEscapeString($supplyRegId);
        $studentId = (int)$this->realEscapeString($studentId);
        $marksTable = null;
        $examSupplyDetails = null;
        $studentDetails = StudentService::getInstance()->getStudentDetailsById($studentId);
        $batchId = $studentDetails->batchID;
        $examSupplyDetails = ExamSupplementaryService::getInstance()->getExamSupplementaryById($supplyRegId);
        $batchId = $this->getStudentExamBatchBySemester ($studentId, $examSupplyDetails->semID);
        if ( empty ( $batchId ) ) {
            $batchId = $studentDetails->batchID;
        }
        $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchId);
        $batchCourseType = $batchDetails->course_Type;
        $marksTable = 'exammarks_external';
        if ($batchCourseType == CourseTypeConstants::UG) {
            $marksTable = 'exammarks_external';
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD) {
            $marksTable = 'externalexammarks_finalized';
        }
        $subjectDetails = [];
        $sql = "SELECT DISTINCT
                    sa.studentName,
                    sa.regNo,
                    sa.myImage,
                    b.batchID,
                    b.batchName,
                    b.batchDesc,
                    b.batchStartYear,
                    b.courseTypeID,
                    es.supplyDesc,
                    es.semID,
                    es.examMonth,
                    es.examYear,
                    s.subjectID,
                    s.subjectName,
                    s.subjectDesc,
                    s.syllabusName,
                    im.internalMarks,
                    ims.maxInternalMarks,
                    ee.mark AS externalMarks,
                    e.examTotalMarks AS maxExternalMarks,
                    ea.isAbsent,
                    esc.credit,
                    esc.isInternal,
                    esc.isExternal,
                    esc.hideGrade,
                    esc.excludeSubjectFromTotal,
                    esc.subjectType
                FROM
                    exam_supplementary es
                        INNER JOIN
                    exam_supplementary_student_subjects esss ON es.id = esss.exam_supplementary_id
                        INNER JOIN
                    studentaccount sa ON sa.studentID = esss.studentID
                    INNER JOIN
                    exam e_temp ON e_temp.examID = esss.examID
                        INNER JOIN
                    batches b ON b.batchID = e_temp.batchID
                        INNER JOIN
                    exam e ON e.batchID = e_temp.batchID
                        AND es.id = e.supply_examreg_id
                        AND e_temp.subjectID = e.subjectID
                        INNER JOIN
                    subjects s ON s.subjectID = e.subjectID
                        LEFT JOIN
                    internal_marks im ON im.studentID = sa.studentID
                        AND im.subjectID = e.subjectID
                        AND im.batchID = e.batchID
                        AND im.semID = es.semID
                        LEFT JOIN
                    internal_marks_settings ims ON ims.subjectID = e.subjectID
                        AND ims.batchID = e.batchID
                        AND ims.semID = es.semID
                        LEFT JOIN
                    $marksTable ee ON ee.studentID = sa.studentID
                        AND ee.examID = e.examID
                        LEFT JOIN
                    exam_attendance ea ON ea.studentID = sa.studentID
                        AND ea.examID = e.examID
                        INNER JOIN
                    exam_subjectcredit esc ON esc.subjectID = e.subjectID
                        AND esc.batchID = e.batchID
                        AND esc.semID = es.semID
                WHERE
                    es.id = '$supplyRegId' AND sa.studentID = '$studentId' AND e.batchID = $batchId
                ORDER BY esc.subjectOrder,s.subjectPriority ASC";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    public function getStudentFailedSubjectByExamregId($examregId, $batchId, $studentId = NULL)
    {
        $examregId = (int)$this->realEscapeString($examregId);
        $batchId = (int)$this->realEscapeString($batchId);
        $studentId = (int)$this->realEscapeString($studentId);
        $marksTable = null;
        $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchId);
        $batchCourseType = $batchDetails->course_Type;
        $batchStartYear = $batchDetails->batchStartYear;
        $marksTable = 'exammarks_external';
        if ($batchCourseType == CourseTypeConstants::UG) {
            $marksTable = 'exammarks_external';
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD) {
            $marksTable = 'externalexammarks_finalized';
        }
        if ($studentId) {
            $condition = " AND sa.studentID = '$studentId";
        }
        $sql = "SELECT
                    sa.studentID,
                    sa.regNo,
                    sa.studentName,
                    b.batchID,
                    b.batchName,
                    b.batchStartYear,
                    sem.semID,
                    sem.semName,
                    s.subjectID,
                    s.subjectName,
                    s.subjectDesc,
                    er.examregID,
                    er.examregName,
                    er.examMonth,
                    er.examYear,
                    e.examID,
                    e.examName,
                    esc.credit,
                    esc.isInternal,
                    IF ( esc.isInternal, im.internalMarks, 0 ) AS internalMark,
                    IF ( esc.isInternal, ims.maxInternalMarks, 0 ) AS maxInternalMark,
                    esc.isExternal,
                    IF ( esc.isExternal, ee.mark, 0 ) AS externalMark,
                    IF ( esc.isExternal, e.examTotalMarks, 0 ) AS maxExternalMark,
                    ea.isAbsent,
                    esc.excludeSubjectFromTotal,
                    esc.subjectType
                FROM
                    exam_subjectcredit esc
                        INNER JOIN
                    subjects s ON esc.subjectID = s.subjectID
                        INNER JOIN
                    semesters sem ON sem.semID = s.semID
                        LEFT JOIN
                    exam e ON e.subjectID = s.subjectID
                        AND e.batchID = esc.batchID
                        AND e.semID = esc.semID
                        INNER JOIN
                    exam_type et ON et.typeID = e.examTypeID
                        INNER JOIN
                    batches b ON b.batchID = e.batchID
                        INNER JOIN
                    exam_registration er ON er.examregID = e.examregID
                        INNER JOIN
                    exam_reg_studentsubject erss ON erss.subjectID = e.subjectID
                        AND erss.examregID = e.examregID
                        INNER JOIN
                    exam_reg_studentchallan ersc ON erss.examregID = ersc.examregID
                        AND erss.studentID = ersc.studentID
                        INNER JOIN
                    studentaccount sa ON sa.studentID = erss.studentID
                        AND sa.studentID = ersc.studentID
                        LEFT JOIN
                    $marksTable ee ON ee.examID = e.examID
                        AND sa.studentID = ee.studentID
                        LEFT JOIN
                    exam_attendance ea ON ea.examID = e.examID
                        AND ea.studentID = sa.studentID
                        LEFT JOIN
                    internal_marks im ON im.subjectID = e.subjectID
                        AND im.batchID = e.batchID
                        AND im.semID = e.semID
                        AND im.studentID = sa.studentID
                        LEFT JOIN
                    internal_marks_settings ims ON ims.subjectID = e.subjectID
                        AND ims.batchID = e.batchID
                        AND ims.semID = e.semID
                WHERE
                    e.examregID IS NOT NULL
                        AND ersc.paid = 1
                        AND sa.batchID = '$batchId'
                        AND er.examregID = '$examregId'
                    $condition
                ORDER BY sa.regNo , sem.semID , s.subjectPriority ASC";
        try {
            $regularExamSubjects = $this->executeQueryForList($sql);
            if (!empty ($regularExamSubjects)) {
                if ($batchStartYear <= 2014) {
                    $internalPassCriteria = (float)CommonService::getInstance()->getSettings("INTERNAL_EXAM_PASS_LIMIT", "INTERNAL_EXAM_PASS_LIMIT");
                }
                $externalPassCriteria = CommonService::getInstance()->getSettings("EXTERNAL_EXAM_PASS_LIMIT", "EXTERNAL_EXAM_PASS_LIMIT");
                $overallPassCriteria = CommonService::getInstance()->getSettings("OVERALL_EXAM_PASS_LIMIT", "OVERALL_EXAM_PASS_LIMIT");
                $batchStartYear = $regularExamSubjects[0]->batchStartYear;
                foreach ($regularExamSubjects as $examSubject) {
                    $failedStatus = 0;
                    if ($examSubject->isInternal == 1 && $internalPassCriteria && $batchStartYear <= 2014 && $examSubject->excludeSubjectFromTotal == 0) {
                        $internalPercentage = $examSubject->maxInternalMark ? (100 * $examSubject->internalMark / $examSubject->maxInternalMark) : 0;
                        $failedStatus = $internalPercentage < $internalPassCriteria ? 1 : $failedStatus;
                    }
                    if ($examSubject->isExternal == 1 && $externalPassCriteria && $examSubject->excludeSubjectFromTotal == 0) {
                        $externalPercentage = $examSubject->maxExternalMark ? (100 * $examSubject->externalMark / $examSubject->maxExternalMark) : 0;
                        $failedStatus = $externalPercentage < $externalPassCriteria ? 1 : $failedStatus;
                    }
                    if ($overallPassCriteria) {
                        $totalMark = $examSubject->internalMark + $examSubject->externalMark;
                        $maxTotalMark = $examSubject->maxInternalMark + $examSubject->maxExternalMark;
                        $overallPercentage = $maxTotalMark ? (100 * $totalMark / $maxTotalMark) : 0;
                        $failedStatus = $overallPercentage < $overallPassCriteria ? 1 : $failedStatus;
                    }
                    $examSubject->failedStatus = $failedStatus;
                    if ($failedStatus) {
                        $failedSubjects[$examSubject->subjectID] = $examSubject->subjectName;
                    }
                }
            }
            $response["markDetails"] = $regularExamSubjects;
            $response["failedSubjects"] = $failedSubjects;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    /**
     * Get supply exam marks by studentID and regular examID
     * @author Vishnu M
     */
    public function getSupplyMarksByStudentAndRegularExamId($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 || $batchCourseType == CourseTypeConstants::MPHIL || $batchCourseType == CourseTypeConstants::PHD) {
            $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'
                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 all student blocked & unblocked subjects list
     * @author Ranjith Balachandran
     */
    public function getAllStudentBlockedAndUnblockedSubjects($studentId, $examRegId, $isSupply)
    {
        $examRegId = (int)$this->realEscapeString($examRegId);
        $studentId = (int)$this->realEscapeString($studentId);
        $isSupply = (int)$this->realEscapeString($isSupply);
        $subjectDetails = [];
        $condition = null;
        if ($isSupply == 0) {
            $condition = "AND examreg_id = $examRegId";
        } elseif ($isSupply == 1) {
            $condition = "AND supplyreg_id = $examRegId";
        }
        $sql = "SELECT erbs.subject_id AS subjectId, erbr.id AS reasonId, erbr.reason FROM exam_reg_blocked_student erbs INNER JOIN exam_reg_block_reason erbr ON erbr.id = erbs.reason_id WHERE student_id = $studentId $condition";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    /**
     * copy exam hall seat arrangement form on group to other group
     * @param int $fromGroupId
     * @param int $toGroupId
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function copyExamHallSeatArrangement($fromGroupId, $toGroupId)
    {
        $fromGroupId = $this->realEscapeString($fromGroupId);
        $toGroupId = $this->realEscapeString($toGroupId);
        try {
            $sql_sit = "SELECT * FROM exam_classarrange_samebatchsiting WHERE groupID='$toGroupId'";
            $sitData = $this->executeQueryForObject($sql_sit);
            if (empty($sitData)) {
                $sql_sit_tog = "INSERT INTO exam_classarrange_samebatchsiting (groupID, sittogether, notSitTogetherAround) SELECT  '$toGroupId', sittogether, notSitTogetherAround FROM exam_classarrange_samebatchsiting where groupID='$fromGroupId'";
                $this->executeQuery($sql_sit_tog);
            }
            $arg_count_sql = "select count(groupID) as arrangementCount from exam_arrangement_count where groupID=$toGroupId";
            $count_arg = $this->executeQueryForObject($arg_count_sql)->arrangementCount;
            if ($count_arg) {
                $sql_arg = "update exam_arrangement_count set arrange_count=arrange_count+1 where groupID=\"$toGroupId\"";
            } else {
                $sql_arg = "insert into exam_arrangement_count(groupID, arrange_count, arrangetype) SELECT  '$toGroupId', 1, arrangetype FROM exam_arrangement_count WHERE groupID='$fromGroupId'";
            }
            $this->executeQuery($sql_arg);
            $sql_exam_cond = "select count(groupID) as exmCondCound from exam_classarrange_examwise_conditions where groupID=\"$fromGroupId\"";
            $cond_count = $this->executeQueryForObject($sql_exam_cond)->exmCondCound;
            if ($cond_count) {
                $sql_exam_cond = "select count(groupID) as exmCondCound from exam_classarrange_examwise_conditions where groupID=\"$toGroupId\"";
                $cond_count = $this->executeQueryForObject($sql_exam_cond)->exmCondCound;
                if (!$cond_count) {
                    $sql_exam = "INSERT INTO exam_classarrange_examwise_conditions (groupID, examIDs) select '$toGroupId', examIDs from exam_classarrange_examwise_conditions where groupID='$fromGroupId'";
                    $this->executeQuery($sql_exam);
                }
            }
            $sql_del = "DELETE FROM exam_hall_arranged_students WHERE groupID=$toGroupId";
            $this->executeQuery($sql_del);
            $sql = "INSERT INTO exam_hall_arranged_students(groupID, hallID, studentID, examID, seatNo, rowNo, columnNo, seat) SELECT '$toGroupId', hallID, studentID, examID, seatNo, rowNo, columnNo, seat FROM exam_hall_arranged_students WHERE groupID='$fromGroupId'";
            $this->executeQuery($sql);
            $update_examId = "UPDATE exam exm INNER JOIN studentaccount sa ON sa.batchID=exm.batchID INNER JOIN exam_group_exams ege ON ege.examID=exm.examID INNER JOIN exam_hall_arranged_students  eha ON eha.studentID=sa.studentID AND eha.groupID=ege.groupID SET eha.examID=exm.examID WHERE ege.groupID='$toGroupId'";
            return $this->executeQuery($update_examId);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Method check whether the pseudosubject is not approved in normalized mark
     *
     * @param int $subjectId
     * @return Boolean
     * @author Nandu
     */
    public function pseudoNormalizedMarkNotApproveStatus($subjectId)
    {
        $subjectId = $this->realEscapeString($subjectId);
        $normalizedMarkApproveStatus = null;
        $sql = "SELECT isAproved as isAproved FROM aprove_normalise_mark anm WHERE anm.pseudosubjectID = $subjectId";
        try {
            $normalizedMarkApproveStatus = $this->executeQueryForList($sql);
            if (count($normalizedMarkApproveStatus) === 0)
                return false;
            foreach ($normalizedMarkApproveStatus as $status) {
                if ($status->isAproved == 0)
                    return false;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get mark difference threshold value by courseTypeId
     * @param Integer $courseTypeId
     * @return Integer $markDiff
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getExternalValuationMarkDiff($courseTypeId)
    {
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $markDiff = null;
        try {
            $sql = "SELECT courseTypeID, markdiff AS markDiff FROM externalexam_thirdvalmarkdiff WHERE courseTypeID = '$courseTypeId";
            $markDiff = $this->executeQueryForObject($sql)->markDiff;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $markDiff;
    }
    /**
     * Get students exam mark External
     * @param Array $conditions
     */
    public function getStudentsExternalMarksByStudentExamDetail($conditions)
    {
        $sql = '';
        $conditions = $this->realEscapeArray($conditions);
        $studentExternalMark = [];
        try {
            $sql = "SELECT ee.studentID, ee.examID, ee.mark AS studentExternalMark, 1 AS valuationCount FROM exammarks_external ee WHERE " . implode(" OR ", $conditions) . "
            UNION
            SELECT ee.studentID, ee.examID, ee.mark AS studentExternalMark, valuationCount FROM external_exammarks ee WHERE " . implode(" OR ", $conditions);
            $studentExternalMark = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentExternalMark;
    }
    public function getMarkFailedCriteriaByBatchId($batchId)
    {
        $sql = '';
        $batchId = $this->realEscapeString($batchId);
        $markFailedCriteria = null;
        try {
            $sql = "SELECT mfc.typeID, mfc.internal_percentage, mfc.external_percentage, mfc.total_percentage FROM mark_failed_criteria mfc INNER JOIN university_assignbatchcourse uabc ON ( mfc.typeID = uabc.typeID ) WHERE uabc.batchID = '$batchId";
            $markFailedCriteria = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $markFailedCriteria;
    }
    /**
     * Get all supplementary registered students by batchId and supplyExamregId
     * @param $supplyExamregId
     * @param $batchId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentsRegisteredForSupplyExamination($supplyExamregId, $batchId)
    {
        $sql = '';
        $batchId = $this->realEscapeString($batchId);
        $supplyExamregId = $this->realEscapeString($supplyExamregId);
        $studentDetails = null;
        try {
            $sql = "SELECT sa.studentID, sa.studentName, sa.regNo FROM studentaccount sa INNER JOIN exam_supplementary_student_details essd ON (sa.studentID = essd.studentID) WHERE sa.batchID = '$batchId' AND essd.exam_supplementary_id = '$supplyExamregId' ORDER BY sa.regNo ASC";
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /******* University mark list configurations ********/
    /**
     * Add UniversityMarkListPassPercentConfigurations
     * @param UniversityMarkListPassPercentConfig $passPercentConfig
     * @return Boolean True
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function addUniversityMarkListPassPercentConfigs($passPercentConfig)
    {
        $sql = null;
        $passPercentConfig = $this->realEscapeObject($passPercentConfig);
        if (!empty ($passPercentConfig->batchYear)) {
            foreach ($passPercentConfig->batchYear as $batchYear) {
                $passPercentConfig->internalCutOff = $passPercentConfig->internalCutOff ? $passPercentConfig->internalCutOff : 'NULL';
                $passPercentConfig->semExamCutOff = $passPercentConfig->semExamCutOff ? $passPercentConfig->semExamCutOff : 'NULL';
                $passPercentConfig->subjectCutOff = $passPercentConfig->subjectCutOff ? $passPercentConfig->subjectCutOff : 'NULL';
                $passPercentConfig->aggrCutOff = $passPercentConfig->aggrCutOff ? $passPercentConfig->aggrCutOff : 'NULL';
                $values[] = "$passPercentConfig->courseTypeId$batchYear$passPercentConfig->internalCutOff,  $passPercentConfig->semExamCutOff$passPercentConfig->subjectCutOff$passPercentConfig->aggrCutOff$passPercentConfig->userId, utc_timestamp(), $passPercentConfig->userId, utc_timestamp())";
            }
            $sql = "INSERT INTO universityMarkListPassPercentConfigs ( course_type_id, batchYear, internalCutOff, semExamCutOff, subjectCutOff, aggregateCutOff, createdBy, createdDate, updatedBy, updatedDate ) VALUES ";
            $sql .= implode(", ", $values) . " ON DUPLICATE KEY UPDATE
            internalCutOff = VALUES(internalCutOff),
            semExamCutOff = VALUES(semExamCutOff),
            subjectCutOff = VALUES(subjectCutOff),
            aggregateCutOff = VALUES(aggregateCutOff),
            updatedBy = VALUES(updatedBy),
            updatedDate = VALUES(updatedDate)";
            try {
                $this->executeQuery($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        } else {
            throw new ProfessionalException("", ProfessionalException::INVALID_REQUEST);
        }
        return true;
    }
    /**
     * Get the UniversityMarkListPassPercentConfigurations by courseTypeId and batchStartYear
     * @param UniversityMarkListPassPercentConfig $passPercentConfig
     * @return Array $passPercentConfig
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getUniversityMarkListPassPercentConfig($passPercentConfigRequest = NULL)
    {
        $sql = null;
        $passPercentConfig = null;
        $sqlCondition = null;
        $request = $this->realEscapeObject($passPercentConfigRequest);
        if ($request->courseTypeId) {
            $sqlCondition .= " AND course_type_id = $request->courseTypeId ";
        }
        if ($request->batchYear) {
            $sqlCondition .= " AND batchYear = $request->batchYear ";
        }
        if ($request->subjectCatId) {
            $sqlCondition .= " AND ppc.subject_category_id = $request->subjectCatId ";
        }
        try {
            $sql = "SELECT ppc.id, ppc.course_type_id AS courseTypeId, ct.typeName AS courseTypeName, ppc.batchYear,
                    ppc.internalCutOff, ppc.semExamCutOff, ppc.subjectCutOff, ppc.aggregateCutOff
                    FROM universityMarkListPassPercentConfigs ppc
                    INNER JOIN course_type ct ON ( ppc.course_type_id = ct.courseTypeID ) WHERE 1 = 1 $sqlCondition ";
            $passPercentConfig = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $passPercentConfig;
    }
    public function removeUniversityMarkListPassPercentConfig($courseTypeId, $batchYear)
    {
        $sql = null;
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $batchYear = $this->realEscapeString($batchYear);
        $condition = null;
        if ($batchYear) {
            $condition = " batchYear = $batchYear ";
        } else {
            $condition = " batchYear IS NULL ";
        }
        $sql = "DELETE FROM universityMarkListPassPercentConfigs WHERE course_type_id = $courseTypeId AND $condition ";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * @author Vishnu M
     */
    public function getRegisteredRegularExamSubjects($studentId, $batchId, $semId, $examRegId = NULL)
    {
        $termPaper = ExamSubjectTypeConstants::TERM_PAPER;
        $openElective = ExamSubjectTypeConstants::OPEN_ELECTIVE;
        $sql = null;
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $batchId = $this->getStudentExamBatchBySemester ($studentId, $semId);
        if ( empty ( $batchId ) ) {
            throw new ProfessionalException(ProfessionalException::DATA_EMPTY, "Student's internal marks not found for this semester for any subject!");
        }
        $regExamSubjects = [];
        $sqlConditions = '';
        if ($semId != NULL) {
            $sqlConditions = "AND e.semID = '$semId'";
        }
        if ($examRegId != NULL) {
            $sqlConditions = "AND e.examregID = '$examRegId'";
        }
        // $sql = "SELECT e.examID, s.subjectID, s.subjectName, s.subjectDesc, ea.isAbsent FROM exam e INNER JOIN exam_reg_studentsubject erss ON (e.subjectID = erss.subjectID AND e.examregID = erss.examregID) INNER JOIN subjects s ON (s.subjectID = erss.subjectID AND s.subjectID = e.subjectID) INNER JOIN exam_subjectcredit esc ON (e.batchID = esc.batchID AND e.semID = esc.semID AND e.subjectID = esc.subjectID) LEFT JOIN exam_attendance ea ON (ea.studentID = erss.studentID AND ea.examID = e.examID) WHERE esc.isExternal = 1 AND e.batchID = '$batchId' AND e.semID = '$semId' AND erss.studentID = '$studentId' AND e.examID NOT IN (SELECT ees.examID FROM exam_excluded_students ees WHERE ees.studentID = erss.studentID AND ees.batchID = e.batchID) ";
        $sql = "SELECT
            e.examID,
            s.subjectID,
            s.subjectName,
            s.subjectDesc,
            ea.isAbsent
        FROM
            exam e
                INNER JOIN
            exam_reg_studentsubject erss ON (e.subjectID = erss.subjectID
                AND e.examregID = erss.examregID)
                INNER JOIN
            subjects s ON (s.subjectID = erss.subjectID
                AND s.subjectID = e.subjectID)
                INNER JOIN
            exam_subjectcredit esc ON (e.batchID = esc.batchID
                AND e.semID = esc.semID
                AND e.subjectID = esc.subjectID)
                LEFT JOIN
            exam_attendance ea ON (ea.studentID = erss.studentID
                AND ea.examID = e.examID)
        WHERE
            esc.isExternal = 1
                AND ( esc.excludeSubjectFromTotal = 0 OR ( esc.excludeSubjectFromTotal = 1 AND (esc.subjectType = '$termPaper' OR esc.subjectType = '$openElective' ) ) )
                AND e.batchID = '$batchId'
                $sqlConditions
                AND erss.studentID = '$studentId'
                AND e.examID NOT IN (SELECT
                    ees.examID
                FROM
                    exam_excluded_students ees
                WHERE
                    ees.studentID = erss.studentID
                        AND ees.batchID = e.batchID)";
        try {
            $regExamSubjects = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $regExamSubjects;
    }
    /**
     * @author Vishnu M
     */
    public function getAllExamsByExamRegId($examRegType, $examRegId)
    {
        $examRegType = $this->realEscapeString($examRegType);
        $examRegId = $this->realEscapeString($examRegId);
        $examDetails = [];
        if ($examRegType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT examID, examName, subjectID, examStartTime, examEndTime, examDate, batchID, semID, examregID, supply_examreg_id FROM exam WHERE examregID = '$examRegId";
        } else if ($examRegType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT examID, examName, subjectID, examStartTime, examEndTime, examDate, batchID, semID, examregID, supply_examreg_id FROM exam WHERE supply_examreg_id = '$examRegId";
        }
        try {
            $examDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
    /**
     * @author Vishnu M
     */
    public function getExamRegisteredStudentsByExamDateTime($examType, $examRegId, $examDate, $examTime)
    {
        $examType = $this->realEscapeString($examType);
        $examRegId = $this->realEscapeString($examRegId);
        $examDate = $this->realEscapeString($examDate);
        $examTime = $this->realEscapeString($examTime);
        $studentDetails = [];
        if ($examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT DISTINCT sa.studentID, sa.regNo FROM studentaccount sa INNER JOIN exam_reg_studentsubject erss ON (sa.studentID = erss.studentID) INNER JOIN exam e ON (e.examregID = erss.examregID AND e.subjectID = erss.subjectID AND sa.batchID = e.batchID) WHERE e.examDate = '$examDate' AND e.examStartTime = '$examTime' AND erss.examregID = '$examRegId";
        } else if ($examType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT DISTINCT sa.studentID, sa.regNo FROM studentaccount sa INNER JOIN exam_supplementary_student_subjects esss ON (sa.studentID = esss.studentID) INNER JOIN exam e ON (e.examID = esss.examID AND sa.batchID = e.batchID) INNER JOIN exam es ON (e.subjectID = es.subjectID AND es.supply_examreg_id = esss.exam_supplementary_id AND es.batchID = e.batchID) WHERE es.examDate = '$examDate' AND es.examStartTime = '$examTime' AND esss.exam_supplementary_id = '$examRegId";
        }
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * @throws ProfessionalException
     */
    public function calculatePassedStudentsInPassoutBatches()
    {
        $year = date("Y");
        $failed = BatchConstants::BATCH_FAILED_NAME;
        $sql = "SELECT sa.studentID,sa.regNo,sa.batchID FROM studentaccount sa
                INNER JOIN batches b on sa.batchID = b.batchID
                LEFT JOIN exam_student_passout_year espy on sa.studentID = espy.student_id
                WHERE b.batchEndYear<=$year AND espy.student_id IS NULL AND b.batchName!='$failed'";
        try {
            $students = $this->executeQueryForList($sql);
            $totalStudents = count($students);
            $passedStudents = 0;
            foreach ($students as $student) {
                $request = new ConsolidatedMarkReportRequest();
                $request->studentId = $student->studentID;
                $regularExamDetails = ConsolidatedMarkReportService::getInstance()->getStudentRegularExamMarkDetails($request);
                if (empty($regularExamDetails)) {
                    continue;
                }
                $studentResult = ConsolidatedMarkReportService::getInstance()->getStudentsOverallMarkReport($request, $regularExamDetails);
                $studentResult = array_pop($studentResult);
                if ($studentResult && !$studentResult->isFailed) {
                    $passoutYear = $this->getStudentLastAttendedExamYearByStudentId($student->studentID);
                    $addRequest = new AddStudentPassoutYearRequest();
                    $addRequest->studentId = $student->studentID;
                    $addRequest->passoutYear = $passoutYear;
                    $addRequest->createdBy = $addRequest->createdBy ? $addRequest->createdBy : 0;
                    $this->addStudentPassoutYear($addRequest);
                    ++$passedStudents;
                }
            }
            $this->createStudentPassoutYearCalculatorSchedulerLog($totalStudents, $passedStudents);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param AddStudentPassoutYearRequest $request
     * @throws ProfessionalException
     */
    public function addStudentPassoutYear(AddStudentPassoutYearRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "INSERT INTO exam_student_passout_year (student_id, passout_year, created_by, created_date)
                VALUES ($request->studentId,$request->passoutYear,$request->createdBy,UTC_TIMESTAMP())";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $studentId
     * @return mixed
     * @throws ProfessionalException
     */
    public function getStudentLastAttendedExamYearByStudentId($studentId)
    {
        $sql = "SELECT MAX(DISTINCT er.examYear) as examYear FROM exam_registration er
                INNER JOIN exam_reg_studentchallan ers ON ers.examregID = er.examregID
                INNER JOIN exam_registration_batches erb on er.examregID = erb.examregID
                INNER JOIN studentaccount sa ON sa.studentID = ers.studentID
                WHERE ers.studentID = $studentId AND er.shortCourse=0";
        try {
            return $this->executeQueryForObject($sql)->examYear;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $numberOfStudentsProcessed
     * @param $numberOfStudentsPassed
     * @throws ProfessionalException
     */
    private function createStudentPassoutYearCalculatorSchedulerLog($numberOfStudentsProcessed, $numberOfStudentsPassed)
    {
        $sql = "INSERT INTO passout_student_scheduler_log (number_of_students, number_of_students_passed, calculated_on) VALUES ($numberOfStudentsProcessed,$numberOfStudentsPassed,UTC_TIMESTAMP())";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $studentId
     * @param $examRegType
     * @param $examRegId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getExamOnlinePaymentTransactionDetails($studentId, $examRegType, $examRegId)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegType = $this->realEscapeString($examRegType);
        $examRegId = $this->realEscapeString($examRegId);
        $transactionDetails = null;
        $sql = "SELECT studentID, txnID, status, amount, transactionDate, exam_registration_type, exam_registration_type_id FROM  exam_online_payment WHERE studentID = '$studentId' AND exam_registration_type = '$examRegType' AND exam_registration_type_id = '$examRegId' ORDER BY transactionDate DESC";
        try {
            $transactionDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $transactionDetails;
    }
    /**
     * @param $supplyId
     * @param $studentId
     * @param $semId
     * @param $subjectId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getPreviousBatchExamMarkDetails($supplyId, $studentId, $semId, $subjectId)
    {
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $supplyId = $this->realEscapeString($supplyId);
        $markDetails = [];
        $sql = "SELECT DISTINCT
                e.examID,
                im.batchID,
                im.semID,
                im.studentID,
                im.subjectID,
                im.internalMarks,
                ims.maxInternalMarks,
                e.examTotalMarks AS maxExternalMarks,
                fs.previousBatch,
                b.batchStartYear,
                b.courseTypeID
            FROM
                internal_marks im
                    INNER JOIN
                internal_marks_settings ims ON im.batchID = ims.batchID
                    AND im.semID = ims.semID
                    AND im.subjectID = ims.subjectID
                    INNER JOIN
                failed_students fs ON fs.studentID = im.studentID
                    AND fs.previousBatch = im.batchID
                    INNER JOIN
                batches b ON fs.previousBatch = b.batchID
                    INNER JOIN
                exam e ON e.subjectID = im.subjectID
                    AND e.batchID = b.batchID
                    AND e.semID = im.semID
            WHERE
                im.studentID = '$studentId'
                    AND e.semID = '$semId'
                    AND e.subjectID = '$subjectId'
                    AND e.supply_examreg_id = '$supplyId'
                    AND fs.failedInSemester > im.semID
            ORDER BY fs.failedInSemester ASC";
        try {
            $markDetails = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $markDetails;
    }
    /**
     * @return Object
     * @throws ProfessionalException
     */
    public function getInternalExamComponents()
    {
        $sql = "SELECT id, name, max_mark, converted_max_mark FROM exam_type_component ORDER BY id DESC";
        try {
            $internalExams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $internalExams;
    }
    /**
     * Get exams by Requesest
     * @param Object $request
     * @return object|NULL|$objectList[]
     * @throws ProfessionalException
     */
    public function getExamsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $semId = $request->semID;
        $batchId = $request->batchId;
        $examTypeId = $request->examTypeId;
        $subjectId = $request->subjectId;
        $innerJoinTables = "";
        $whereConditions = "";
        if ($semId) {
            $whereConditions .= " AND e.semID IN ($semId)";
        }
        if ($batchId) {
            $whereConditions .= " AND e.batchID IN ($batchId)";
        }
        if ($examTypeId) {
            $whereConditions .= " AND e.examTypeID IN ($examTypeId)";
        }
        if ($subjectId) {
            $whereConditions .= " AND e.subjectID IN ($subjectId)";
        }
        if ($request->examRegId) {
            $whereConditions .= " AND e.examregID IN ($request->examRegId)";
        }
        if ($request->supplyExamRegId) {
            $whereConditions .= " AND e.supply_examreg_id IN ($request->supplyExamRegId)";
        }
        $sql = "SELECT
            e.examID AS id,
            e.examTotalMarks,
            e.examName AS name,
            e.batchID,
            e.semID,
            e.subjectID,
            e.examTypeID,
            e.subbatchID
        FROM
            exam e
            $innerJoinTables
        WHERE
            1=1
            $whereConditions";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
     * @param $courseTypeID
     * @return array|Object
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getSupplyExamRegistrationsByCourseTypeId($courseTypeId)
    {
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $supplyExamRegs = [];
        $sql = "SELECT DISTINCT es.id, es.supplyDesc, es.examMonth, es.examYear FROM exam_supplementary es INNER JOIN supply_improve_batches sib ON (es.id= sib
  .exam_supplementary_id) INNER JOIN batches b ON (sib.batchID = b.batchID) WHERE b.courseTypeID = '$courseTypeId";
        try {
            $supplyExamRegs = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyExamRegs;
    }
    public function getStudentSupplyExamMarkDetailsBySupplyStudentId($supplyRegId, $studentId)
    {
        $supplyRegId = (int)$this->realEscapeString($supplyRegId);
        $studentId = (int)$this->realEscapeString($studentId);
        $marksTable = null;
        $studentDetails = StudentService::getInstance()->getStudentDetailsById($studentId);
        $batchId = $studentDetails->batchID;
        $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchId);
        if (!$batchDetails) {
            $batchId = BatchService::getInstance()->getPreviousBatchWithStudentID($studentId)->previousBatch;
            $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchId);
        }
        $batchCourseType = $batchDetails->course_Type;
        $marksTable = 'exammarks_external';
        if ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::PGD) {
            $marksTable = 'externalexammarks_finalized';
        }
        $subjectDetails = [];
        $sql = "SELECT DISTINCT
                    sa.studentName,
                    sa.regNo,
                    sa.myImage,
                    b.batchID,
                    b.batchName,
                    b.batchDesc,
                    b.batchStartYear,
                    b.courseTypeID,
                    es.supplyDesc,
                    es.semID,
                    es.examMonth,
                    es.examYear,
                    s.subjectID,
                    s.subjectName,
                    s.subjectDesc,
                    im.internalMarks,
                    ims.maxInternalMarks,
                    ee.mark AS externalMarks,
                    e.examTotalMarks AS maxExternalMarks,
                    ea.isAbsent,
                    esc.credit,
                    esc.isInternal,
                    esc.isExternal,
                    esc.hideGrade,
                    esc.excludeSubjectFromTotal,
                    esc.subjectType,
                    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
                    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.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
                    $marksTable ee ON ee.examID = e.examID
                        AND sa.studentID = ee.studentID
                        LEFT JOIN
                    exam_attendance ea ON ea.examID = e.examID
                        AND ea.studentID = sa.studentID
                        LEFT JOIN
                    internal_marks im ON im.subjectID = e.subjectID
                        AND im.batchID = e.batchID
                        AND im.semID = e.semID
                        AND im.studentID = sa.studentID
                        LEFT JOIN
                    internal_marks_settings ims ON ims.subjectID = e.subjectID
                        AND ims.batchID = e.batchID
                        AND ims.semID = e.semID
                        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 essd.isSupply = 1
                        AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID)
                        AND es.id = '$supplyRegId'
                        AND sa.studentID = '$studentId'
                ORDER BY sa.regNo ASC, es.examYear ASC, es.examMonth ASC, es.examDate ASC, s.subjectPriority ASC";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    public function getExamDetailsForABatch(GetExamDetailsRequest $request)
    {
        $request = $this->realEscapeObject($request);
        $query = "SELECT e.examID,e.examName,e.subjectID,e.semID,e.examTotalMarks,e.examTypeID,s.subjectName,s.subjectDesc, pet.typeID AS childTypeId , et.parent_exam_typeID FROM exam e INNER JOIN subjects s on e.subjectID=s.subjectID INNER JOIN exam_type et ON et.typeID = e.examTypeID LEFT JOIN exam_type pet ON pet.parent_exam_typeID = et.typeID WHERE e.batchID='$request->batchId' AND e.semID='$request->semesterId' AND e.subjectID='$request->subjectId' AND e.examRegID IS NULL AND e.supply_examreg_id IS NULL ";
        if ($request->subbatchId) {
            $query .= " AND (e.subbatchID='$request->subbatchId' OR e.subbatchID=0)";
        } else if ($request->subbatchId !== "") {
            $query .= " AND e.subbatchID=0";
        }
        if ($request->isAproved) {
            $query .= " AND e.examID IN (SELECT examID FROM aprove_exam_marks WHERE examID=e.examID AND batchID=e.batchID AND semID=e.semID AND examTypeID=e.examTypeID AND isAproved=1) ";
        }
        try {
            $examList = $this->executeQueryForList($query);
            return $examList;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * check is approved marks enterd by staff
     * @param StudentExamMark $studentExamMarkList
     * @return \com\linways\base\dto\MySqlResult
     * @throws ProfessionalException
     */
    public function checkIsConfirmedMark($semId, $batchId, $examTypeId, $examId, $subBatchId = NULL, $staffId = NULL)
    {
        $semId = $this->realEscapeString($semId);
        $batchId = $this->realEscapeString($batchId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $examId = $this->realEscapeString($examId);
        $staffId = $this->realEscapeString($staffId);
        $subBatchId = $this->realEscapeString($subBatchId);
        $whereCondition = "";
        $isApproved = NULL;
        if ($subBatchId) {
            $whereCondition .= " AND subbatchID IN ($subBatchId)";
        }
        if ($staffId) {
            $whereCondition .= " AND staffID = $staffId";
        }
        $sql = "SELECT
            isAproved
        FROM
            aprove_exam_marks
        WHERE
            semID = $semId
                AND
            batchID = $batchId
                AND
            examTypeID = $examTypeId
                AND
            examID = $examId
            $whereCondition";
        try {
            $isApproved = $this->executeQueryForObject($sql)->isAproved;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $isApproved;
    }
    /**
     * get registered regular exam subjects by student id and exam reg id
     *
     */
    public function getRegisteredRegularExamSubjectsByStudentIdAndRegId($studentId, $examRegId)
    {
        global $COLLEGE_CODE;
        $sql = null;
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = BatchService::getInstance()->getBatcheIdByStudentId($studentId);
        $regularExamSemId = ExamService::getInstance()->getExamSemId($examRegId, $batchId);
        $regExamSubjects = [];
        if($COLLEGE_CODE == 'SJCC'){
            $sql = "SELECT
                s.subjectID,
                s.subjectName,
                s.subjectDesc,
                s.syllabusName,
                s.subjectPriority
            FROM
                exam_reg_studentsubject ers
                    INNER JOIN
                subjects s ON s.subjectID = ers.subjectID
                INNER JOIN studentaccount sa ON sa.studentID = ers.studentID
                INNER JOIN exam_subjectcredit esc ON sa.batchID = esc.batchID AND esc.subjectID = ers.subjectID
            WHERE
                ers.examregID = $examRegId
                    AND
                ers.studentID = $studentId AND esc.semID = $regularExamSemId
            ORDER BY esc.subjectOrder ASC";
        }
        else if($COLLEGE_CODE == 'CHRISTIJK'){
            $sql = "SELECT
                        s.subjectID,
                        s.subjectName,
                        s.subjectDesc,
                        s.syllabusName,
                        s.subjectPriority,
                        s.isTheory,
                        s.subjectcatID,
                        sc.subjectcatName
                    FROM
                        exam_reg_studentsubject ers
                            INNER JOIN
                        subjects s ON s.subjectID = ers.subjectID
                        INNER JOIN studentaccount sa ON sa.studentID = ers.studentID
                        INNER JOIN exam_subjectcredit esc ON sa.batchID = esc.batchID AND ers.subjectID = esc.subjectID
                        LEFT JOIN subject_category sc ON sc.subjectcatID = s.subjectcatID
                    WHERE
                        ers.examregID = '$examRegId'
                            AND 
                        ers.studentID = '$studentId' AND esc.semID = $regularExamSemId
                    ORDER BY esc.subjectOrder ASC";
        }
        else{
            $sql = "SELECT
                s.subjectID,
                s.subjectName,
                s.subjectDesc,
                s.syllabusName,
                s.subjectPriority,
                s.isTheory,
                ers.properties
            FROM
                exam_reg_studentsubject ers
                    INNER JOIN
                subjects s ON s.subjectID = ers.subjectID
                INNER JOIN studentaccount sa ON sa.studentID = ers.studentID
                INNER JOIN exam_subjectcredit esc ON sa.batchID = esc.batchID AND ers.subjectID = esc.subjectID
            WHERE
                ers.examregID = $examRegId
                    AND
                ers.studentID = $studentId
            ORDER BY esc.subjectOrder ASC";
        }
        try {
            $regExamSubjects = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $regExamSubjects;
    }
    /**
     * Get student registered exam fee payment details
     * @param int $studentId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentRegisteredExamFeePaymentDetails($studentId, $examRegId)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        try {
            $sql = "SELECT examstdregID, studentID, examregID, examfineID, examtotalFees, challanNo, dateofRegistration, paid, dateofPay, chlnpatternID, payment_method,courseMode FROM exam_reg_studentchallan WHERE examregID = $examRegId AND studentID = $studentId AND paid = 1";
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get student registered exam fee payment details
     * @return object|array
     * @throws ProfessionalException
     */
    public function getAllExamFineTypes()
    {
        try {
            $sql = "SELECT examfineID, examfineName, priority FROM exam_finetype WHERE priority<>0 ORDER BY priority ASC";
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $studentId
     * @param $examRegId
     * @param $isPaid
     * @return bool
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function updateStudentExamRegistrationPaidStatus($studentId, $examRegId, $isPaid)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $isPaid = $this->realEscapeString($isPaid);
        $sql = null;
        try {
            $sql = "UPDATE exam_reg_studentchallan SET paid = $isPaid WHERE studentID = $studentId AND examregID = $examRegId ";
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $studentId
     * @param $examRegId
     * @param $isPaid
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function updateStudentExamSupplementaryPaidStatus($studentId, $examRegId, $isPaid)
    {
        $automaticApprove = CommonService::getInstance()->getSettings(SettingsConstents::SUPPLY_IMPROVE, SettingsConstents::SUPPLY_IMPROVE_STUDENT_AUTOMATIC_APPROVE);
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $isPaid = $this->realEscapeString($isPaid);
        $sql = null;
        try {
            if ( $automaticApprove ){
                $sql = "UPDATE exam_supplementary_student_details SET paid = $isPaid, approved = 1, fee_paidDate = '".date('Y-m-d')."', payment_method = 'online' WHERE studentID = $studentId AND exam_supplementary_id = $examRegId ";
            }else{
              $sql = "UPDATE exam_supplementary_student_details SET paid = $isPaid, fee_paidDate = '".date('Y-m-d')."', payment_method = 'online' WHERE studentID = $studentId AND exam_supplementary_id = $examRegId ";
            }
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getExamRegistrationMonthYear()
    {
        $sql = null;
        $examRegistrationMonthYear = null;
        try {
            $sql = "
                SELECT
                    er.examMonth, er.examYear, 0 AS isSupply
                FROM
                    exam_registration er
                WHERE
                    er.examMonth IS NOT NULL
                        AND er.examYear IS NOT NULL
                UNION SELECT
                    es.examMonth, es.examYear, 1 AS isSupply
                FROM
                    exam_supplementary es
                WHERE
                    es.examMonth IS NOT NULL
                        AND es.examYear IS NOT NULL
                ORDER BY CAST(examYear AS SIGNED) DESC , CAST(examMonth AS SIGNED) DESC , isSupply ASC";
            $examRegistrationMonthYear = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistrationMonthYear;
    }
    /**
     * @param ExamRegistrationSubjectRequest $examSubjectRequest
     * @return $studentList
     * @throws ProfessionalException
     */
    public function getExamRegisteredStudentDetailsWithExamDateTime($examSubjectRequest)
    {
        $examSubjectRequest = $this->realEscapeObject($examSubjectRequest);
        $sql = null;
        $examStudentList = null;
        $sqlColumns = '';
        $sqlCondition = '';
        $sqlJoin = '';
        $customMapper = ExamServiceMapper::GET_STUDENT_EXAM_TIME_SLOT;
        if ($examSubjectRequest->includeStudentDetails) {
            $sqlColumns = " ,sa.studentID AS studentId,
            sa.studentName,
            sa.regNo,
            sa.admissionNo,
            sa.studentAccount,
            sa.rollNo,
            ssets.id AS timeSlotId,
            ssets.date,
            TIME_FORMAT(ssets.start_at, '%l:%i %p') AS start_at,
            TIME_FORMAT(ssets.end_at, '%l:%i %p') AS end_at";
            $sqlGroupBy = " , sa.studentID";
        } else {
            $sqlGroupBy = "";
            $sqlColumns = ", COUNT(DISTINCT sa.studentID) AS studentCount,
            COUNT(CASE WHEN ssets.date IS NOT NULL THEN 1 END) AS alottedStudentCount";
        }
        if ($examSubjectRequest->examCategory) {
            $examRegTableColumn = '';
            if ($examSubjectRequest->examCategory == ExamTypeConstant::REGULAR) {
                $examRegTableColumn = 'examregID';
                $examTableColumn = 'examregID';
                $examStudentTableColumn = 'examregID';
                $examTimeSlotTableColumn = 'exam_reg_id';
                $sqlJoin = 'exam_registration er
                INNER JOIN
                exam_reg_studentchallan ers ON er.examregID = ers.examregID';
                $sqlColumns .= ', er.examregID AS examRegId,
                er.examregName AS examRegName,
                er.examregDesc AS examRegDec';
            } else if ($examSubjectRequest->examCategory == ExamTypeConstant::SUPPLY || $examSubjectRequest->examCategory == 'IMPROVE') {
                $examRegTableColumn = 'id';
                $examTableColumn = 'supply_examreg_id';
                $examStudentTableColumn = 'exam_supplementary_id';
                $examTimeSlotTableColumn = 'supply_exam_reg_id';
                $sqlJoin = 'exam_supplementary er
                INNER JOIN
                exam_supplementary_student_details ers ON er.id = ers.exam_supplementary_id';
                $sqlColumns .= ', er.id AS examRegId,
                er.supplyDesc AS examRegName';
                $sqlCondition .= " AND ers.paid = '1'";
            } else {//To be updated on Internal Exams are created
                $examStudentList = [];
                return $examStudentList;
            }
        } else {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, 'Exam Category can not be null');
        }
        if ($examSubjectRequest->examRegistrationIds) {
            $examRegIdsStr = implode(',', $examSubjectRequest->examRegistrationIds) ? implode(',', $examSubjectRequest->examRegistrationIds) : $examSubjectRequest->examRegistrationIds;
            $sqlCondition .= " AND er.$examRegTableColumn IN ($examRegIdsStr";
        }
        if ($examSubjectRequest->subjects) {
            $subjectsStr = implode(',', $examSubjectRequest->subjects) ? implode(',', $examSubjectRequest->subjects) : $examSubjectRequest->subjects;
            $sqlCondition .= " AND s.subjectID IN ($subjectsStr";
        }
        if ($examSubjectRequest->subjectCategoryIds) {
            $subjectCategoryIdsStr = implode(',', $examSubjectRequest->subjectCategoryIds) ? implode(',', $examSubjectRequest->subjectCategoryIds) : $examSubjectRequest->subjectCategoryIds;
            $sqlCondition .= " AND s.subjectcatID IN ($subjectCategoryIdsStr";
        }
        if ($examSubjectRequest->batchIds) {
            $batchIdsStr = implode(',', $examSubjectRequest->batchIds) ? implode(',', $examSubjectRequest->batchIds) : $examSubjectRequest->batchIds;
            $sqlCondition .= " AND ex.batchID IN ($batchIdsStr";
        }
        if ($examSubjectRequest->departmentIds) {
            $departmentIdsStr = implode(',', $examSubjectRequest->departmentIds) ? implode(',', $examSubjectRequest->departmentIds) : $examSubjectRequest->departmentIds;
            $sqlCondition .= " AND b.deptID IN ($departmentIdsStr";
        }
        try {
            //     $sql = "SELECT
            //     s.subjectID,
            //     s.subjectName AS subjectCode,
            //     s.subjectDesc AS subjectName
            //     $sqlColumns
            // FROM
            //     $sqlJoin
            //         INNER JOIN
            //     studentaccount sa ON ers.studentID = sa.studentID
            //         INNER JOIN
            //     sbs_relation sbsr ON sbsr.batchID = sa.batchID
            //         AND sbsr.semID = er.semID
            //         INNER JOIN
            //     subjects s ON s.subjectID = sbsr.subjectID
            //         INNER JOIN
            //     batches b ON b.batchID = sbsr.batchID
            //         -- AND b.batchID = ex.batchID
            //         AND b.batchID = sa.batchID
            //         LEFT JOIN
            //     exam ex ON ex.$examTableColumn = ers.$examStudentTableColumn
            //         AND ex.$examTableColumn = er.$examRegTableColumn
            //         AND ex.subjectID = s.subjectID
            //         AND ex.subjectID = sbsr.subjectID
            //         AND ex.batchID = sbsr.batchID
            //         AND ex.batchID = sa.batchID
            //         AND ex.semID = sbsr.semID
            //         AND ex.semID = er.semID
            //         LEFT JOIN
            //     ec_student_subject_exam_time_slot ssets ON ssets.$examTimeSlotTableColumn = er.$examRegTableColumn
            //         AND ssets.subject_id = s.subjectID
            //         -- AND ssets.subject_id = ex.subjectID
            //         AND ssets.subject_id = sbsr.subjectID
            //         AND ssets.student_id = sa.studentID
            //         AND ssets.student_id = ers.studentID
            //         AND ssets.exam_type_id = ex.examTypeID
            // WHERE
            //     1 = 1
            //     $sqlCondition
            // GROUP BY s.subjectID$sqlGroupBy
            // ORDER BY er.$examRegTableColumn DESC";
            $sql = "SELECT
            s.subjectID,
            s.subjectName AS subjectCode,
            s.subjectDesc AS subjectName
            $sqlColumns
        FROM
            exam_supplementary er
            INNER JOIN
        exam_supplementary_student_details ers ON er.id = ers.exam_supplementary_id
            INNER JOIN
        exam_supplementary_student_subjects exsub ON exsub.exam_supplementary_id = ers.exam_supplementary_id
            AND exsub.studentID = ers.studentID
            INNER JOIN
        studentaccount sa ON ers.studentID = sa.studentID
            AND exsub.studentID = sa.studentID
            INNER JOIN
        exam ex ON ex.examID = exsub.examID
            -- AND ex.batchID = sa.batchID  -- condition removed to get failed students and year out students
            AND ex.semID = er.semID
            INNER JOIN
        subjects s ON ex.subjectID = s.subjectID
            INNER JOIN
        batches b ON b.batchID = sa.batchID
            AND b.batchID = sa.batchID
            -- AND b.batchID = ex.batchID   -- condition removed to get failed students and year out students
            LEFT JOIN
        ec_student_subject_exam_time_slot ssets ON ssets.supply_exam_reg_id = er.id
            AND ssets.subject_id = s.subjectID
            AND ssets.subject_id = ex.subjectID
            AND ssets.student_id = sa.studentID
            AND ssets.student_id = ers.studentID
            -- AND ssets.exam_type_id = ex.examTypeID
        WHERE
            1 = 1
            $sqlCondition
        GROUP BY s.subjectID$sqlGroupBy
        ORDER BY er.$examRegTableColumn DESC";
            $examStudentList = $this->executeQueryForList($sql, $this->mapper[$customMapper]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examStudentList;
    }
    /**
     * Method for assign time slot for exam
     * @param $timeSlotAssignRequest
     * @return $id
     * @throws ProfessionalException
     */
    public function assignExamTimeSlot($timeSlotAssignRequest)
    {
        $timeSlotAssignRequest = $this->realEscapeObject($timeSlotAssignRequest);
        $sql = '';
        $valueArray = NULL;
        $valueSql = "";
        $timeSlotAssignRequest->createdBy = $_SESSION['adminID'];
        if (!$timeSlotAssignRequest->examType) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, 'Exam Type can not be null');
        }
        if (!$timeSlotAssignRequest->examRegId) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, 'Exam id can not be null');
        }
        if (!$timeSlotAssignRequest->subjectId) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, 'Subject id can not be null');
        }
        if (!$timeSlotAssignRequest->createdBy) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, 'User can not be null');
        }
        if (empty($timeSlotAssignRequest->students)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, 'Students can not be null');
        } else {
            foreach ($timeSlotAssignRequest->students as $student) {
                if ($timeSlotAssignRequest->examType && $student['examTimeSlots']['date'] && $student['examTimeSlots']['startAt'] && $student['examTimeSlots']['endAt']) {
                    $examTypeDetails = ExamService::getInstance()->getExamTypeById($timeSlotAssignRequest->examType);
                    if ($examTypeDetails->isInternal == 1) {
                        // $valueArray[] = "($timeSlotAssignRequest->examRegId,$student['examTimeSlots']['date'],$student->amount,$timeSlotAssignRequest->createdBy)";
                    } else if ($examTypeDetails->isSupply == 1) {
                        $valueArray[] = "(NULL,$timeSlotAssignRequest->examRegId,$timeSlotAssignRequest->examType,$timeSlotAssignRequest->subjectId," . $student['studentId'] . ",'" . $student['examTimeSlots']['date'] . "',STR_TO_DATE('" . $student['examTimeSlots']['startAt'] . "', '%l:%i %p' ),STR_TO_DATE('" . $student['examTimeSlots']['endAt'] . "', '%l:%i %p' )," . "$timeSlotAssignRequest->createdBy)";
                    } else {
                        $valueArray[] = "($timeSlotAssignRequest->examRegId,NULL,$timeSlotAssignRequest->examType,$timeSlotAssignRequest->subjectId," . $student['studentId'] . ",'" . $student['examTimeSlots']['date'] . "',STR_TO_DATE('" . $student['examTimeSlots']['startAt'] . "', '%l:%i %p' ),STR_TO_DATE('" . $student['examTimeSlots']['endAt'] . "', '%l:%i %p' )," . "$timeSlotAssignRequest->createdBy)";
                    }
                }
            }
        }
        if ($valueArray) {
            $valueSql = implode(',', $valueArray);
        }
        try {
            $sql = "INSERT INTO ec_student_subject_exam_time_slot
                (
                    exam_reg_id,
                    supply_exam_reg_id,
                    exam_type_id,
                    subject_id,
                    student_id,
                    date,
                    start_at,
                    end_at,
                    created_by
                )
            VALUES
                $valueSql";
            $id = $this->executeQuery($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::INTERNAL_SERVICE_FAILURE, $e->getMessage());
        }
        return $id;
    }
    /**
     * Method for assign time slot for exam
     * @param $timeSlotAssignRequest
     * @return $id
     * @throws ProfessionalException
     */
    public function getExamTimeSlotForStudentSubject($studentId, $subjectId, $examId, $examTypeId)
    {
        $studentId = $this->realEscapeString($studentId);
        $subjectId = $this->realEscapeString($subjectId);
        $examId = $this->realEscapeString($examId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $sql = '';
        $sqlWhere = "";
        if ($examTypeId) {
            $examTypeDetails = ExamService::getInstance()->getExamTypeById($examTypeId);
            if ($examTypeDetails->isInternal == 1) {
                $sqlWhere .= "";
            } else if ($examTypeDetails->isSupply == 1) {
                $sqlWhere .= " AND
                supply_exam_reg_id = $examId";
            } else {
                $sqlWhere .= "AND
                exam_reg_id = $examId";
            }
        }
        $sqlWhere .= " AND
                exam_type_id = $examTypeId
                AND
                subject_id = $subjectId
                AND
                student_id = $studentId";
        try {
            $sql = "SELECT id, subject_id AS subjectId, date, TIME_FORMAT(start_at, '%l:%i %p') AS startAt,TIME_FORMAT(end_at, '%l:%i %p') AS endAt FROM ec_student_subject_exam_time_slot
            WHERE
                id>0
                $sqlWhere";
            $timeSlot = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::INTERNAL_SERVICE_FAILURE, $e->getMessage());
        }
        return $timeSlot;
    }
    /**
     *
     * @param $timeSlotAssignRequest
     * @return $id
     * @throws ProfessionalException
     */
    public function updateExamTimeSlotForStudentSubject($student, $oldId)
    {
        $student = $this->realEscapeObject($student);
        $oldId = $this->realEscapeString($oldId);
        $updatedBy = $_SESSION['adminID'];
        $date = $student['examTimeSlots']['date'];
        $startAt = $student['examTimeSlots']['startAt'];
        $endAt = $student['examTimeSlots']['endAt'];
        try {
            $sql = "UPDATE ec_student_subject_exam_time_slot
            SET
                date = '$date',
                start_at = STR_TO_DATE('$startAt', '%l:%i %p' ),
                end_at = STR_TO_DATE('$endAt', '%l:%i %p' ),
                updated_by = '$updatedBy'
            WHERE
                id IN ($oldId)";
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::INTERNAL_SERVICE_FAILURE, $e->getMessage());
        }
    }
    public function getRegularExamTypeId($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        try {
            $sql = "SELECT DISTINCT examTypeID FROM exam WHERE examregID IN ($examRegId);";
            $examTypeId = $this->executeQueryForObject($sql)->examTypeID;
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::INTERNAL_SERVICE_FAILURE, $e->getMessage());
        }
        return $examTypeId;
    }
    public function getSupplyExamTypeId($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        try {
            $sql = "SELECT DISTINCT examTypeID FROM exam WHERE supply_examreg_id IN ($examRegId);";
            $examTypeId = $this->executeQueryForObject($sql)->examTypeID;
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::INTERNAL_SERVICE_FAILURE, $e->getMessage());
        }
        return $examTypeId;
    }
    /**
     * check is enable edit option for exam registrations after students are registered
     * @param  $examType
     * @return Object $isEditEnable
     * @throws ProfessionalException
     * @author Anoop
     *
     */
    public function isEnableEditExamRegAfterStudentRegistration($examType)
    {
        $examType = $this->realEscapeString($examType);
        $isEnableEdit = NULL;
        $enableEditObj = NULL;
        try {
            $enableEditJSON = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::ENABLE_EDIT_FOR_ALREADY_REGISTERED_EXAM_REGISTRATIONS);
            $enableEditObj = json_decode($enableEditJSON);
            if ($enableEditObj) {
                if ($examType == ExamTypeConstant::REGULAR) {
                    $isEnableEdit = $enableEditObj->regular;
                } else if ($examType == ExamTypeConstant::SUPPLY) {
                    $isEnableEdit = $enableEditObj->supply;
                } else if ($examType == ExamTypeConstant::INTERNAL) {
                    $isEnableEdit = $enableEditObj->internal;
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $isEnableEdit;
    }
    /**
     * get course type of a regular exam registration
     * @param  $examRegId
     * @return Object $courseType
     * @throws ProfessionalException
     * @author Anoop
     */
    public function getCourseTypeOfRegularExamRegistration($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        try {
            $sql = "SELECT DISTINCT
            er.examregID,
            er.examregName,
            ct.courseTypeID,
            ct.course_Type AS courseType
         FROM
             exam_registration er
                 INNER JOIN
             exam_registration_batches erb ON erb.examregID = er.examregID
                 INNER JOIN
             batches b ON b.batchID = erb.batchID
                 INNER JOIN
                 course_type ct ON ct.courseTypeID = b.courseTypeID
              WHERE
              er.examregID = $examRegId";
            $courseType = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException(ProfessionalException::INTERNAL_SERVICE_FAILURE, $e->getMessage());
        }
        return $courseType;
    }
    /**
     * Student bulk exam registration by exam registration id in EXAM side
     */
    /**
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function searchExamRegistrationBatches($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = null;
        $sql = null;
        $batches = null;
        $orderBy = " ORDER BY b.batchStartYear ASC, b.batchName ASC ";
        if ($request->batchStartYear) {
            $condition .= " AND b.batchStartYear = '$request->batchStartYear";
        }
        if ($request->courseTypeId) {
            $condition .= " AND b.courseTypeID = '$request->courseTypeId";
        }
        if ($request->semId) {
            $condition .= " AND erb.semId = '$request->semId";
        }
        if($request->orderByBatchDisplayOrder){
            $orderBy = " ORDER BY b.batchDisplayOrder ASC,b.batchStartYear ASC, b.batchName ASC ";
        }
        try {
            $sql = "SELECT b.batchID, b.batchName, b.batchID as id, b.batchName as name, b.batchDesc, erb.attClosingDate FROM exam_registration er INNER JOIN exam_registration_batches erb ON (er.examregID = erb.examregID) INNER JOIN batches b ON (b.batchID = erb.batchID) WHERE er.examregID = '$request->examRegId$condition $orderBy";
            $batches = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $batches;
    }
    /**
     * Student bulk exam registration by exam registration id in EXAM side
     */
    /**
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function searchSupplyExamRegistrationBatches($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = null;
        $sql = null;
        $batches = null;
        try {
            $sql = "SELECT b.batchID, b.batchName, b.batchDesc FROM exam_supplementary es INNER JOIN supply_improve_batches sib ON (es.id = sib.exam_supplementary_id) INNER JOIN batches b ON (b.batchID = sib.batchID) WHERE es.id = '$request->examRegId";
            $batches = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $batches;
    }
    /**
     * @param ExamRegistrationBatchRequest $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getExamRegStudentNotRegisteredBatches($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $batches = null;
        $condition = null;
        if (!empty ($request->batchStartYear)) {
            $batchStartYearString = implode(",", $request->batchStartYear) ? implode(",", $request->batchStartYear)
                : $request->batchStartYear;
            $condition .= " AND b.batchStartYear IN ($batchStartYearString";
        }
        if (!empty ($request->examRegistrationBatches)) {
            $examRegistrationBatchString = implode(",", $request->examRegistrationBatches) ? implode(",",
                $request->examRegistrationBatches) : $request->examRegistrationBatches;
            $condition .= " AND b.batchID IN ($examRegistrationBatchString";
        }
        try {
            $sql = "SELECT DISTINCT b.batchID AS id, b.batchName AS name, b.batchStartYear FROM exam_registration er INNER JOIN exam_registration_batches erb ON (er.examregID = erb.examregID) INNER JOIN batches b ON (b.batchID = erb.batchID) INNER JOIN studentaccount sa ON (sa.batchID = b.batchID) WHERE er.examregID = '$request->examRegId' AND sa.studentID NOT IN (SELECT ersc.studentID FROM exam_reg_studentchallan ersc WHERE ersc.examregID = '$request->examRegId') $condition ORDER BY b.batchStartYear ASC, b.batchName ASC";
            $batches = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $batches;
    }
    /**
     * @param ExamRegistrationBatchRequest $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getExamRegistrationBatches($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $batches = null;
        $condition = null;
        if (!empty ($request->batchStartYear)) {
            $batchStartYearString = implode(",", $request->batchStartYear) ? implode(",", $request->batchStartYear)
                : $request->batchStartYear;
            $condition .= " AND b.batchStartYear IN ($batchStartYearString";
        }
        if (!empty ($request->examRegistrationBatches)) {
            $examRegistrationBatchString = implode(",", $request->examRegistrationBatches) ? implode(",",
                $request->examRegistrationBatches) : $request->examRegistrationBatches;
            $condition .= " AND b.batchID IN ($examRegistrationBatchString";
        }
        if (!empty ($request->semId)) {
            $semIdString = is_array($request->semId) ? implode(",", $request->semId)
                : $request->semId;
            $condition .= " AND erb.semID IN ($semIdString";
        }
        try {
            $sql = "SELECT DISTINCT b.batchID AS id, b.batchName AS name, b.batchStartYear, erb.semID AS semId, ct.typeName as courseTypeName, b.courseTypeID AS courseTypeId,ct.course_Type FROM exam_registration er INNER JOIN exam_registration_batches erb ON (er.examregID = erb.examregID) INNER JOIN batches b ON (b.batchID = erb.batchID) LEFT JOIN course_type ct on ct.courseTypeID = b.courseTypeID WHERE er.examregID = '$request->examRegId$condition ORDER BY b.batchStartYear ASC, b.batchName ASC";
            $batches = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $batches;
    }
    /**
     * @param ExamRegistrationBatchRequest $request
     * @return Object|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getStudentsForExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $students = null;
        $condition = null;
        if (!empty ($request->batchStartYear)) {
            $batchStartYearString = implode(",", $request->batchStartYear) ? implode(",", $request->batchStartYear)
                : $request->batchStartYear;
            $condition .= " AND b.batchStartYear IN ($batchStartYearString";
        }
        if (!empty ($request->examRegistrationBatches)) {
            $examRegistrationBatchString = implode(",", $request->examRegistrationBatches) ? implode(",",
                $request->examRegistrationBatches) : $request->examRegistrationBatches;
            $condition .= " AND b.batchID IN ($examRegistrationBatchString";
        }
        try {
            $sql = "SELECT sa.studentID AS studentId, sa.studentName, sa.regNo, b.batchID AS id, b.batchName AS name FROM exam_registration er INNER JOIN  exam_registration_batches erb ON (er.examregID = erb.examregID) INNER JOIN batches b ON (b.batchID = erb.batchID) INNER JOIN studentaccount sa ON (sa.batchID = b.batchID) WHERE er.examregID = '$request->examRegId' AND sa.studentID NOT IN (SELECT ersc.studentID FROM exam_reg_studentchallan ersc WHERE ersc.examregID = '$request->examRegId') $condition";
            $students = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $students;
    }
    /**
     * @param $request
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function studentBulkExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $examRegId = $request->examRegId;
        $today = date("Y-m-d");
        $paid = 1;
        $paymentMethod = "COLLEGE_REGISTRATION";
        $studentRegValues = [];
        try {
            $batches = $this->getExamRegistrationBatches($request);
            if (!empty ($batches)) {
                foreach ($batches as $batch) {
                    $batchStudentSubjects = $this->getStudentExamSubjectsForRegistration($examRegId, $batch->id);
                    if (!empty ($batchStudentSubjects)) {
                        $studentExamRegSubjects = [];
                        foreach ($batchStudentSubjects as $batchStudentSubject) {
                            $studentId = $batchStudentSubject->studentID;
                            $studentRegValues[$studentId] = "($studentId$examRegId, '$today', $paid, '$today', '$paymentMethod')";
                            $studentExamRegSubjects[] = "($studentId$examRegId$batchStudentSubject->subjectID)";
                        }
                        $sql = "INSERT IGNORE INTO exam_reg_studentsubject ( studentID, examregID, subjectID ) VALUES " . implode(",", $studentExamRegSubjects);
                        $this->executeQuery($sql);
                    }
                }
                if (!empty ($studentRegValues)) {
                    $sql = "INSERT IGNORE INTO exam_reg_studentchallan ( studentID, examregID, dateofRegistration, paid, dateofPay, payment_method) VALUES " . implode(",", $studentRegValues);
                    $this->executeQuery($sql);
                } else {
                    throw new ProfessionalException(ProfessionalException::DATA_EMPTY, "No data found");
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param  $request
     * @return array|Object
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getExamRegistrationsByBatch($request)
    {
        $request = $this->realEscapeObject($request);
        $batchId = $request->batchId;
        $condition = null;
        if ($request->examRegId) {
            $condition .= " AND er.examregID = '$request->examRegId";
        }
        $sql = null;
        $examRegistrations = [];
        try {
            $sql = "SELECT er.examregID AS id, examregName AS name, erb.semID AS semId FROM exam_registration er INNER JOIN exam_registration_batches erb ON (er.examregID = erb.examregID) WHERE erb.batchID = '$batchId$condition ";
            $examRegistrations = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistrations;
    }
    /**
     * @param ExamRegStudentBlockingRequest $request
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function blockUnblockStudentBySemesterWiseReason($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $examRegId = null;
        $supplyRegId = null;
        $values = [];
        try {
            if ($request->action == "BLOCK") {
                $sql = "INSERT IGNORE INTO exam_reg_blocked_student (student_id, subject_id, examreg_id, supplyreg_id, reason_id, created_by, created_date) VALUES ";
                foreach ($request->subjectIdArray as $subjectId) {
                    $values[] = "(
                        " . $request->studentId . ",
                        " . $subjectId . ",
                        " . $request->examRegId . ",
                        " . $request->supplyRegId . ",
                        " . $request->reasonId . ",
                        " . $request->createdBy . ",
                        utc_timestamp()
                    )";
                }
                $sql .= implode(',', $values);
            } else {
                $condition = $request->isSupply ? " AND supplyreg_id = '$request->supplyRegId" : " AND examreg_id = '$request->examRegId";
                // $sql = "DELETE FROM exam_reg_blocked_student WHERE student_id = '$request->studentId' AND reason_id
                // = '$request->reasonId' AND subject_id IN (".implode(',', $request->subjectIdArray).") $condition ";
                $sql = "DELETE FROM exam_reg_blocked_student WHERE student_id = '$request->studentId' AND reason_id = '$request->reasonId$condition ";
            }
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $request
     * @return array|Object
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getStudentExamRegBlockedStatusSemesterwise($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $reasons = [];
        $condition = null;
        $reasonType = "SEMESTER_WISE";
        if ($request->isSupply) {
            $condition .= " AND erbs.supplyreg_id = '$request->supplyRegId";
        } else {
            $condition .= " AND erbs.examreg_id = '$request->examRegId";
        }
        try {
            $sql = "SELECT DISTINCT erbr.id, erbr.reason, erbr.contact_person_id, erbr.reason_type FROM exam_reg_blocked_student erbs INNER JOIN exam_reg_block_reason erbr ON (erbs.reason_id = erbr.id) WHERE erbs.student_id = '$request->studentId' AND erbr.reason_type = '$reasonType$condition";
            $reasons = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $reasons;
    }
    public function getSubjectsForBulkExamDefinition($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $subjects = [];
        $condition = null;
        if ($request->subjectCategoryId) {
            $condition .= " AND s.subjectcatID IN ($request->subjectCategoryId";
        }
        if ($request->subjectPriority) {
            $condition .= " AND s.subjectPriority IN ($request->subjectPriority";
        }
        if ($request->examType === ExamType::REGULAR) {
            $sql = "SELECT s.subjectID as subjectId, s.subjectName, s.syllabusName, s.subjectDesc, DATE_FORMAT(e.examDate, '%d-%m-%Y') as examDate, e.examStartTime, e.examEndTime, er.examregID AS examRegId, b.courseTypeID AS courseTypeId, ersf.semID AS semId, 0 as isSuppply, e.examTotalMarks,e.valuationMaxMark FROM exam_registration er INNER JOIN exam_registration_subject_fees ersf ON (er.examregID = ersf.examregID) INNER JOIN subjects s ON (s.subjectID = ersf.subjectID) INNER JOIN batches b ON (b.batchID = ersf.batchID) LEFT JOIN exam e ON (e.examregID = er.examregID AND e.subjectID = s.subjectID AND e.batchID = ersf.batchID) WHERE b.courseTypeID = '$request->courseTypeId' AND ersf.semID = '$request->semId' AND er.examregID = '$request->examRegId$condition GROUP BY s.subjectID ORDER BY s.subjectName ASC ";
        } else if ($request->examType === ExamType::SUPPLY) {
            $sql = "SELECT s.subjectID as subjectId, s.subjectName, s.syllabusName, s.subjectDesc, IF ( e.examDate != '0000-00-00', DATE_FORMAT(e.examDate, '%d-%m-%Y'), null) AS examDate, e.examStartTime, e.examEndTime, es.id AS examRegId, b.courseTypeID AS courseTypeId, e_reg.semID AS semId, 1 as isSuppply, e.examTotalMarks, e_reg.examID as regularExamID, e_reg.examTotalMarks as regularMaxMark,e.valuationMaxMark FROM exam_supplementary es INNER JOIN exam_supplementary_student_subjects esss ON (es.id = esss.exam_supplementary_id) INNER JOIN exam e_reg ON (esss.examID = e_reg.examID) INNER JOIN subjects s ON (s.subjectID = e_reg.subjectID) INNER JOIN batches b ON (b.batchID = e_reg.batchID) LEFT JOIN exam e ON (e.subjectID = e_reg.subjectID AND e.semID = e_reg.semID AND e.batchID = e_reg.batchID AND e.supply_examreg_id = '$request->examRegId') WHERE b.courseTypeID = '$request->courseTypeId' AND e_reg.semID = '$request->semId' AND esss.exam_supplementary_id = '$request->examRegId$condition GROUP BY s.subjectID ORDER BY s.subjectName ASC ";
        }
        else {
            $sql = "SELECT
                        s.subjectID AS subjectId,
                        s.subjectName,
                        s.syllabusName,
                        s.subjectDesc,
                        IF ( e.examDate != '0000-00-00', DATE_FORMAT(e.examDate, '%d-%m-%Y'), null) AS examDate,
                        e.examStartTime,
                        e.examEndTime,
                        b.courseTypeID AS courseTypeId,
                        e.examTotalMarks,
                        e.semID,
                        e.valuationMaxMark
                    FROM
                        sbs_relation sbs
                            INNER JOIN
                        subjects s ON (s.subjectID = sbs.subjectID)
                            INNER JOIN
                        batches b ON (b.batchID = sbs.batchID)
                            LEFT JOIN
                        exam e ON e.subjectID = sbs.subjectID
                            AND e.semID = sbs.semID
                            AND e.batchID = sbs.batchID
                            AND e.examTypeID = '$request->examTypeId'
                    WHERE
                        b.courseTypeID = '$request->courseTypeId'
                            AND sbs.semID = '$request->semId'
                            AND sbs.semID = b.semID
                    GROUP BY s.subjectID
                    ORDER BY s.subjectDesc ASC , s.subjectName ASC";
        }
        try {
            $subjects = $this->executeQueryForList($sql);
            if ( !empty ( $subjects ) ) {
                foreach ( $subjects as $subject ) {
                    if ( $subject->examStartTime) {
                        $subject->examStartTime = date("h:i A", strtotime($subject->examStartTime));
                    }
                    if ( $subject->examEndTime ) {
                        $subject->examEndTime = date("h:i A", strtotime($subject->examEndTime));
                    }
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    /**
     * @param $exams
     * @throws ProfessionalException
     */
    public function defineExam($exams)
    {
        $exams = $this->realEscapeArray($exams);
        $sql = null;
        $values = [];
        try {
            if (!empty ($exams)) {
                foreach ($exams as $exam) {
                    $existingExam = null;
                    $existingExam = ExamService::getInstance()->getExamsByRequest($exam);
                    if (empty ($existingExam)) {
                        $exam->examRegId = $exam->examRegId ? $exam->examRegId : 'NULL';
                        $exam->supplyExamRegId = $exam->supplyExamRegId ? $exam->supplyExamRegId : 'NULL';
                        $exam->examCode = $exam->examCode ? $exam->examCode : 'NULL';
                        $exam->courseId = $exam->courseId ? $exam->courseId : 'NULL';
                        $values[] = "(
                            '$exam->name',
                            $exam->subjectId,
                            $exam->examTotalMarks,
                            '$exam->examDate',
                            '$exam->examStartTime',
                            '$exam->examEndTime',
                            $exam->batchId,
                            $exam->semId,
                            $exam->examTypeId,
                            $exam->examRegId,
                            $exam->supplyExamRegId,
                            $exam->isRoundOff,
                            $exam->unixtimeStart,
                            $exam->unixtimeEnd,
                            $exam->examCode,
                            $exam->courseId,
                            $exam->createdBy,
                            IF('$exam->valuationMaxMark' = '', NULL, '$exam->valuationMaxMark')
                        )";
                    } else {
                        $examId = $existingExam[0]->id;
                        $sql = "UPDATE exam SET examTotalMarks = $exam->examTotalMarks, examDate = '$exam->examDate', examStartTime = '$exam->examStartTime', examEndTime = '$exam->examEndTime', unixtime_start = '$exam->unixtimeStart', unixtime_end = '$exam->unixtimeEnd', updated_by = '$exam->createdBy',valuationMaxMark = '$exam->valuationMaxMark' WHERE examID = $examId ";
                        $this->executeQuery($sql);
                    }
                }
                if (!empty ($values)) {
                    $sql = "INSERT INTO exam (examName, subjectID, examTotalMarks, examDate, examStartTime, examEndTime, batchID, semID, examTypeID, examregID, supply_examreg_id, isRoundOff, unixtime_start, unixtime_end, examCode, courseID, created_by,valuationMaxMark) VALUES " . implode(", ", $values) . " ON DUPLICATE KEY UPDATE 
                    examDate = VALUES (examDate),
                    examStartTime = VALUES (examStartTime),
                    examEndTime = VALUES (examEndTime),
                    unixtime_start = VALUES (unixtime_start),
                    unixtime_end = VALUES (unixtime_end),
                    updated_by = VALUES (created_by)";;
                    $this->executeQuery($sql);
                }
            } else {
            }
        } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $request
     * @return array|Object
     * @throws ProfessionalException
     */
    public function searchExamTypes($request)
    {
        $conditions = NULL;
        $examTypes = [];
        $sql = null;
        if ($request->canShow === 1) {
            $conditions = 'WHERE canShow = 1 ';
        } else if ($request->canShow === 0) {
            $conditions = 'WHERE canShow = 0 ';
        } else {
            $conditions = 'WHERE canShow IN (0, 1) ';
        }
        if ($request->canFacultyCreate) {
            $conditions .= ' AND can_faculty_create = 1';
        }
        if ($request->isInternal === 1) {
            $conditions .= " AND isInternal = 1";
        } else if ($request->isInternal === 0) {
            $conditions .= " AND isInternal = 0";
        }
        if ($request->isSupply) {
            $conditions .= " AND isSupply = 1";
        }
        if ($request->isNonParent) {
            $conditions .= " AND parent_exam_typeID is not null";
        }
        if ($request->isNonParent) {
            $conditions .= " AND parent_exam_typeID is not null";
        }
        try {
            $sql = "SELECT typeID AS id, typeName as name, typeDesc, can_faculty_create AS canFacultyCreate, canShow, isInternal, isSupply, parent_exam_typeID as parentExamTypeId FROM exam_type $conditions";
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTypes;
    }
    /**
     * get exam registration fees types
     *
     * @param int $examRegId
     * @param string $examType
     *
     * @throws ProfessionalException
     * @return list $regFeeTypes
     */
    public function getFeeTypesForExamRegistration($examRegId, $examType = ExamType::REGULAR, $isCommon = NULL) {
        $examRegId = $this->realEscapeString($examRegId);
        $examType = $this->realEscapeString($examType);
        $sql = NULL;
        $sqlRegFeeJoinCondition = NULL;
        $sqlRegFeeJoinTable = NULL;
        $conditions = NULL;
        if(!$examRegId){
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST,"Exam registration Id required!");
        }
        if ( $isCommon === true ) {
            $conditions .= " AND eft.everySubject = 0 ";
        }
        else if ( $isCommon === false ) {
            $conditions .= " AND eft.everySubject = 1 ";
        }
        if($examType == ExamType::REGULAR){
            $sqlRegFeeJoinCondition = " AND erf.examregID = $examRegId";
            $sqlRegFeeJoinTable = "exam_registration_fees";
            $sqlColumns = ",erf.examfeesAmount AS examRegAmount";
        }
        else if($examType == ExamType::SUPPLY){
            $sqlRegFeeJoinCondition = " AND erf.exam_supplementary_id = $examRegId";
            $sqlRegFeeJoinTable = "supply_improve_exam_fees";
            $sqlColumns = ",erf.supply_feesAmount AS supplyAmount,
            erf.improve_feesAmount AS improveAmount";
        }
        else{
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST,"Invalid exam type!");
        }
        try {
            $sql = "SELECT
                eft.examfeesID AS id,
                eft.examfeesName AS name,
                NOT eft.everySubject AS isCommonFee
                $sqlColumns
            FROM
                exam_feestype eft
                    LEFT JOIN
                $sqlRegFeeJoinTable erf ON erf.examfeesID = eft.examfeesID
                    $sqlRegFeeJoinCondition
            WHERE
                eft.examfeesID IS NOT NULL
                $conditions";
            $regFeeTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $regFeeTypes;
    }
    /**
     * get exam registration Fine types
     *
     * @param int $examRegId
     * @param string $examType
     *
     * @throws ProfessionalException
     * @return list $regFeeTypes
     */
    public function getFineTypesForExamRegistration($examRegId, $examType = ExamType::REGULAR) {
        $examRegId = $this->realEscapeString($examRegId);
        $examType = $this->realEscapeString($examType);
        $sql = NULL;
        $sqlRegFineJoinCondition = NULL;
        $sqlRegFineJoinTable = NULL;
        if(!$examRegId){
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST,"Exam registration Id required!");
        }
        if($examType == ExamType::REGULAR){
            $sqlRegFineJoinCondition = " AND erf.examregID = $examRegId";
            $sqlRegFineJoinTable = "exam_registration_fine";
            $sqlColumns = ",erf.examfineAmount,
            erf.lastDate AS endDate,
            erf.startDate,
            erf.verificationDate";
        }
        else if($examType == ExamType::SUPPLY){
            $sqlRegFineJoinCondition = " AND erf.exam_supplementary_id = $examRegId";
            $sqlRegFineJoinTable = "supply_improve_exam_fine";
            $sqlColumns = ",erf.supply_fineAmount AS supplyFineAmount,
            erf.supply_startDate AS supplyStartDate,
            erf.supply_endDate AS supplyEndDate,
            erf.supply_verification_date AS supplyVerificationDate,
            erf.improve_fineAmount AS improveFineAmount,
            erf.improve_startDate AS improveStartDate,
            erf.improve_endDate AS improveEndDate,
            erf.improvement_verification_date AS improveVerificationDate";
        }
        else{
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST,"Invalid exam type!");
        }
        try {
            $sql = "SELECT
                eft.examfineID AS id,
                eft.examfineName AS name,
                eft.priority
                $sqlColumns
            FROM
                exam_finetype eft
                    LEFT JOIN
                $sqlRegFineJoinTable erf ON erf.examfineID = eft.examfineID
                    $sqlRegFineJoinCondition
            ORDER BY eft.priority ASC";
            $regFineTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $regFineTypes;
    }
    public function getAssignedPaymentOptions ( $examRegId, $examType = ExamType::REGULAR ) {
        $sql = null;
        $paymentOptions = null;
        $examRegistrationType = null;
        $examRegId = $this->realEscapeString($examRegId);
        $examType = $this->realEscapeString($examType);
        if ( $examType === ExamType::REGULAR ) {
            $examRegistrationType = "regular";
        }
        else if ( $examType === ExamType::SUPPLY ) {
            $examRegistrationType = "supplementary";
        }
        else {
            throw new ProfessionalException( ProfessionalException::INVALID_REQUEST, "Invalid exam-type");
        }
        try {
            $sql = "SELECT id, exam_paymentmethod_id AS paymentMethod, '$examType' AS examType, exam_registration_type_id AS examRegId FROM exam_paymentmethod_settings WHERE exam_registration_type = '$examRegistrationType' AND exam_registration_type_id = $examRegId ";
            $paymentOptions = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $paymentOptions;
    }
    /**
     * @param DeleteExcludedStudentRequest $request
     * @throws ProfessionalException
     * @author jithinvijayan
     */
    public function deleteExcludedStudentsFromExam(DeleteExcludedStudentRequest $request)
    {
        $request = $this->realEscapeObject($request);
        if (empty($request->batchId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_BATCH_ID, "Invalid batch details given");
        }
        if (empty($request->examId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_EXAM_ID, "Invalid exan details given");
        }
        $sql = "DELETE FROM exam_excluded_students WHERE batchID = $request->batchId AND examID = $request->examId";
        if (!empty($request->studentId)) {
            $sql .= " studentID =$request->studentId ";
        }
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $examTypeId
     * @return mixed
     * @throws ProfessionalException
     * @author jithinvijayan
     */
    public function getExamTypeNameById($examTypeId)
    {
        $examTypeId = $this->realEscapeString($examTypeId);
        if (empty($examTypeId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_EXAM_TYPE_ID, "Invalid exam type");
        }
        $sql = "SELECT typeName FROM exam_type WHERE typeID=$examTypeId";
        try {
            return $this->executeQueryForObject($sql)->typeName;
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $studentId
     * @param $semId
     * @param $batchId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getSubjectWiseStudentInternalMarks($studentId, $semId, $batchId){
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $batchId = $this->realEscapeString($batchId);
        $studentExamMarks=[];
        $sql ="SELECT studentID, studentName, batchName, semName, examTypeID, typeName, examID, examName, examTotalMarks, if(marksObtained=-1,'A',if(marksObtained<0,'MAL',marksObtained)) as marksObtained , totalMarksObtained, totalMaxMark, (totalMarksObtained/totalMaxMark)*100 as totalPercentage, weightedPercentage, subjectName, subjectCode, subjectID FROM ( SELECT
                sa.studentID,
                sa.studentName,
                bth.batchName,
                sem.semName,
                exm.examTypeID,
                exm.examID,
                exm.examName,
                exm.examTotalMarks,
                stm.marksObtained,
                stm.percentage,
                et.typeName,
                      (SELECT sum(percentage)/count(ex.examID) FROM exam ex INNER JOIN exam_type et ON
                        ex.examTypeID = et.typeID
                        LEFT JOIN student_marks sm ON sm.examID = ex.examID AND et.typeID = sm.examTypeID
                        AND ex.batchID = sm.batchID AND ex.semID = sm.semID
                             WHERE ex.examTypeID = exm.examTypeID and ex.batchID = $batchId
                            AND ex.semID = $semId
                            AND sm.studentID = $studentId ) as weightedPercentage,
                (SELECT
                        SUM(IF(sm.marksObtained < 0,
                                0,
                                sm.marksObtained))
                    FROM
                        student_marks sm INNER JOIN exam ex ON ex.examID=sm.examID
                    WHERE
                        ex.examTypeID = exm.examTypeID
                            AND ex.batchID = $batchId
                            AND ex.semID = $semId
                            AND sm.studentID = $studentId) AS totalMarksObtained,
                (SELECT
                        SUM(ex.examTotalMarks)
                    FROM
                        exam ex INNER JOIN student_marks sm ON sm.examTypeID=ex.examTypeID AND sm.examID=ex.examID
                    WHERE
                            ex.batchID = $batchId
                            AND ex.semID = $semId
                            AND sm.studentID = $studentId
                            AND ex.examTypeID=exm.examTypeID) AS totalMaxMark,
                (SELECT
                        SUM(examTotalMarks)
                    FROM
                        exam
                    WHERE
                        examTypeID = exm.examTypeID
                            AND batchID = $batchId
                            AND semID = $semId) AS weightedMaxMark,
            sub.subjectName as subjectCode, sub.subjectDesc as subjectName, sub.subjectID
            FROM
                exam exm INNER JOIN exam_type et ON et.typeID=exm.examTypeID INNER JOIN studentaccount sa ON sa.batchID=exm.batchID AND sa.studentID=$studentId INNER JOIN batches bth ON bth.batchID=exm.batchID INNER JOIN semesters sem ON sem.semID=exm.semID
                    LEFT JOIN
                student_marks stm ON stm.examID = exm.examID
                    AND stm.examTypeID = exm.examTypeID left join subjects sub on sub.subjectID = exm.subjectID
            WHERE
                exm.batchID = $batchId AND exm.semID = $semId
                    AND stm.studentID = $studentId
            ORDER BY stm.examTypeID , stm.examID) as studentMarks";
        try {
            $studentExamMarks = $this->executeQueryForList($sql,$this->internalExamMapper[InternalExamMapper::GET_SUBJECT_WISE_STUDENT_MARKS]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(),$e->getCode());
        }
        return $studentExamMarks;
    }
    /**
     * @param $studentId
     * @param $batchId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getBothUniversityAndInternalMarksForAllSemesters($studentId, $batchId){
        $universityAndInternalExamDetails = [];
        $universityAndInternalExamDetails = $this->getStudentUniversityResults($studentId, $batchId, null, true);
        $universityAndInternalExamDetails = $this->getInternalMarkDetails($universityAndInternalExamDetails);
        $universityAndInternalExamDetails = $this->mergeUniversityAndInternal($universityAndInternalExamDetails);
        $universityAndInternalExamDetails = $this->getSubjectWiseAttendanceDetails($universityAndInternalExamDetails, $studentId, $batchId);
        $universityAndInternalExamDetails = $this->mergeAttendanceDetails($universityAndInternalExamDetails);
        return $universityAndInternalExamDetails;
    }
    private function getSubjectWiseAttendanceDetails($universityAndInternalExamDetails, $studentId, $batchId){
        foreach($universityAndInternalExamDetails->semesters as $semester){
            $semester->subjectWiseAttendanceDetails = AttendanceService::getInstance()->getSubjectWiseStudentAttendanceWithAttendanceRulesConsidered($studentId, $batchId, $semester->id);
        }
        return $universityAndInternalExamDetails;
    }
    private function mergeAttendanceDetails($examList){
        foreach ($examList->semesters as $key => $semester) {
            foreach($semester->subjects as $subject){
                foreach ($semester->subjectWiseAttendanceDetails as $attendenceIndex => $subjectWiseAttendanceDetails) {
                    if($subjectWiseAttendanceDetails->subjectID == $subject->id){
                        $subject->attendancePercent = $subjectWiseAttendanceDetails->attPercent;
                        unset($semester->subjectWiseAttendanceDetails[$attendenceIndex]);
                    }
                }
            }
            if(!empty($semester->subjectWiseAttendanceDetails)){
                foreach($semester->subjectWiseAttendanceDetails as $attendenceIndex => $subjectWiseAttendanceDetails){
                    $newSubjectDetails = null;
                    $newSubjectDetails = new Subject();
                    $newSubjectDetails->id = $subjectWiseAttendanceDetails->subjectID;
                    $newSubjectDetails->code = $subjectWiseAttendanceDetails->subjectName;
                    $newSubjectDetails->name = $subjectWiseAttendanceDetails->subjectDesc;
                    $newSubjectDetails->attendancePercent = $subjectWiseAttendanceDetails->attPercent;
                    $semester->subjects[] =  $newSubjectDetails;
                }
            }
            unset($semester->subjectWiseAttendanceDetails);
        }
        return $examList;
    }
   private function getInternalMarkDetails($universityExamDetails)
    {
        foreach ($universityExamDetails->semesters as $key => $semester) {
            $semester->subjects = null;
            $semester->subjects = $this->getSubjectWiseStudentInternalMarks($universityExamDetails->studentId, $semester->id, $universityExamDetails->batch->id);
        }
        return $universityExamDetails;
    }
    private function mergeUniversityAndInternal($examList){
        foreach ($examList->semesters as $key => $semester) {
            foreach($semester->subjects as $subject){
                $subject->universityResult = null;
                foreach ($semester->universityResult as $universityIndex => $universityResult) {
                    if($universityResult->subjectId == $subject->id){
                        $subject->universityResult = $universityResult;
                        unset($semester->universityResult[$universityIndex]);
                    }
                }
            }
            if(!empty($semester->universityResult)){
                foreach($semester->universityResult as $universityIndex => $universityResult){
                    $newInternalExamDetails = null;
                    $newInternalExamDetails = new Subject();
                    $newInternalExamDetails->id = $universityResult->subjectId;
                    $newInternalExamDetails->name = $universityResult->subjectName;
                    $newInternalExamDetails->code = $universityResult->subjectCode;
                    $newInternalExamDetails->universityResult = $universityResult;
                    $semester->subjects[] = $newInternalExamDetails;
                }
            }
            unset($semester->universityResult);
        }
        return $examList;
    }
    /**
     * @param $studentId
     * @param $subjectId
     * @return mixed
     * @throws ProfessionalException
     */
    public function getSupplyAttemptCount($studentId, $subjectId)
    {
        $studentId = $this->realEscapeString($studentId);
        $subjectId = $this->realEscapeString($subjectId);
        if (empty($studentId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid student");
        }
        if (empty($subjectId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid subject");
        }
        $sql = "SELECT COUNT(esss.exam_supplementary_id) AS supplyAttemptCount FROM exam_supplementary_student_subjects esss INNER JOIN exam e ON e.examID = esss.examID WHERE esss.studentID = $studentId AND e.subjectID = $subjectId";
        try {
            return $this->executeQueryForObject($sql)->supplyAttemptCount;
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $hallId
     * @param $examTypeId
     * @param $semId
     * @param $patternId
     * @return Object
     * @throws ProfessionalException
     */
    public function getStudentsInExamHall($hallId, $examTypeId, $semId, $patternId, $batchId = null, $examDate = null)
    {
        $hallId = $this->realEscapeString($hallId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $semId = $this->realEscapeString($semId);
        $patternId = $this->realEscapeString($patternId);
        $batchId = $this->realEscapeString($batchId);
        $sqlCondition = "";
        try {
            if (empty($hallId)) {
                throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid hall");
            }
            if (empty($examTypeId)) {
                throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam type");
            }
            if (empty($semId)) {
                throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid semester");
            }
            if (empty($patternId)) {
                throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid course");
            }
            if (!empty($batchId)) {
                $sqlCondition .= " AND b.batchID = '$batchId'";
            }
            if (!empty($examDate)) {
                $sqlCondition .= " AND e.examDate = '$examDate'";
            }
            $sql = "SELECT
                eh.hallName,
                sa.studentID AS studentId,
                sa.studentName,
                sa.rollNo,
                sa.regNo,
                e.examID,
                e.examName,
                e.examDate,
                e.subjectID,
                e.examStartTime,
                e.examEndTime,
                b.batchID AS batchId,
                b.batchName,
                sa.secondlangaugeID,
                sl.secondLangaugeName,
                s.subjectID,
                s.subjectName,
                s.subjectDesc,
                s.syllabusName,
                IF(s.secondLangaugeId IS NOT NULL, 1, 0) AS isSecondLanguage,
                IF(sgs.subjectGroups_id = 0, 0, 1) AS isGroupedSubject,
                sgs.subjectGroups_id AS subjectGroupId,
                sg.name AS subjectGroupName,
                sg.code AS subjectGroupCode
            FROM
                exam_halls eh
            INNER JOIN exam_hall_arranged_students ehas ON
                ehas.hallID = eh.hallID
            INNER JOIN exam e ON
                e.examID = ehas.examID
            INNER JOIN batches b ON
                b.batchID = e.batchID
            INNER JOIN studentaccount sa ON
                sa.studentID = ehas.studentID
                AND sa.batchID = b.batchID
                AND sa.batchID = e.batchID
            INNER JOIN subjects s ON
                s.subjectID = e.subjectID
            LEFT JOIN secondLangauge sl ON
                sl.secondlangaugeID = s.secondlangaugeID
            LEFT JOIN subjectGroups_subjects sgs ON
                sgs.subjects_id = s.subjectID
                AND sgs.subjects_id = e.subjectID
                AND sgs.batches_id = e.batchID
                AND sgs.batches_id = b.batchID
                 AND sgs.batches_id = sa.batchID
                AND sgs.semesters_id = e.semID
            LEFT JOIN subjectGroups sg ON
                sg.id = sgs.subjectGroups_id
            WHERE
                eh.hallID = '$hallId'
                AND e.examTypeID = '$examTypeId'
                AND e.semID = '$semId'
                AND b.patternID = '$patternId'
                $sqlCondition
            ORDER BY sa.regNo";
            $studentList = $this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentList;
    }
    /**
     * @param $request
     * @return array|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getInternalExamSubjectBatches( $request ) {
        $request = $this->realEscapeObject($request);
        $sql = null;
        $batches = null;
        try {
            $sql = "SELECT e.batchID AS batchId FROM exam e WHERE e.subjectID = $request->subjectId AND e.examregID IS NULL AND e.supply_examreg_id IS NULL AND e.semID = $request->semId ";
            $batches = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $batches;
    }
    /**
     * Returns exam absetees count
     * @param $examId
     * @return $absenteesCount
     * @throws ProfessionalException
     */
    public function getExamAbsenteesCount($examId)
    {
        $examId = $this->realEscapeString($examId);
        if (empty($examId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        $sql = "SELECT COUNT(studentID) AS absenteesCount FROM exam_attendance WHERE isAbsent = 1 AND examID = $examId";
        try {
            return $this->executeQueryForObject($sql)->absenteesCount;
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * To get the batchID of the student by semester
     *
     * @param $studentId
     * @param $semId
     * @return $batchId|null
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getStudentExamBatchBySemester($studentId, $semId) {
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $sql = null;
        try {
            $sql = "SELECT DISTINCT batchID FROM internal_marks WHERE semID = $semId AND studentID IN ($studentId";
            return $this->executeQueryForObject($sql)->batchID;
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return null;
    }
    public function getSessionalExamStudentDetails($examTypeID,$subbatchID,$batchID,$subjectID,$semID,$sortOrderColumn, $examID = NULL) {
        $examTypeID  = $this->realEscapeString($examTypeID);
        $subbatchID  = $this->realEscapeString($subbatchID);
        $batchID  = $this->realEscapeString($batchID);
        $subjectID  = $this->realEscapeString($subjectID);
        $semID  = $this->realEscapeString($semID);
        $examID = $this->realEscapeString($examID);
        $sortOrderColumn  = $this->realEscapeString($sortOrderColumn);
        $examTypeDetails = ExamService::getInstance()->getExamTypeById($examTypeID);
        $parent = (int)$examTypeDetails->parent_exam_typeID;
        $condition = $examID?" and sm.examID = $examID ":"";
        if($parent)
        {
            if ($subbatchID)
            {
                $sql = "SELECT std.studentID, std.studentName, std.rollNo, std.regNo, std.batchID, ecsub.studentaccount_id, subs.subbatchID, ecbat.batch_id, typ.typeName, typ.parent_exam_typeID, ecsub.subjects_id,ecstd.is_paid,sm.marksObtained,sm.markID,ba.batchName,ba.semID
                FROM
                    exam_type typ
                    INNER JOIN ec_sessional_exam_registration ecreg ON ecreg.exam_type_id = typ.typeID
                    INNER JOIN ec_sessional_exam_student_details ecstd ON ecstd.ec_sessional_exam_registration_id = ecreg.id
                    INNER JOIN ec_sessional_exam_registered_batch ecbat ON ecbat.sessional_exam_reg_id = ecreg.id
                    INNER JOIN studentaccount std ON std.studentID = ecstd.studentaccount_id AND ecbat.batch_id = std.batchID
                    INNER JOIN ec_sessional_exam_student_subjects ecsub ON ecsub.ec_sessional_exam_registration_id = ecreg.id AND ecsub.studentaccount_id = std.studentID
                    INNER JOIN batches ba ON ba.batchID = std.batchID
                    INNER JOIN subbatch_student subs ON subs.studentID = std.studentID
                    LEFT JOIN student_marks sm on sm.batchID = ecbat.batch_id and sm.subjectID = ecsub.subjects_id and sm.studentID = ecstd.studentaccount_id and sm.subjectID = ecsub.subjects_id and typ.typeID = sm.examTypeID $condition
                WHERE
                    typ.typeID = $examTypeID AND typ.isInternal = 1 AND subs.subbatchID = $subbatchID AND std.batchID = $batchID AND ecsub.subjects_id = $subjectID and ecstd.is_paid = 1 order by std.$sortOrderColumn;";
            }
            else
            {
                $sql = "SELECT std.studentID, std.studentName, std.rollNo, std.regNo, std.batchID,ecsub.studentaccount_id, ecbat.batch_id, typ.typeName, typ.parent_exam_typeID, ecsub.subjects_id,ecstd.is_paid,ba.batchName,ba.semID
                FROM exam_type typ
                    INNER JOIN ec_sessional_exam_registration ecreg ON ecreg.exam_type_id = typ.typeID
                    inner join ec_sessional_exam_student_details ecstd ON ecstd.ec_sessional_exam_registration_id = ecreg.id
                    INNER JOIN ec_sessional_exam_registered_batch ecbat ON ecbat.sessional_exam_reg_id = ecreg.id
                    INNER JOIN studentaccount std ON std.studentID = ecstd.studentaccount_id AND ecbat.batch_id = std.batchID
                    INNER JOIN batches ba ON ba.batchID = std.batchID
                    INNER JOIN  ec_sessional_exam_student_subjects ecsub ON ecsub.ec_sessional_exam_registration_id = ecreg.id AND ecsub.studentaccount_id = std.studentID
                WHERE typ.typeID = $examTypeID AND typ.isInternal = 1 AND ecbat.batch_id = $batchID AND ecstd.is_paid =1 AND ecsub.subjects_id = $subjectID and ecstd.is_paid = 1 order by std.$sortOrderColumn;";
            }
        }
        else
        {
            $isCurrentSem = SemesterService::getInstance()->isCurrentSemester($batchID, $semID);
            if ($subbatchID)
            {
                if($isCurrentSem)
                {
                    $sql = "SELECT sa.studentID, sa.studentName, sa.rollNo, sa.studentAccount, sa.regNo, sa.batchID,ba.batchName,ba.semID
                    FROM studentaccount sa
                        INNER JOIN subbatch_student ss ON sa.studentID = ss.studentID
                        INNER JOIN batches ba ON ba.batchID = sa.batchID
                        INNER JOIN semesters sem ON sem.semID = ba.semID
                        INNER JOIN semesters joinedSem ON sa.joiningSemId = joinedSem.semID
                    WHERE sa.batchID = $batchID AND ss.subbatchID = $subbatchID AND joinedSem.orderNo <= sem.orderNo
                    ORDER BY sa.$sortOrderColumn;";
                }
                else
                {
                    $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semID);
                    $sql = "SELECT st.* FROM (SELECT sa.studentID, sa.studentName, sa.rollNo,sa.regNo, sa.batchID ,ba.batchName,ba.semID
                    FROM studentaccount sa
                    INNER JOIN batches ba ON sa.batchID = ba.batchID
                    INNER JOIN semesters sem ON sem.semID = ba.semID
                    INNER JOIN semesters joinedSem ON sa.joiningSemId = joinedSem.semID
                    INNER JOIN subbatch_student ss ON sa.studentID = ss.studentID
                    WHERE ba.batchID = $batchID AND joinedSem.orderNo <= $semDetails->orderNo AND ss.subbatchID = $subbatchID
                    UNION
                    SELECT sa.studentID,sa.studentName, sa.rollNo,sa.regNo, fs.previousBatch ,ba.batchName,$semID FROM failed_students fs
                    INNER JOIN studentaccount sa ON sa.studentID = fs.studentID
                    INNER JOIN semesters fsem ON fsem.semID = fs.failedInSemester
                    INNER JOIN semesters joinedSem ON sa.joiningSemId = joinedSem.semID
                    INNER JOIN subbatch_student ss ON sa.studentID = ss.studentID
                    INNER JOIN batches ba ON fs.previousBatch = ba.batchID
                    WHERE fs.previousBatch = $batchID AND fsem.orderNo > $semDetails->orderNo
                    AND joinedSem.orderNo <= $semDetails->orderNo AND ss.subbatchID = $subbatchID) st ORDER BY st.$sortOrderColumn ";
                }
            }
            else
            {
                if($isCurrentSem)
                {
                    $sql = "SELECT sa.studentID, sa.studentName, sa.rollNo, sa.regNo,sa.batchID,ba.batchName,ba.semID
                    FROM studentaccount sa
                        INNER JOIN batches ba ON ba.batchID = sa.batchID
                        INNER JOIN semesters sem ON sem.semID = ba.semID
                        INNER JOIN semesters joinedSem ON sa.joiningSemId = joinedSem.semID
                    WHERE sa.batchID = $batchID AND joinedSem.orderNo <= sem.orderNo
                    ORDER BY sa.$sortOrderColumn";
                }
                else
                {
                    $semDetails = SemesterService::getInstance()->getSemDetailsBySemId($semID);
                    $sql = "SELECT sa.studentID, sa.studentName, sa.rollNo, sa.studentAccount,sa.regNo,sa.batchID ,ba.batchName,ba.semID
                    FROM studentaccount sa
                        INNER JOIN batches ba ON sa.batchID =  ba.batchID
                        INNER JOIN semesters joinedSem ON sa.joiningSemId = joinedSem.semID
                    WHERE ba.batchID = $batchID AND joinedSem.orderNo <= $semDetails->orderNo
                    UNION
                    SELECT sa.studentID, sa.studentName, sa.rollNo, sa.studentAccount,sa.regNo,sa.batchID ,ba.batchName,fsem.semID
                    FROM failed_students fs
                        LEFT JOIN studentaccount sa on fs.studentID= sa.studentID
                        INNER JOIN batches ba ON fs.previousBatch =  ba.batchID
                        INNER JOIN semesters fsem on fsem.semID = fs.failedInSemester
                        INNER JOIN semesters joinedSem on sa.joiningSemId = joinedSem.semID
                    WHERE previousBatch =$batchID AND fsem.orderNo > $semDetails->orderNo AND joinedSem.orderNo <= $semDetails->orderNo
                    ORDER BY $sortOrderColumn";
                }
            }
        }
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getExamRegistrationDetailsByExamTypeID($examTypeID)
    {
        $sql = "select id, name, exam_type_id, start_date, end_date, with_out_fine_date from ec_sessional_exam_registration where exam_type_id = $examTypeID ";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function createRetestSessionalExam($examName,$subjectID,$examTotalMarks,$batchID,$semID,$examTypeID,$staffID,$subbatchID)
    {
        $sql = "INSERT INTO exam (examName , subjectID, examTotalMarks, batchID, semID, examTypeID, created_by, subbatchID) values ('$examName','$subjectID','$examTotalMarks','$batchID','$semID','$examTypeID', '$staffID','$subbatchID')";
        try {
            $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getSessionalExamDetails($batchID,$subjectID,$examType,$subbatchID,$semID)
    {
        $sql = "select examID, examName, examTotalMarks, semID, examStartTime, examEndTime,examDate from exam where batchID=$batchID and subjectID=$subjectID and examTypeID=$examType AND subbatchID=$subbatchID AND semID = $semID";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $request
     * @return List
     * @throws ProfessionalException
     */
    public function getStudentsListExamHallwise($request)
    {
        $request = $this->realEscapeObject($request);
        $sqlCondition = "";
        try {
            if (!empty($request->hallId)) {
                $sqlCondition .= " AND eh.hallID = '$request->hallId'";
            }
            if (!empty($request->examTypeId)) {
                $sqlCondition .= " AND e.examTypeID = '$request->examTypeId'";
            }
            if (!empty($request->semId)) {
                $sqlCondition .= " AND e.semID = '$request->semId'";
            }
            if (!empty($request->patternId)) {
                $sqlCondition .= " AND b.patternID = '$request->patternId'";
            }
            if (!empty($request->batchId)) {
                $sqlCondition .= " AND b.batchID = '$request->batchId'";
            }
            if (!empty($request->examDate)) {
                $sqlCondition .= " AND e.examDate = '$request->examDate'";
            }
            if (!empty($request->startTime)) {
                if (!empty($request->startTimeFormatted)) {
                    $sqlCondition .= " AND DATE_FORMAT(CAST(STR_TO_DATE(e.examStartTime,'%l:%i%p') AS DATETIME),'%r') = '$request->startTimeFormatted'";
                }else{
                    $sqlCondition .= " AND e.examStartTime = '$request->startTime'";
                }
            }
            $sql = "SELECT
                eh.hallID,
                eh.hallName,
                eh.noofseat AS seatCount,
                eh.studentperseat AS studentPerSeat,
                sa.studentID AS studentId,
                sa.studentName,
                sa.rollNo,
                sa.regNo,
                e.examID,
                e.semID,
                e.examDate,
                e.subjectID,
                e.examStartTime,
                e.examEndTime,
                b.batchID AS batchId,
                b.patternID,
                b.batchName,
                cp.patternName,
                sa.secondlangaugeID,
                s.subjectID,
                s.subjectName,
                s.subjectDesc,
                s.syllabusName
            FROM
                exam_halls eh
            INNER JOIN exam_hall_arranged_students ehas ON
                ehas.hallID = eh.hallID
            INNER JOIN exam e ON
                e.examID = ehas.examID
            INNER JOIN batches b ON
                b.batchID = e.batchID
            INNER JOIN course_pattern cp ON
                cp.patternID = b.patternID
            INNER JOIN studentaccount sa ON
                sa.studentID = ehas.studentID
                AND sa.batchID = b.batchID
                AND sa.batchID = e.batchID
            INNER JOIN subjects s ON
                s.subjectID = e.subjectID
            WHERE
                1=1
                $sqlCondition
            ORDER BY sa.regNo";
            $studentList = $this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentList;
    }
    public function isConfirmedAssessmentMark($examDetails,$subjectId,$subBatchId = NULL) {
        $examDetails = $this->realEscapeObject($examDetails);
        $subjectId = $this->realEscapeString($subjectId);
        $subBatchId = $this->realEscapeString($subBatchId);
        try {
           $sql_confirm = "select isAproved from aprove_exam_marks am inner join exam ex on ex.batchID = am.batchID and ex.semID = am.semID and ex.examID = am.examID where am.batchID =".$examDetails->batchID." and am.semID = ".$examDetails->semID." and am.examTypeID = ".$examDetails->examTypeID." and subjectID = ".$subjectId."";
            if ($subBatchId) {
                $sql_confirm .= " and am.subbatchID = " . $subBatchId;
            }
            return $this->executeQueryForObject($sql_confirm)->isAproved;
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return null;
    }
    public function checkAssessmentMarkByExamId($examDetails) {
        $examDetails = $this->realEscapeObject($examDetails);
        try {
           $sql_check = "SELECT DISTINCT markID FROM student_marks WHERE examID = ".$examDetails->examID."";
           $assessmentMarks = $this->executeQueryForList($sql_check);
           if(count($assessmentMarks)){
                $sql_check_question_mark = "SELECT id FROM assessment_student_marks WHERE assessment_id = ".$examDetails->examID." AND assessment_type = 'EXAM'";
                $assessmentQuestionMarks = $this->executeQueryForList($sql_check_question_mark);
                if(count($assessmentQuestionMarks)==0){
                    $enableAssessmentQuestionMarkEntry = 0;
                    return $enableAssessmentQuestionMarkEntry;
                }
           }
           return $enableAssessmentQuestionMarkEntry = 1;
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
    }
    public function checkInternalSubjectPresentInThatBatch ($batchId,$semId){
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectPresent = null;
        $sql = null;
        try {
            $sql = "SELECT subjectID FROM exam_subjectcredit WHERE batchID = $batchId AND semID = $semId AND isInternal = 1 ";
            $subjectPresent =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $subjectPresent;
    }
    public function createSessionalMarkSettings($sessionalExamSettings)
    {
        $settings = $this->realEscapeObject($sessionalExamSettings);
        $sql = "INSERT INTO sessional_marks_settings (batchID, semID, subjectID, fromDate, toDate, examTypeID) VALUES ($settings->batchID$settings->semID$settings->subjectID, '$settings->fromDate', '$settings->toDate', '$settings->examTypeID');";
        try
        {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
    }
    public function getTransactionDetails ($studentId,$examRegId, $status, $examType){
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $status = $this->realEscapeString($status);
        $examType = $this->realEscapeString($examType);
        $sql = null;
        try {
            $sql = "SELECT
                txnID AS linTxnId,
                payment_gateway_txn_id AS paymentGateTxnId
            FROM
                exam_online_payment
            WHERE
                status = '$status'
                AND studentID = $studentId
                AND exam_registration_type = '$examType'
                AND exam_registration_type_id = $examRegId";
            $transaction =  $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $transaction;
    }
    public function getExamRegStudentSettings ($batchId){
        $batchId = $this->realEscapeString($batchId);
        $sql = null;
        try {
            $sql = "SELECT considerOpencourse,considerEvaluation FROM exam_reg_student_settings WHERE batches_id = $batchId";
            $examRegStudentSettings =  $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $examRegStudentSettings;
    }
    public function getExamsListForReport ($examSearchRequest){
        $examSearchRequest = $this->realEscapeObject($examSearchRequest);
        $sql = null;
        $sqlCondition = "";
        if (empty($examSearchRequest->examType)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Exam type is null");
        }
        else{
            if ($examSearchRequest->examRegId) {
                if ($examSearchRequest->examType == ExamType::REGULAR) {
                    $sqlCondition .= " AND ex.examregID = $examSearchRequest->examRegId ";
                }
                else if ($examSearchRequest->examType == ExamType::SUPPLY) {
                    $sqlCondition .= " AND ex.supply_examreg_id = $examSearchRequest->examRegId ";
                }
            }
        }
        if ($examSearchRequest->examDate) {
            $sqlCondition .= " AND ex.examDate = '$examSearchRequest->examDate";
        }
        if ($examSearchRequest->semId) {
            $sqlCondition .= " AND ex.semID = '$examSearchRequest->semId";
        }
        try {
            $sql = "SELECT
                ex.examID AS id,
                ex.examName,
                ex.examTotalMarks,
                ex.examDate,
                ex.examStartTime,
                ex.examEndTime,
                b.batchID AS batchId,
                b.batchName,
                b.batchDesc,
                s.subjectID AS subjectId,
                s.subjectName,
                s.subjectDesc,
                s.syllabusName,
                sem.semID AS semId,
                sem.semName
            FROM
                exam ex
            INNER JOIN batches b ON
                b.batchID = ex.batchID
            INNER JOIN subjects s ON
                s.subjectID = ex.subjectID
            INNER JOIN semesters sem ON
                sem.semID = ex.semID
            WHERE
                ex.examID = ex.examID
                $sqlCondition
            ORDER BY ex.examDate";
            $examRegStudentSettings =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $examRegStudentSettings;
    }
    public function getRegularExamsOfStudent ($studentId){
        $studentId = $this->realEscapeString($studentId);
        if(empty($studentId)){
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Student id is null");
        }
        $sql = null;
        try {
            $sql = "SELECT
                DISTINCT er.examregID AS examRegId,
                erb.semID AS semId
            FROM
                exam_registration er
            INNER JOIN exam_registration_batches erb ON
                erb.examregID = er.examregID
            INNER JOIN studentaccount sa ON
                sa.batchID = erb.batchID
            INNER JOIN exam_reg_studentchallan ersc ON
                ersc.studentID = sa.studentID
                AND ersc.examregID = er.examregID
            WHERE
                ersc.studentID = $studentId";
            $regularExams =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $regularExams;
    }
    public function getSupplyExamsOfStudent ($studentId){
        $studentId = $this->realEscapeString($studentId);
        if(empty($studentId)){
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Student id is null");
        }
        $sql = null;
        try {
            $sql = "SELECT
                es.id,
                es.supplyDesc AS name,
                es.semID AS semId
            FROM
                exam_supplementary es
            INNER JOIN exam_supplementary_student_details essd ON
                essd.exam_supplementary_id = es.id
            WHERE
                essd.studentID = $studentId";
            $supplyExams =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $supplyExams;
    }
    /**
     * Is sessional exam mark submitted
     * @param int $examId
     * @return boolean
     * @throws ProfessionalException
     */
    public function isSessionalExamMarkSubmittedByExamType($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "select aem.isAproved
        from aprove_exam_marks aem
        INNER JOIN exam ex ON ex.examID=aem.examId and ex.subbatchID in (null,aem.subbatchID)
        WHERE ex.batchID=$request->batchId AND ex.semID=$request->semId AND ex.subjectID=$request->subjectId AND ex.subbatchID=$request->subbatchId AND ex.examTypeID=$request->examTypeId group by aem.examTypeID order by aem.isAproved desc";
        try {
            $confirmed = $this->executeQueryForObject($sql)->isAproved;
            if ($confirmed) {
                return true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return false;
    }
    public function getStaffPseudoSubjectDetailsInRetestExams($pseudoSubjectId,$staffId,$examtypeId)
    {
        $pseudoSubjectId = $this->realEscapeString($pseudoSubjectId);
        $staffId = $this->realEscapeString($staffId);
        $examtypeId = $this->realEscapeString($examtypeId);
        $sql = "SELECT sbs.batchID,sbs.semID,sbs.subjectID,sbs.staffID,pss.subjectName,b.batchDesc,b.batchName,su.subbatchID,su.subbatchName,sta.staffName
        FROM exam_type typ
            INNER JOIN ec_sessional_exam_registration ecreg ON ecreg.exam_type_id = typ.typeID
            INNER JOIN ec_sessional_exam_student_details ecstd ON ecstd.ec_sessional_exam_registration_id = ecreg.id
            INNER JOIN ec_sessional_exam_registered_batch ecbat ON ecbat.sessional_exam_reg_id = ecreg.id
            INNER JOIN pseudosubjects_students ps on ps.studentID = ecstd.studentaccount_id
            INNER JOIN studentaccount std ON std.studentID = ps.studentID AND ecbat.batch_id = std.batchID
            INNER JOIN ec_sessional_exam_student_subjects ecsub ON ecsub.ec_sessional_exam_registration_id = ecreg.id AND ecsub.studentaccount_id = std.studentID
            INNER JOIN subbatch_student subs ON subs.studentID = std.studentID
            INNER JOIN subbatches su ON su.subbatchID=subs.subbatchID AND su.psID=ps.pseudosubjectID
            INNER JOIN sbs_relation sbs on sbs.subjectID = ecsub.subjects_id and ecbat.batch_id = sbs.batchID
            INNER JOIN pseudosubjects pss on ps.pseudosubjectID = pss.pseudosubjectID
            INNER JOIN pseudosubjects_sbs psbs on psbs.sbsID = sbs.sbsID and psbs.pseudosubjectID = ps.pseudosubjectID
            INNER JOIN batches b on b.batchID = sbs.batchID
            INNER JOIN staffaccounts sta ON sta.staffID = sbs.staffID
        WHERE
            typ.typeID = $examtypeId AND typ.isInternal = 1 and ps.pseudosubjectID = $pseudoSubjectId and sbs.staffID = $staffId and ecstd.is_paid = 1 group by ecbat.batch_id,su.subbatchID ORDER BY b.batchName;";
        try {
            $supplyExamsBatches =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $supplyExamsBatches;
    }
    public function getStaffPseudoSubjectDetails($pseudoSubjectId,$staffId)
    {
        $pseudoSubjectId = $this->realEscapeString($pseudoSubjectId);
        $staffId = $this->realEscapeString($staffId);
        $sql = "SELECT sbs.batchID,sbs.semID,sbs.subjectID,sbs.staffID,ps.subjectName,bat.batchDesc,bat.batchName,su.subbatchID,su.subbatchName,sta.staffName
        FROM pseudosubjects_sbs psbs
            INNER JOIN sbs_relation sbs ON sbs.sbsID = psbs.sbsID
            INNER JOIN pseudosubjects ps ON ps.pseudosubjectID = psbs.pseudosubjectID
            INNER JOIN subbatches su ON su.psID = psbs.pseudosubjectID AND su.batchID = sbs.batchID AND su.semID = sbs.semID
            INNER JOIN batches bat ON bat.batchID = sbs.batchID
            INNER JOIN staffaccounts sta ON sta.staffID = sbs.staffID
        WHERE psbs.pseudosubjectID = $pseudoSubjectId AND sbs.staffID = $staffId ORDER BY bat.batchName;";
        try {
            $supplyExamsBatches =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $supplyExamsBatches;
    }
    public function getSessionalExamSubbatchStudentMarks($pseudoSubjectId,$batchId,$subBatchId,$examId,$subjectId)
    {
        $pseudoSubjectId = $this->realEscapeString($pseudoSubjectId);
        $batchId = $this->realEscapeString($batchId);
        $subBatchId = $this->realEscapeString($subBatchId);
        $examId = $this->realEscapeString($examId);
        $subjectId = $this->realEscapeString($subjectId);
        $sortOrderColumn = BatchService::getInstance()->getStudentSortByColumnOfABatch($batchId);
        if (empty($sortOrderColumn)) {
            $sortOrderColumn = "rollNo";
        }
        $sql = "SELECT
        sta.studentID, sta.studentName,sta.rollNo,sta.regNo,mrk.markID, mrk.marksObtained, sta.batchID,mrk.examID,mrk.examTypeID,ba.batchName,ba.semID
        from pseudosubjects_students pss
        INNER JOIN studentaccount sta ON sta.studentID = pss.studentID
        INNER JOIN batches ba ON ba.batchID = sta.batchID
        INNER JOIN subbatch_student ss on ss.studentID = pss.studentID
        LEFT JOIN student_marks mrk ON mrk.studentID = sta.studentID AND mrk.batchID = sta.batchID and mrk.subjectID=$subjectId and mrk.examID=$examId
        where pss.pseudosubjectID= $pseudoSubjectId and sta.batchID = $batchId and ss.subbatchID = $subBatchId ORDER BY sta.batchID, $sortOrderColumn";
        try {
            $supplyExamsBatches =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $supplyExamsBatches;
    }
//start blockStudentFromExamRegistrationBySubject
    /**
     * @author Sibin
     */
    public function blockStudentFromExamRegistrationBySubject($studentId, $examregId, $subjectId, $reasonId, $isSupply)
    {
        global $COLLEGE_CODE;
        $studentId = (int)$this->realEscapeString($studentId);
        $examregId = (int)$this->realEscapeString($examregId);
        $subjectId = (int)$this->realEscapeString($subjectId);
        $reasonId =  (int) $this->realEscapeString($reasonId);
        $isSupply = (int)$this->realEscapeString($isSupply);
        if ($isSupply === 0) { //Regular Exam
            $examreg_id = $examregId;
            $supplyreg_id = 'NULL';
        } else if ($isSupply === 1) {
            $supplyreg_id = $examregId;
            $examreg_id = 'NULL';
        }
        $response = null;
        $condition = $isSupply ? " AND erbs.supplyreg_id = '$examregId" : " AND erbs.examreg_id = '$examregId";
        if ($reasonId === 0) {
            //$sql = "DELETE erbs.* FROM exam_reg_blocked_student erbs INNER JOIN exam_reg_block_reason erbr ON (erbr.id = erbs.reason_id) WHERE erbs.student_id = '$studentId' AND erbs.subject_id = '$subjectId' AND erbr.reason_type = '$reasonType' $condition ";
            $sql ="DELETE erbs.*
                    FROM exam_reg_blocked_student erbs
                        WHERE erbs.student_id ='$studentId'
                        AND erbs.subject_id = '$subjectId'
                        $condition";
        } else {
                $sql_check ="SELECT erbs.id
                                 FROM exam_reg_blocked_student erbs
                                    WHERE erbs.student_id ='$studentId'
                                    AND erbs.subject_id ='$subjectId'
                                        $condition";
                $id = $this->executeQueryForObject($sql_check)->id;
            if ($id) {
                $sql = "UPDATE exam_reg_blocked_student SET reason_id = $reasonId WHERE id = $id ";
            } else {
                $sql = "INSERT INTO exam_reg_blocked_student (student_id, subject_id, examreg_id, supplyreg_id, reason_id) VALUES ('$studentId', '$subjectId', $examreg_id$supplyreg_id, '$reasonId') ON DUPLICATE KEY UPDATE reason_id = VALUES(reason_id)";
            }
        }
        try {
            $response = $this->executeQuery($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    //end blockStudentFromExamRegistrationBySubject
    /**
     * @param  $request
     * @return array|Object
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamRegistrationsByBatchAndSem($request)
    {
        $request = $this->realEscapeObject($request);
        $batchId = $request->batchId;
        $semId = $request->semId;
        $condition = null;
        if ($request->examRegId) {
            $condition .= " AND er.examregID = '$request->examRegId";
        }
        $sql = null;
        $examRegistrations = [];
        try {
            $sql = "SELECT erb.examregID,erb.semID from exam_registration_batches erb
                        INNER JOIN exam_registration er ON er.examregID =erb.examregID
                        where erb.batchID='$batchId' and erb.semID='$semId' AND er.shortCourse = 0";
             $examRegistrations = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistrations;
    }
/**
     * @throws ProfessionalException
     * @author Sibin
     */
    public function addSessionalExamSettings($subjects,$batchId,$semId,$examTypeId,$batch)
    {
        $subjects = $this->realEscapeArray($subjects);
        $batch = $this->realEscapeObject($batch);
        $batchId= (int)$this->realEscapeString($batchId);
        $semId = (int)$this->realEscapeString($semId);
        $examTypeId= (int) $this->realEscapeString($examTypeId);
        $newfromDate=$batch['newfromDate'];
        $newtoDate =$batch['newtoDate'];
        foreach ($subjects as $subject) {
            $subject = (Object) $subject;
            $subjectId=(int)$subject->subjectID;
            $sql = "SELECT sms.batchID from sessional_marks_settings sms
                        where batchID ='$batchId'
                            and semID='$semId'
                            and subjectID ='$subjectId'
                            and examTypeID=' $examTypeId'";
            $isExist=$this->executeQueryForObject($sql);
            if($isExist){
                $update ="UPDATE sessional_marks_settings
                        set fromDate='$newfromDate' ,
                        toDate='$newtoDate'
                            where batchID='$batchId'
                            and semID='$semId'
                            and subjectID ='$subjectId'
                            and examTypeID=' $examTypeId'";
            $result = $this->executeQueryForObject($update);
            }
            else{
                $values[] =
                  "($batchId,
                    $semId,
                    $subjectId,
                    '$newfromDate',
                    '$newtoDate',
                    $examTypeId)";
            }
        }
        if($values){
            try {
                $sql = "INSERT INTO sessional_marks_settings (batchID, semID, subjectID,fromDate, toDate, examTypeID)
                VALUES " . implode(",", $values);
                 $result = $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        return $result;
    }
    /**
     * @param  $request
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getReglarExamPaymentDetails ($request){
        $request = $this->realEscapeObject($request);
        $filterValues =(object) $request->reportFilterValues;
        $condition = "";
        if($request->examRegId){
            $condition .= " AND ers.examregID = '$request->examRegId";
        }
        if ($filterValues->paymentMethod ){
            if ($filterValues->paymentMethod == 1){
                $condition .= " and ers.payment_method LIKE 'online'";
            }
            else{
                $condition .= " and (ers.payment_method NOT LIKE 'online' or ers.payment_method is null)";
            }
        }
        if ($filterValues->campusType ){
            $condition .= " and ba.campus_typeID = $filterValues->campusType";
        }
        if ($filterValues->admissionYear ){
            $condition .= " and ba.batchStartYear = $filterValues->admissionYear";
        }
        if ($filterValues->batch ){
            $condition .= " and ba.batchID = $filterValues->batch";
        }
        if ($filterValues->department ){
            $condition .= " and ba.deptID = $filterValues->department";
        }
        if ($filterValues->startDate ){
            $condition .= " and IF (ers.dateOfPay, DATE_FORMAT(ers.dateOfPay,'%Y-%m-%d'), DATE_FORMAT(ers.dateofRegistration,'%Y-%m-%d')) >= '$filterValues->startDate'";
        }
        if ($filterValues->endDate ){
            $condition .= " and IF (ers.dateOfPay, DATE_FORMAT(ers.dateOfPay,'%Y-%m-%d'), DATE_FORMAT(ers.dateofRegistration,'%Y-%m-%d')) <= '$filterValues->endDate'";
        }
        if ($filterValues->regNo ){
            $condition .= " and sa.regNo = '$filterValues->regNo'";
        }
        if ($filterValues->studentName ){
            $condition .= " and sa.studentName = '$filterValues->studentName'";
        }
        if ($filterValues->admNo ){
            $condition .= " and sa.admissionNo = '$filterValues->admNo'";
        }
        if ($filterValues->rollNo ){
            $condition .= " and sa.rollNo = '$filterValues->rollNo'";
        }
        $sql = null;
        try {
            $sql = "
            SELECT sa.regNo, sa.studentName, ba.batchName, ers.examtotalFees as examtotalFees, ers.dateOfPay  as dateOfPay,IF ( ers.dateOfPay, DATE_FORMAT(ers.dateOfPay,'%Y-%m-%d'),DATE_FORMAT(ers.dateofRegistration,'%Y-%m-%d')) as dateOfPayFormatted,
            ers.payment_method
            from
                exam_reg_studentchallan ers
            inner join
                studentaccount sa
                on (ers.studentID = sa.studentID )
            inner join batches ba
                on(sa.batchID = ba.batchID )
            where
            ers.paid=1  $condition ORDER BY IF (ers.dateOfPay, DATE_FORMAT(ers.dateOfPay,'%Y-%m-%d'), DATE_FORMAT(ers.dateofRegistration,'%Y-%m-%d')) ASC,sa.regNo";
            $studentsList =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $studentsList;
    }
      /**
     * @param  $request
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getSupplyExamPaymentDetails ($request){
        $request = $this->realEscapeObject($request);
        $filterValues =(object) $request->reportFilterValues;
        $condition = "";
        if($request->examRegId){
            $condition .= " AND ess.exam_supplementary_id =  '$request->examRegId";
        }
        if ($filterValues->paymentMethod ){
            if ($filterValues->paymentMethod == 1){
                $condition .= " and ess.payment_method LIKE 'online'";
            }
            else{
                $condition .= " and (ess.payment_method NOT LIKE 'online' or ess.payment_method is null)";
            }
        }
        if ($filterValues->campusType ){
            $condition .= " and ba.campus_typeID = $filterValues->campusType";
        }
        if ($filterValues->admissionYear ){
            $condition .= " and ba.batchStartYear = $filterValues->admissionYear";
        }
        if ($filterValues->batch ){
            $condition .= " and ba.batchID = $filterValues->batch";
        }
        if ($filterValues->department ){
            $condition .= " and ba.deptID = $filterValues->department";
        }
        if ($filterValues->startDate) {
            $condition .= " and IF (ess.fee_paidDate, DATE_FORMAT(ess.fee_paidDate,'%Y-%m-%d'), DATE_FORMAT(ess.appliedDate,'%Y-%m-%d')) >= '$filterValues->startDate'";
        }
        if ($filterValues->endDate) {
            $condition .= " and IF (ess.fee_paidDate, DATE_FORMAT(ess.fee_paidDate,'%Y-%m-%d'), DATE_FORMAT(ess.appliedDate,'%Y-%m-%d')) <= '$filterValues->endDate'";
        }
        if ($filterValues->regNo ){
            $condition .= " and sa.regNo = '$filterValues->regNo'";
        }
        if ($filterValues->studentName ){
            $condition .= " and sa.studentName = '$filterValues->studentName'";
        }
        if ($filterValues->admNo ){
            $condition .= " and sa.admissionNo = '$filterValues->admNo'";
        }
        if ($filterValues->rollNo ){
            $condition .= " and sa.rollNo = '$filterValues->rollNo'";
        }
        $sql = null;
        try {
            $sql = "
            SELECT sa.regNo, sa.studentName, ba.batchName, IF ( ess.total_fees, ess.total_fees, '-') as examtotalFees , IF ( ess.fee_paidDate, ess.fee_paidDate, '-')  as dateOfPay,IF ( ess.fee_paidDate, DATE_FORMAT(ess.fee_paidDate,'%Y-%m-%d'),DATE_FORMAT(ess.appliedDate,'%Y-%m-%d')) as dateOfPayFormatted from
                exam_supplementary_student_details ess
            inner join
                studentaccount sa
                on (ess.studentID = sa.studentID )
            inner join
                batches ba
                on(sa.batchID = ba.batchID )
            where
                ess.paid=1  $condition";
            $studentsList =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException ($e->getCode(), $e->getMessage());
        }
        return $studentsList;
    }
    /**
     * get suplly chance count of batch
     *
     * @param $request
     * @return Array
     */
    public function getSupplyChanceCount($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if($request->batchId){
            $batchIdString = is_array($request->batchId) ? implode(",", $request->batchId) : $request->batchId;
            $condition .= " AND sib.batchID IN ($batchIdString";
        }
        if($request->semId){
            $semIdString = is_array($request->semId) ? implode(",", $request->semId) : $request->semId;
            $condition .= " AND es.semID IN ($semIdString";
        }
        $sql = "SELECT
            sib.batchID AS batchId,
            es.semID AS semId,
            COUNT(es.id) AS supplyChanceCount
        FROM
            supply_improve_batches sib
        INNER JOIN exam_supplementary es ON
            es.id = sib.exam_supplementary_id
        WHERE
            sib.id = sib.id
            $condition
        GROUP BY sib.batchID, es.semID";
        try {
            return $this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
     /**
     * for get exam type by exam type id
     * @param int $$examId
     * @return object $examType
     */
    public function getExamTypeIdByExamId($examId)
    {
        $sql = "SELECT examTypeID FROM exam WHERE examID='$examId'";
        try {
            $examType = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examType;
    }
    /**
     * for get examDetails by examReg ,sem,batch,subject
     *
     * @param $examRegId
     * @param $semId
     * @param $batchId
     * @param $subjectId
     * @return object $examID
     */
    public function getExamDetailsByBatchIdSemIdAndExamRegId($examRegId,$semId,$batchId,$subjectId,$isSuppply)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $isSupply =(int)$this->realEscapeString($isSuppply);
        $examDetails="";
        if($isSupply){
            $examRegColumn="supply_examreg_id";
        }
        else{
            $examRegColumn="examregID";
        }
        $sql = "SELECT e.examID,e.examName from exam e
                    where e.$examRegColumn ='$examRegId'
                    and e.semID='$semId'
                    and e.batchID='$batchId'
                    and e.subjectID='$subjectId'";
        try{
            $examDetails = $this->executeQueryForObject($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetails;
    }
         /**
     * @param $subjectId
     * @param $batchId
     * @param $examRegId
     * @param $semesterId
     * @param $courseTypeId
     * @return mixed
     * @throws ProfessionalException
     */
    public function getRegularExamDetailsByRegIdSubjectId($subjectId, $batchId, $examRegId, $semesterId, $courseTypeId)
    {
        $sql = "SELECT e.examID as id FROM exam e
                INNER  JOIN exam_registration er on e.examregID = er.examregID
                WHERE e.subjectID=$subjectId
                AND er.examregID=$examRegId
                AND e.batchID = $batchId
                AND e.semID = $semesterId";
        try {
            return $this->executeQueryForObject($sql)->id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $subjectId
     * @param $batchId
     * @param $examRegId
     * @param $semesterId
     * @param $courseTypeId
     * @return mixed
     * @throws ProfessionalException
     */
    public function getExamDetailsForSupplementaryBySubjectId($subjectId, $batchId, $examRegId, $semesterId, $courseTypeId)
    {
        $sql = "SELECT e.examID as id FROM exam e
                INNER  JOIN exam_supplementary er on e.supply_examreg_id = er.id
                WHERE e.subjectID=$subjectId
                AND e.supply_examreg_id=$examRegId
                AND e.batchID = $batchId
                AND e.semID = $semesterId";
        try {
            return $this->executeQueryForObject($sql)->id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $subjectId
     * @param $examId
     * @param $courseTypeId
     * @return mark
     * @throws ProfessionalException
     */
    public function getRegularSupplyExamMark($studentId, $examId, $batchId)
    {
        $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchId);
        $batchCourseType = $batchDetails->course_Type;
        if ($batchCourseType == CourseTypeConstants::UG || strtoupper($batchCourseType) == CourseTypeConstants::BVOC ||$batchCourseType == CourseTypeConstants::UG_DIPLOMA) {
            $examTable = "exammarks_external";
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::MBA || $batchCourseType == CourseTypeConstants::LIB || $batchCourseType == CourseTypeConstants::MSW) {
            $examTable = "externalexammarks_finalized";
        }
        $sql = "SELECT mark  FROM $examTable WHERE examID = $examId AND studentID = $studentId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $subjectId
     * @param $examId
     * @param $mark
     * @throws ProfessionalException
     */
    public function addStudentMarkBeforeModeration($studentId, $examId, $mark,$ruleId = null)
    {
        $date = date('Y-m-d H:i:s');
        if($ruleId){
            $sql = "INSERT INTO student_mark_before_moderation ( studentID,examID,oldMark,moderation_rule_id,date_and_time) VALUES ( $studentId$examId$mark,$ruleId, '$date')";
        }else{
            $sql = "INSERT INTO student_mark_before_moderation ( studentID,examID,oldMark,date_and_time) VALUES ( $studentId$examId$mark, '$date')";
        }
        try {
            return $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
        /**
     * @param $subjectId
     * @param $examId
     * @param $courseTypeId
     * @param $mark
     * @throws ProfessionalException
     */
    public function updateRegularSupplyExamMark($studentId, $examId, $batchId, $mark)
    {
        $batchDetails = CourseTypeService::getInstance()->getcourseTypeByBatchId($batchId);
        $batchCourseType = $batchDetails->course_Type;
        if ($batchCourseType == CourseTypeConstants::UG || strtoupper($batchCourseType) == CourseTypeConstants::BVOC ||$batchCourseType == CourseTypeConstants::UG_DIPLOMA) {
            $examTable = "exammarks_external";
        } elseif ($batchCourseType == CourseTypeConstants::PG || $batchCourseType == CourseTypeConstants::MBA || $batchCourseType == CourseTypeConstants::LIB || $batchCourseType == CourseTypeConstants::MSW) {
            $examTable = "externalexammarks_finalized";
        }
        $sql = "UPDATE $examTable set mark = $mark WHERE examID = $examId AND studentID = $studentId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
          /**
     * @param $subjectId
     * @param $examId
     * @param $courseTypeId
     * @param $mark
     * @throws ProfessionalException
     */
    public function getStudentMarkBeforeModeration($studentId, $examId)
    {
        $sql = "SELECT id FROM student_mark_before_moderation WHERE examID =$examId AND studentID = $studentId";
        try {
            return $this->executeQueryForObject($sql)->id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
      /**
     * @param $examRegId
     * @param $semId
     * @throws ProfessionalException
     */
    public function getExamBatchesForPublishingTimeTable($courseTypeId, $semId,$examTypeId,$batchYear,$isSupply,$supplyId)
    {
        $condition = "";
        if($isSupply){
            $condition = "AND ex.supply_examreg_id = $supplyId";
        }
        $sql1 = " SELECT DISTINCT bt.batchName, ex.batchID, ex.examregID, ptt.publish, ptt.startDate, ptt.endDate, ptt.subjectDetails from exam ex inner join batches bt on(bt.batchID = ex.batchID)  left join publish_exam_time_table ptt on (ex.batchID=ptt.batchID and ex.semID = ptt.semID and ex.examTypeID = ptt.examTypeID) where ex.examTypeID = $examTypeId AND ex.semID =$semId AND bt.batchStartYear =$batchYear AND bt.courseTypeID= $courseTypeId  $condition order by bt.batchName ASC";
        try {
            $result = $this->executeQueryForList($sql1);
            return $result;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $request
     * @throws ProfessionalException
     */
    public function setExamTimeTablePublishFlag($request)
    {
        $sql1="";
        $request = $this->realEscapeObject($request);
        $examregId=$request->examregId;
        $examTypeId=$request->examTypeId;
        $batchId=$request->batchId;
        $semId=$request->semId;
        $subjectDetails = $request->subjectDetails;
        $publish = (int) $request->publish;
        $startDate = $request->startDate;
        $endDate=$request->endDate;
        $isSupply=$request->isSupply;
        $supplyId=$request->supplyId;
        if($subjectDetails){
            $subjectDetails = json_encode($subjectDetails);
        }else{
            $subjectDetails = "null";
        }
        $user = $_SESSION['adminID'];
        $examregId = $request->examregId ? $request->examregId : NULL;
        $examTypeVar = "examregID";
        if($isSupply){
            $examregId = $supplyId;
            $examTypeVar = "supplyregID";
        }
        $sql= " SELECT * from publish_exam_time_table WHERE examTypeID = '$examTypeId' and $examTypeVar = '$examregId' and batchID= '$batchId' and semID = '$semId'";
        $result = $this->executeQueryForList($sql);
        if ( $result){
            if ($publish == 1){
               $sql1= " UPDATE publish_exam_time_table
                            SET subjectDetails= '$subjectDetails',
                            startDate = '$startDate',
                            endDate = '$endDate',
                            publish = $publish,
                            updated_by = '$user'
                            WHERE  examTypeID = '$examTypeId'
                            and $examTypeVar = '$examregId'
                            and batchID= '$batchId'
                            and semID = '$semId'";
            }
            else{
               $sql1= " UPDATE publish_exam_time_table
                            SET publish = '$publish',
                            updated_by = '$user'
                            WHERE  examTypeID = '$examTypeId'
                            and $examTypeVar = '$examregId'
                            and batchID= '$batchId'
                            and semID = '$semId'";
            }
        }
        else{
            if ($publish == 1){
                $sql1= " INSERT into publish_exam_time_table(batchID, startDate, endDate, publish, examTypeID, semID, $examTypeVar, subjectDetails, created_by)
                                VALUES ('$batchId',
                                        '$startDate',
                                        '$endDate',
                                        '$publish',
                                        '$examTypeId',
                                        '$semId',
                                        '$examregId',
                                        '$subjectDetails',
                                        '$user')";
            }
       }
        if($sql1){
            try {
                return $this->executeQuery($sql1);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }else{
            return null;
        }
    }
     /**
     * for get examDetails by examReg ,sem,batch,subject
     *
     * @param $examRegId
     * @param $semId
     * @param $batchId
     * @param $subjectId
     * @return object $examType
     */
    public function getRegularExamDetailsByBatchIdSemIdAndSubjectId($batchId,$semId,$subjectId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examDetails="";
        $sql = "SELECT examID,examName from exam
                    where batchID='$batchId'
                    and semID='$semId'
                    and subjectID='$subjectId'
                    and examregID IS NOT NULL";
        try{
            $regularExamDetails = $this->executeQueryForObject($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $regularExamDetails;
    }
 /**
     * to mark status of attendance
     *
     * @param $examId
     * @param $checkAbsent
     * @param $studentId
     */
    public function markAbsentStatus($absentStudents)
    {
        $isExistSql="";
        $insertSql="";
        $updateSql="";
        $sql="";
        $isExist="";
        $status="";
        $absentStudents = $this->realEscapeArray($absentStudents);
        foreach($absentStudents as $student){
            $examId = $student->examId;
            $studentId = $student->studentId;
            $checkAbsent = $student->checkAbsent;
            //start check the status and set status code
            if($checkAbsent == "ab"){
                $status=1;
            }
            else if($checkAbsent == "mal"){
                $status=2;
            }
            else{
                $status=0;
            }
            //end check the status and set status code
            //check entry already exists
            $isExistSql = "SELECT id,examID,studentID,isAbsent from exam_attendance
                                where examID='$examId'
                                and studentID='$studentId'";
            try{
                $isExist = $this->executeQueryForObject($isExistSql);
            }
            catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            //update if exists
            if($isExist){
                if($status==0){
                    $updateSql="Delete from exam_attendance
                                    where examID='$examId'
                                    and studentID='$studentId'";
                }
                else{
                    $updateSql="UPDATE exam_attendance
                            set isAbsent='$status'
                                where examID='$examId'
                                and studentID='$studentId'";
                }
                try{
                    $this->executeQueryForObject($updateSql);
                    $isAbsent=true;
                }
                catch (\Exception $e) {
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
            }
            //insert as new entry if not exists
            else{
                if(($status==1)|| ($status==2)){
                    if($insertSql){
                        $insertSql=$insertSql.",('$examId','$studentId','$status')";
                    }else{
                        $insertSql="('$examId','$studentId','$status')";
                    }
                }
            }
        }
        //insert as new entry if not exists
        if($insertSql){
            $sql="INSERT into exam_attendance(examID,studentID,isAbsent)
                        values $insertSql";
            try{
                $this->executeQueryForObject($sql);
                $isAbsent=true;
            }
            catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        return $isAbsent;
    }
    /**
     * to check status of attendance
     *
     * @param $examId
     * @param $checkAbsent
     * @param $studentId
     */
    public function getAbsentStatus($student)
    {
        $isExistSql="";
        $status="";
        $student = $this->realEscapeObject($student);
            $examId = $student->examId;
            $studentId = $student->studentID;
            //check absent status of student for the exam
            $isExistSql = "SELECT id,examID,studentID,isAbsent from exam_attendance
                                where examID='$examId'
                                and studentID='$studentId'";
            try{
                $isAbsent = $this->executeQueryForObject($isExistSql);
            }
            catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        return $isAbsent;
    }
     /** for get published examDetails by sem,batch
     *
     * @param $semId
     * @param $batchId
     * @return List $exams
     */
    public function getExamsFromPublishExamTimeTable($batchId,$semId,$isInternal)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $isInternal = (int) $this->realEscapeString($isInternal);
        $condition="";
        if($isInternal){
            $condition = "and (pet.examregID is null or pet.examregID=0)";
        }
        else if($isInternal==0){
            $condition = "and (pet.examregID is not null and pet.examregID!=0)";
        }
        $exams="";
        $sql = "SELECT pet.id,
                        pet.batchID,
                        b.batchName,
                        pet.examTypeID,
                        et.typeName,
                        pet.semID,
                        pet.examregID,
                        pet.startDate,
                        pet.endDate,
                        pet.publish,
                        pet.subjectDetails
                        from publish_exam_time_table pet
                        inner join batches b
                            on b.batchID=pet.batchID
                        inner join exam_type et
                            on et.typeID=pet.examTypeID
                        where pet.batchID ='$batchId'
                        and pet.semID ='$semId'
                        -- and pet.publish=1
                        $condition
                        and pet.supplyregID is null";
        try{
            $exams = $this->executeQueryForList($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
    /**
     * Get examId by subjectId
     * @param int $subjectId
     * @param int $batchId
     * @param int $semId
     * @param int $examTypeId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getPublishExamDetailsBySubjectId($subjectId, $batchId, $semId, $examTypeId, $subbatchId = NULL)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $subbatchId = $this->realEscapeString($subbatchId);
        $whereCondition = "";
        if ($subbatchId) {
            $whereCondition .= "AND subbatchID IN ( $subbatchId )";
        }
        $sql = "SELECT e.examID,
                            s.subjectDesc,
                            e.subjectID,
                            e.examTotalMarks,
                            e.examStartTime,
                            e.examEndTime,
                            DATE_FORMAT(e.examDate,'%d-%m-%Y') AS examDate,
                            s.subjectName,
                            s.syllabusName,
                            e.subbatchID,
                            s.subjectPriority,
                            er.examregID,
                            er.examregName,
                            es.id as supplyRegId,
                            es.supplyDesc
                                FROM exam e
                                    inner join subjects s
                                        on s.subjectID=e.subjectID
                                    LEFT JOIN exam_registration er
                                        ON er.examregID = e.examregID
                                    LEFT JOIN exam_supplementary es
                                        ON es.id = e.supply_examreg_id
                                    WHERE e.subjectID = $subjectId
                                    AND e.batchID = $batchId
                                    AND e.semID = $semId
                                    and e.examTypeID = $examTypeId $whereCondition";
        try {
            $examId = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examId;
    }
    /**
     *  to get all supply registered subjects by supplyRegId
     * @param $supplyRegId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getSupplyExamStudentSubject($supplyRegId)
    {
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $subjects = [];
        $sql = " SELECT DISTINCT sb.subjectID ,sb.subjectDesc ,sb.subjectName ,sb.syllabusName FROM exam_supplementary_student_subjects esss INNER JOIN exam ex ON (esss.examID = ex.examID ) INNER JOIN subjects sb ON (ex.subjectID = sb.subjectID ) WHERE esss.exam_supplementary_id = '$supplyRegId";
        try {
            $subjects = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    /**
     *  to get all registered students in subjects for supply
     * @param $subjectId, $supplyRegId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getSupplyRegisteredStudentsForSubjects($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 batches bt ON (bt.batchID = sa.batchID ) WHERE ex.subjectID = '$subjectId' and esss.exam_supplementary_id = '$supplyRegId'";
        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 getSupplyStudentWiseReport($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 subjects sb ON (sb.subjectID = ex.subjectID) WHERE   esss.exam_supplementary_id = '$supplyRegId'";
        try {
            $students = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $students;
    }
    public function getSubjectCategoryCode($subjectId)
    {
        $sql = '';
        $subjectId = $this->realEscapeString($subjectId);
        $subjectDetails = [];
        try{
            $sql = "SELECT cc.categoryCode FROM subjects s INNER JOIN subject_category sc ON s.subjectcatID = sc.subjectcatID INNER JOIN categoryCode cc ON cc.subject_category_id = sc.subjectcatID AND cc.subject_category_id = s.subjectcatID WHERE s.subjectID = $subjectId";
            $subjectDetails = $this->executeQueryForObject($sql);
        }catch (\Exception $e){
            throw new AutonomousException($e->getCode(),$e->getMessage());
        }
        return $subjectDetails->categoryCode;
    }
    /**
     * Returns exam details of subjects
     *
     * @param $batchId
     * @param $examRegId
     * @param $semId
     * @param $subjectId
     * @return $subjects
     */
    public function getSubjectRegularExamDetails($batchId, $examRegId, $semId, $subjectId = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $examRegId = $this->realEscapeString($examRegId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $condition = "";
        if (empty($batchId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        if (empty($examRegId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        if (empty($semId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        if (!empty($subjectId)) {
            $condition .= " AND subjectID IN ($subjectId";
        }
        $sql = "SELECT
            examID AS examId,
            examName,
            subjectID AS subjectId,
            examTotalMarks,
            examStartTime,
            examEndTime,
            examDate,
            batchID AS batchId,
            semID AS semId,
            examTypeID AS examTypeId,
            unixtime_start AS unixtimeStart,
            unixtime_end AS unixtimeEnd,
            examCode,
            subbatchID AS subbatchId,
            canShow,
            examregID AS examregId,
            isRoundOff
        FROM
            exam
        WHERE
            batchID IN ($batchId)
            AND semID IN ($semId)
            AND examregID IN ($examRegId)
            $condition";
        try {
            $subjects = $this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    /**
     * Returns exam details of subjects
     *
     * @param $batchId
     * @param $examRegId
     * @param $semId
     * @param $subjectId
     * @return $subjects
     */
    public function getSubjectSupplyExamDetails($batchId, $examRegId, $semId, $subjectId = null)
    {
        $batchId = $this->realEscapeString($batchId);
        $examRegId = $this->realEscapeString($examRegId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $condition = "";
        if (empty($batchId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        if (empty($examRegId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        if (empty($semId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid exam");
        }
        if (!empty($subjectId)) {
            $condition .= " AND subjectID IN ($subjectId";
        }
        $sql = "SELECT
            examID AS examId,
            examName,
            subjectID AS subjectId,
            examTotalMarks,
            examStartTime,
            examEndTime,
            examDate,
            batchID AS batchId,
            semID AS semId,
            examTypeID AS examTypeId,
            unixtime_start AS unixtimeStart,
            unixtime_end AS unixtimeEnd,
            examCode,
            subbatchID AS subbatchId,
            canShow,
            supply_examreg_id AS examregId,
            isRoundOff
        FROM
            exam
        WHERE
            batchID IN ($batchId)
            AND semID IN ($semId)
            AND supply_examreg_id IN ($examRegId)
            $condition";
        try {
            $subjects = $this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjects;
    }
    public function getStudentLastExamByStudentId($studentId,$lastExamOnly = true){
        $studentId = $this->realEscapeString($studentId);
        $lastExamOnly = $this->realEscapeString($lastExamOnly);
        $limit = $lastExamOnly? "limit 1":"";
        $sql = "select id, examName, examDesc,examDate from (
            select er.examregID as id,er.examregName as examName,er.examregDesc as examDesc,DATE_FORMAT(concat(er.examYear,'-',er.examMonth,'-01'), '%Y-%m-%d') as examDate from exam_registration er
            inner join exam_reg_studentchallan ers on ers.examregID = er.examregID
            where ers.paid = 1 and er.shortCourse = 0 and ers.studentID = $studentId
            union
            select es.id,es.supplyDesc as examName,null,DATE_FORMAT(concat(es.examYear,'-',es.examMonth,'-01'), '%Y-%m-%d') as examDate from exam_supplementary es
            inner join exam_supplementary_student_details essd on es.id = essd.exam_supplementary_id
            where essd.paid = 1 and essd.studentID = $studentId)
            as temp order by examDate desc ".$limit.";";
        try {
            return $lastExamOnly?$this->executeQueryForObject($sql):$this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getStudentLastAppearedExamByStudentId($studentId){
        $studentId = $this->realEscapeString($studentId);
        $sql = "SELECT DISTINCT eer.id, eer.name
                    FROM ec_student_assessment_registration esar 
                    INNER JOIN ec_exam_registration_subject eers 
                        ON eers.am_assessment_id = esar.am_assessment_id
                    INNER JOIN ec_exam_registration_batch eerb 
                        ON eerb.id = eers.ec_exam_registration_batch_id
                    INNER JOIN ec_exam_registration eer 
                        ON eer.id = eerb.ec_exam_registration_id
                    WHERE esar.student_id = $studentId
                    AND esar.ec_exam_registration_type = eer.`type`
                    AND eer.type = 'REGULAR'
                    ORDER BY 
                    CAST(eer.properties ->> '$.examYear' AS UNSIGNED) DESC,
                    CAST(eer.properties ->> '$.examMonth' AS UNSIGNED) DESC
                    LIMIT 1";
         try {
            $lastExam = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $lastExam;
    }
      /**
       * get all Exam Registration by courseTypeId
       * @param  $courseTypeId
     */
    public function getAllRegularExamRegistrationByCourseTypeId($courseTypeId)
    {
        $sql = "SELECT DISTINCT er.examregID AS id, er.examregName AS name, er.examMonth, er.examYear from exam_registration er inner join exam ex on (ex.examregID = er.examregID ) inner join batches bt on (bt.batchID = ex.batchID ) where bt.courseTypeID = $courseTypeId  ORDER BY er.examregID DESC";
        try {
            $regExam = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $regExam;
    }
    /**
     * block students from exam reg
     * @param batchId,examRegId,StudentList
     * @throws ProfessionalException
     */
    public function blockStudentsExamReg($examRegId, $batchId, $studentList,$adminId,$isSupply)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $studentList = $this->realEscapeArray($studentList);
        $adminId = $this->realEscapeString($adminId);
        $isSupply = $this->realEscapeString($isSupply);
        $insertValues="";
        $result=0;
        $isExist="";
        $examType = "examRegId";
        if($isSupply){
            $examType = "supplyRegId";
        }
        foreach($studentList as $student){
            $student = (object) $student;
            //check entry already exist before inserting
            $isExistSql ="select examRegId,batchId,studentId from exam_blocked_students
                            where $examType='$examRegId'
                            and batchId='$batchId'
                            and studentId='$student->studentId'";
                try {
                    $isExist = $this->executeQueryForObject($isExistSql);
                } catch (\Exception $e) {
                    throw new ProfessionalException($e->getCode(), $e->getMessage());
                }
            $blockedStudent = $student->blockedStudentId == 1 ? 1 : 0;
            $blockedHallTicket = $student->blockedHallTicket == 1 ? 1 : 0;
            $student->blockedStudentRemark = $student->blockedStudentRemark == 'null'? '' : $student->blockedStudentRemark;
            $student->blockedHallTicketRemark = $student->blockedHallTicketRemark == 'null'? '' : $student->blockedHallTicketRemark;
            if(!$isExist){
                if( $blockedStudent || $blockedHallTicket){
                    if($insertValues){
                        $insertValues = $insertValues. ",('$examRegId','$batchId','$student->studentId','$blockedStudent','$student->blockedStudentRemark','$blockedHallTicket','$student->blockedHallTicketRemark','$adminId')";
                    }else{
                        $insertValues = "('$examRegId','$batchId','$student->studentId','$blockedStudent','$student->blockedStudentRemark','$blockedHallTicket','$student->blockedHallTicketRemark','$adminId')";
                    }
                }
            }
            else{
                $updateSql ="UPDATE exam_blocked_students set block_student = $blockedStudent, block_student_remark = '$student->blockedStudentRemark',block_hall_ticket = '$blockedHallTicket', block_hall_ticket_remark  = '$student->blockedHallTicketRemark'
                where $examType='$examRegId'
                and batchId='$batchId'
                and studentId='$student->studentId'";
                $result = $this->executeQuery($updateSql);
                $result = 2;
            }
        }
        if($insertValues){
            $insertSql = "INSERT into exam_blocked_students($examType,batchId,studentId,block_student,block_student_remark,block_hall_ticket,block_hall_ticket_remark,created_by)
                        values $insertValues";
            try {
                $result = $this->executeQueryForObject($insertSql);
                $result=1;
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
        }
        return $result;
    }
    /**
     * get blocked students from exam reg
     * @param batchId,examRegId,StudentId
     * @throws ProfessionalException
     */
        public function getStudentBlockedStatus($examregID, $batchID, $studentID, $isSupply){
        $studentId = $this->realEscapeString($studentID);
        $batchId = $this->realEscapeString($batchID);
        $examregId = $this->realEscapeString($examregID);
        $isSupply = $this->realEscapeString($isSupply);
        $result="";
        $examTypeField = "examRegId";
        if($isSupply){
            $examTypeField = "supplyRegId";
        }
        $isExistSql ="select examRegId,batchId,studentId, block_student_remark from exam_blocked_students
                        where $examTypeField='$examregId'
                        and batchId='$batchId'
                        and studentId='$studentId'
                        and block_student = 1";
        try {
            $result = $this->executeQueryForObject($isExistSql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * Method for getting student external mark finalized for an exam pg
     * @param unknown $studentId
     * @param unknown $examId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getExternalMarksFinalizedByStudentId($studentId, $examId)
    {
        $sql = '';
        $studentId = $this->realEscapeObject($studentId);
        $examId = $this->realEscapeObject($examId);
        $studentExternalMark = null;
        try {
            $sql = "SELECT eef.mark AS studentExternalMark, e.examTotalMarks AS examTotalMark
                        FROM externalexammarks_finalized eef
                            INNER JOIN exam e ON eef.examID = e.examID
                            WHERE eef.studentID = '$studentId'
                            AND e.examID = '$examId'";
            $studentExternalMark = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentExternalMark;
    }
    /**
     * get exam registration fees types
     *
     * @param int $examRegId
     * @param string $examType
     *
     * @throws ProfessionalException
     * @return list $regFeeTypes
     */
    public function getFeeTypesForExamRegisterApplication($batchId,$semId,$examRegId, $examType = ExamType::REGULAR) {
        $examRegId = $this->realEscapeString($examRegId);
        $examType = $this->realEscapeString($examType);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $examFees="";
        $sql="SELECT distinct (ersf.examFeesID) as id,
                    eft.examfeesName AS name
                    from exam_registration_subject_fees ersf
                    INNER JOIN exam_feestype eft ON ersf.examfeesID=eft.examfeesID
                    INNER JOIN exam_reg_studentsubject ersb
                    ON ersb.subjectID = ersf.subjectID AND ersb.examregID=ersf.examregID
                        where ersf.batchID='$batchId'
                        AND ersf.semID='$semId'
                        AND ersf.examregID='$examRegId'";
        try{
            $examFees = $this->executeQueryForList($sql);
        }catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examFees;
    }
    /**
     * get exam registration fees types
     * @param int $examRegId
     * @param string $examType
     *
     * @throws ProfessionalException
     * @return list $regFeeTypes
     */
    public function getCommonFeeTypesForExamRegisterApplication($examRegId, $examType = ExamType::REGULAR)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $examType = $this->realEscapeString($examType);
        $sql="";
        $examCommonFees="";
        $sql = "SELECT eft.examfeesID AS id,
                        eft.examfeesName AS name,
                        erf.examfeesAmount AS examRegAmount
                    FROM
                        exam_feestype eft
                        INNER JOIN
                        exam_registration_fees erf ON erf.examfeesID = eft.examfeesID
                            AND erf.examregID = '$examRegId'
                            AND eft.everySubject = 0
                    WHERE
                        eft.examfeesID IS NOT NULL";
        try {
            $examCommonFees = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examCommonFees;
    }
    /**
     * get exam reg fine
     * @param  $examRegId,studentId
     *
     * @throws ProfessionalException
     * @return list $examregFine
     */
    public function getStudentRegisteredExamFine($studentId, $examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $studentId = $this->realEscapeString($studentId);
        $sql="";
        $examRegFine="";
        $sql = "SELECT ers.examfineID,erf.examfineAmount
                    FROM exam_reg_studentchallan  ers
                    INNER JOIN exam_registration_fine erf ON erf.examfineID=ers.examfineID and erf.examregID = ers.examregID
                    WHERE ers.examregID = '$examRegId'
                    AND ers.studentID = '$studentId'";
        try {
            $examRegFine = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegFine;
    }
    /**
     * get exam registration fees types
     *
     * @param int $examRegId
     * @param string $examType
     *
     * @throws ProfessionalException
     * @return list $regFeeTypes
     */
    public function getSumOfExamFees($examRegId, $studentId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $studentId = $this->realEscapeString($studentId);
        $examFees = "";
        $sql = "SELECT sum(examFees) as feesSum from exam_reg_studentsubject where examregID='$examRegId' and studentID='$studentId'";
        try {
            $sumExamFees = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $sumExamFees;
    }
    /**
     * Method for getting student external mark for an exam with maxMark
     * @param unknown $studentId
     * @param unknown $examId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getStudentExternalMarksWithMaxMark($studentId, $examId)
    {
        $sql = '';
        $studentId = $this->realEscapeObject($studentId);
        $examId = $this->realEscapeObject($examId);
        $studentExternalMark = null;
        try {
            $sql = "SELECT ee.mark AS studentExternalMark, e.examTotalMarks AS examTotalMark
                        FROM exam e
                        LEFT JOIN exammarks_external ee  ON ee.examID = e.examID AND ee.studentID = '$studentId'
                        WHERE e.examID ='$examId'";
            $studentExternalMark = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentExternalMark;
    }
    /**
     * Method for getting student external mark finalized for an exam pg with maxMark
     * @param unknown $studentId
     * @param unknown $examId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getExternalMarksFinalizedByStudentIdWithMaxMark($studentId, $examId)
    {
        $sql = '';
        $studentId = $this->realEscapeObject($studentId);
        $examId = $this->realEscapeObject($examId);
        $studentExternalMark = null;
        try {
            if($examId){
                $courseType = CourseTypeService::getInstance()->getcourseTypeByExamId($examId)->course_Type;
                if($courseType == CourseTypeConstants::UG){
                    return $this->getExternalMarks($studentId, $examId);
                }
            }
            $sql = "SELECT eef.mark AS studentExternalMark, e.examTotalMarks AS examTotalMark 
                        FROM exam e 
                            LEFT JOIN externalexammarks_finalized eef ON eef.examID = e.examID AND eef.studentID = '$studentId'
                            WHERE e.examID = '$examId'";
            $studentExternalMark = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentExternalMark;
    }
    /**
     * @author Sibin
     */
    public function getExamRegisteredStudents($examType,$examRegId,$batchId)
    {
        $examType = $this->realEscapeString($examType);
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $studentDetails = [];
        if ($examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT DISTINCT sa.studentID as id,sa.regNo,sa.studentName FROM studentaccount sa
                        INNER JOIN exam_reg_studentsubject erss ON (sa.studentID = erss.studentID)
                        INNER JOIN exam e ON (e.examregID = erss.examregID AND e.subjectID = erss.subjectID AND sa.batchID = e.batchID)
                        INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = sa.studentID AND ersc.examregID ='$examRegId'
                        WHERE erss.examregID = '$examRegId' AND sa.batchID='$batchId' AND ersc.paid=1  order by sa.regNo";
        } else if ($examType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT DISTINCT sa.studentID as id,sa.regNo,sa.studentName FROM studentaccount sa
                        INNER JOIN exam_supplementary_student_subjects esss ON (sa.studentID = esss.studentID)
                        INNER JOIN exam e ON (e.examID = esss.examID AND sa.batchID = e.batchID)
                        INNER JOIN exam es ON (e.subjectID = es.subjectID AND es.supply_examreg_id = esss.exam_supplementary_id AND es.batchID = e.batchID)
                        INNER JOIN exam_supplementary_student_details essd ON essd.studentID = sa.studentID AND essd.exam_supplementary_id ='$examRegId'
                        WHERE esss.exam_supplementary_id = '$examRegId' AND sa.batchID='$batchId' AND essd.paid=1 order by sa.regNo";
        }
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
       /**
     * @author Sibin
     */
    public function getExamSubjectsByBatch($examType,$examRegId,$batchId)
    {
        $examType = $this->realEscapeString($examType);
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $subjectList = [];
        if ($examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT e.examID,s.subjectID,s.subjectName,s.subjectDesc,e.examregID,e.supply_examreg_id from exam e
                        INNER JOIN subjects s ON s.subjectID= e.subjectID
                        WHERE e.examregID = '$examRegId' and e.batchID = '$batchId' order by e.examID";
        } else if ($examType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT e.examID,s.subjectID,s.subjectName,s.subjectDesc,e.examregID,e.supply_examreg_id from exam e
                        INNER JOIN subjects s ON s.subjectID= e.subjectID
                        WHERE e.supply_examreg_id = '$examRegId' and e.batchID = '$batchId' order by e.examID";
        }
        try {
            $subjectList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectList;
    }
    /**
     * @author Sibin
     */
    public function getRegisteredExamsDetailsById($isSupply,$examRegId)
    {
        $isSupply = $this->realEscapeString($isSupply);
        $examRegId = $this->realEscapeString($examRegId);
        if($isSupply){
            $sql = "SELECT id, supplyDesc as name, semID AS semId FROM exam_supplementary where id ='$examRegId'";
        }else{
            $sql = "SELECT examregID AS id, examregName AS name FROM exam_registration where examregiD ='$examRegId'";
        }
        try {
            $examReg = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examReg;
    }
       /**
     * @param $examId
     * @param $studentId
     * @return mark
     * @throws ProfessionalException
     */
    public function getRevaluationMarkFinalized($examId, $studentId)
    {
        $sql = "SELECT mark  FROM revaluation_marks_finalized WHERE examID = $examId AND studentID = $studentId";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $subjectId
     * @param $examId
     * @param $mark
     * @throws ProfessionalException
     */
    public function updateModerationDetailsForRevaluation($studentId, $examId, $givenModerationMark, $revalMark,$givenExternal )
    {
        $date = date('Y-m-d');
        $finalMark = $revalMark + $givenModerationMark;
        $sql = "UPDATE revaluation_marks_finalized set mark = $finalMark WHERE examID = $examId and studentID = $studentId";
        $sql1 = "INSERT INTO student_mark_before_moderation ( studentID,examID,oldMark, exam_revaluation_mark, date_and_time) VALUES ( $studentId$examId$givenExternal$revalMark, '$date')";
        try {
             $this->executeQuery($sql);
             $this->executeQuery($sql1);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Method for getting student external mark
     * @param unknown $studentId
     * @param unknown $examId
     * @return unknown
     * @throws ProfessionalException
     */
    public function getStudentExternalMarks($studentId, $examId ,$isPg = 0)
    {
        $sql = '';
        $studentId = $this->realEscapeString($studentId);
        $examId = $this->realEscapeString($examId);
        $studentExternalMark = null;
        if($isPg){
            $sql = "SELECT ee.examfinalizeID as 'id',ee.mark AS studentExternalMark, e.examTotalMarks AS examTotalMark
                        FROM exam e
                        INNER JOIN externalexammarks_finalized ee  ON ee.examID = e.examID AND ee.studentID = '$studentId'
                        WHERE e.examID ='$examId'";
        }else{
            $sql = "SELECT ee.id,ee.mark AS studentExternalMark, e.examTotalMarks AS examTotalMark
                        FROM exam e
                        INNER JOIN exammarks_external ee  ON ee.examID = e.examID AND ee.studentID = '$studentId'
                        WHERE e.examID ='$examId'";
        }
        try {
            $studentExternalMark = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentExternalMark;
    }
    /**
     * @author Sibin
     */
    public function updateAttendanceOfStudentsWithMigratedExternalMarks($examId,$studentId)
    {
        $examId = $this->realEscapeString($examId);
        $studentId = $this->realEscapeString($studentId);
        $result= false;
        $sql = "UPDATE exam_attendance SET isAbsent = 0
                                    WHERE examID = '$examId'
                                    AND studentID = '$studentId'";
        try {
            $this->executeQueryForObject($sql);
            $result = true;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * @author Sibin
     */
    public function saveMigratedExternalMarksAndMarkAttendance($insertStr , $insertAttendStr , $isPg)
    {
        $isPg = $this->realEscapeString($isPg);
        $result= false;
        if($isPg){
            $insertExamMarkSql = "INSERT into externalexammarks_finalized(examID,studentID,mark)
                                    values $insertStr ON DUPLICATE KEY UPDATE
                                    mark = values(mark)";
        }
        else{
            $insertExamMarkSql = "INSERT into exammarks_external(examID,studentID,mark,adminID)
                                    values $insertStr ON DUPLICATE KEY UPDATE
                                    mark = values(mark)";
        }
        try {
            $this->executeQueryForObject($insertExamMarkSql);
            if($insertAttendStr){
                $insertAttendanceSql = "INSERT into exam_attendance(examID,studentID,isAbsent)
                                            values  $insertAttendStr";
                $this->executeQueryForObject($insertAttendanceSql);
            }
            $result = true;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * Get student supply exam marks of aregular exam
     */
    public function getStudentSupplyMarksOfRegularExam($studentId, $examId, $request = NULL)
    {
        $examId = (int)$this->realEscapeString($examId);
        $studentId = (int)$this->realEscapeString($studentId);
        $request = $this->realEscapeObject($request);
        $type = $request->type;
        $yearUpperLimit = $request->yearUpperLimit;
        $monthUpperLimit = $request->monthUpperLimit;
        $supplyMarks = [];
        $publishTable = $conditions = "";
        $marksTableJoin = " INNER JOIN ";
        if(!empty($request->regType)){
            switch ($request->regType) {
                case 'SUPPLY':
                    $conditions .= " AND essd.isSupply = 1 ";
                    break;
                case 'IMPROVEMENT':
                    $conditions .= " AND essd.isSupply = 0 ";
                    break;
            }
        }
        if($request->considerAbsentExam){
            $marksTableJoin = " LEFT JOIN ";
        }
        if(!(int)$request->isExternal){
            $marksTableJoin = " LEFT JOIN ";
        }
        if($yearUpperLimit && $monthUpperLimit){
            $conditions .= " AND UNIX_TIMESTAMP(CONCAT (es.examYear,'-',es.examMonth,'-01')) <=  UNIX_TIMESTAMP('$yearUpperLimit-$monthUpperLimit-01') ";
        }
        if($request->considerSupplementaryPublishedOnly){
            $publishTable .= " INNER JOIN supplyexam_publishresult epr ON epr.exam_supplementary_id = essd.exam_supplementary_id AND epr.batchID = e.batchID AND epr.semID = e.semID";
            $conditions .= " AND TIMESTAMP(epr.fromDate,'00:00:00') < NOW() ";
        }
        if($request->excludeSupplyRegistrations){
            $conditions .= " AND esss.exam_supplementary_id NOT IN ($request->excludeSupplyRegistrations";
        }
        if($request->supplyRegId){
            $conditions .=" AND esss.exam_supplementary_id  IN ($request->supplyRegId)";
        }
        $batchCourseType  = CourseTypeService::getInstance()->getcourseTypeByExamId($examId)->course_Type;
        $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 || $batchCourseType == CourseTypeConstants::MTECH || $batchCourseType == CourseTypeConstants::MCA || $batchCourseType == CourseTypeConstants::MPHIL || $batchCourseType == CourseTypeConstants::PHD) {
            $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";
        }
        if($request->excludeImprovement){
            $conditions .=" AND essd.isSupply  = 1";
        }
        $sql = "SELECT
        ee.mark,
        es.examMonth,
        es.examYear,
        es.isSpecialExam,
        ea.isAbsent,
        esss.exam_supplementary_id AS supplyRegId,
        essd.isSupply AS isSupply,
        e.examID AS examId,
        e.subjectID AS subjectId,
        e.semID AS semId,
        e.examTotalMarks AS maxMark,
        ea.isAbsent,
        es.isSpecialExam
    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.batchID = e1.batchID
        AND e.supply_examreg_id = esss.exam_supplementary_id)
    LEFT JOIN exam_attendance ea ON ea.examID = e.examID AND ea.studentID = esss.studentID
    INNER JOIN studentaccount sa ON
        (sa.studentID = esss.studentID)
    $marksTableJoin $marksTable ee ON
        (ee.studentID = sa.studentID
        AND ee.examID = e.examID)
    ".$publishTable."
    LEFT JOIN exam_attendance ef ON ef.examID = e.examID
        AND ef.studentID = sa.studentID
        AND ef.examID =  e.examID
    WHERE
        esss.studentID = '$studentId'
        AND esss.examID = '$examId'
        $conditions $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 category code by batch sem relation
     */
    public function getSubjectCategoryCodeByBatchSemSubjectID($batchId , $semId, $subjectId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "SELECT cc.categoryCode FROM batch_sem_subjectCategory_relation bssr LEFT JOIN categoryCode cc ON (bssr.subjectcatID = cc.subject_category_id ) INNER JOIN batches b ON b.batchID = bssr.batchID and b.courseTypeID = cc.course_type_id WHERE  bssr.batchID=$batchId AND bssr.semID= $semId AND bssr.subjectID = $subjectId";
        try {
            $result  = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result->categoryCode;
    }
     /**
     * @author Sibin
     */
    public function getDistinctExamSubjectsByExamReg($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = $groupByCondition ="";
        if($request->subjectId){
            $subjectIds = $request->subjectId;
            if(is_array($request->subjectId)){
                $subjectId = $this->realEscapeArray($request->subjectId);
                $subjectIds = implode(',', $subjectId);
            }
            $condition .= "and e.subjectID IN($subjectIds)";
        }
        if ($request->batchId) {
            $condition .= " and e.batchID IN ($request->batchId)";
        }
        if ($request->groupBySubject) {
            $groupByCondition = " group by e.subjectID ";
        }
        if ($request->groupByExam) {
            $groupByCondition = " group by e.examID ";
        }
        if ($request->batchStartYear) {
            $condition .= " AND b.batchStartYear IN($request->batchStartYear)";
        }
        if ($request->courseTypeId) {
            $condition .= " AND b.courseTypeID IN($request->courseTypeId)";
        }
        if ($request->semId) {
            $condition .= " AND e.semID IN($request->semId)";
        }
        $subjectList = [];
        if ($request->examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT s.subjectID as 'id',s.subjectName,s.subjectDesc as 'name',e.examregID,e.supply_examreg_id,e.examID,e.examTotalMarks,e.semID as semId,e.batchID as batchId from exam e
                        INNER JOIN subjects s ON s.subjectID= e.subjectID
                        INNER JOIN batches b ON b.batchID = e.batchID
                        WHERE e.examregID = '$request->examRegId'
                        $condition
                        $groupByCondition
                        order by e.examID,e.subjectId";
        } else if ($request->examType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT s.subjectID as 'id',s.subjectName,s.subjectDesc as 'name',e.examregID,e.supply_examreg_id,e.examID,e.examTotalMarks,e.semID as semId,e.batchID as batchId from exam e
                        INNER JOIN subjects s ON s.subjectID= e.subjectID
                        INNER JOIN batches b ON b.batchID = e.batchID
                        WHERE e.supply_examreg_id = '$request->examRegId'
                        $condition
                        $groupByCondition
                        order by e.examID,e.subjectId";
        }
        try {
            $subjectList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectList;
    }
      /**
     * @author Sibin
     */
    public function getExamRegisteredStudentsWithExternalMarks($request)
    {
        $request = $this->realEscapeObject($request);
        $studentDetails = [];
        $thirdValStudents="";
        if($request->considerThirdValStudentsOnly){
            $thirdValStudents = " INNER JOIN externalexam_thirdvalstudents eth ON eth.examID = e.examID AND eth.studentID = sa.studentID AND revaluationFlag = 0 ";
        }
        if ($request->examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT DISTINCT erss.studentID,
                            sa.regNo,
                            sa.rollNo,
                            sa.studentName,
                            sa.batchID,
                            e.semID,
                            e.examID,
                            e.subjectID,
                            ee.mark as 'mark1',
                            eem1.mark as 'mark2',
                            eem2.mark as 'mark3',
                            ee.mark as 'hasMark1',
                            eem1.mark as 'hasMark2',
                            eem2.mark as 'hasMark3',
                            IF($request->isPg = 1 ,eef.mark,ee.mark) as 'finalMark',
                            efn.false_number as 'falseNumber',
                            et.isAbsent from exam_reg_studentsubject erss
                                INNER JOIN exam_reg_studentchallan ersc ON (ersc.studentID = erss.studentID AND ersc.examregID = erss.examregID)
                                INNER JOIN studentaccount sa ON sa.studentID = ersc.studentID
                                INNER JOIN exam e ON (e.examregID = erss.examregID AND e.subjectID = erss.subjectID)
                                LEFT JOIN exammarks_external ee ON ee.studentID = ersc.studentID AND ee.examID = e.examID
                                LEFT JOIN examcontroller_false_number efn ON (efn.studentID = ersc.studentID AND efn.examID = e.examID)
                                LEFT JOIN external_exammarks eem1 ON eem1.studentID = ersc.studentID AND eem1.examID = e.examID AND eem1.valuationCount = 2
                                LEFT JOIN external_exammarks eem2 ON eem2.studentID = ersc.studentID AND eem2.examID = e.examID AND eem2.valuationCount = 3
                                LEFT JOIN externalexammarks_finalized eef ON (eef.studentID = ersc.studentID AND eef.examID = e.examID)
                                LEFT JOIN exam_attendance et ON (et.studentID = ersc.studentID AND et.examID = e.examID)
                                LEFT JOIN failed_students fs ON fs.studentID = sa.studentID
                                AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                                $thirdValStudents
                                WHERE erss.examregID = '$request->examRegId'
                                AND e.batchID = '$request->batchId'
                                AND erss.subjectID = '$request->subjectId'
                                AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID)
                                AND ersc.paid=1  order by sa.regNo";
        } else if ($request->examType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT DISTINCT esss.studentID,
                            sa.regNo,sa.studentName,
                            sa.batchID,
                            sa.rollNo,
                            e.semID,
                            e.examID,
                            e.subjectID,
                            ee.mark as 'mark1',
                            eem1.mark as 'mark2',
                            eem2.mark as 'mark3',
                            ee.mark as 'hasMark1',
                            eem1.mark as 'hasMark2',
                            eem2.mark as 'hasMark3',
                            IF($request->isPg = 1 ,eef.mark,ee.mark) as 'finalMark',
                            efn.false_number as 'falseNumber',
                            et.isAbsent FROM exam_supplementary_student_subjects esss
                                    INNER JOIN exam_supplementary_student_details essd ON (essd.studentID = esss.studentID AND essd.exam_supplementary_id = esss.exam_supplementary_id)
                                    INNER JOIN studentaccount sa ON sa.studentID = essd.studentID
                                    INNER JOIN exam e ON (e.batchID = sa.batchID)
                                    LEFT JOIN exammarks_external ee ON ee.studentID = essd.studentID AND ee.examID = e.examID
                                    LEFT JOIN examcontroller_false_number efn ON (efn.studentID = essd.studentID AND efn.examID = e.examID)
                                    LEFT JOIN external_exammarks eem1 ON eem1.studentID = essd.studentID AND eem1.examID = e.examID AND eem1.valuationCount = 2
                                    LEFT JOIN external_exammarks eem2 ON eem2.studentID = essd.studentID AND eem2.examID = e.examID AND eem2.valuationCount = 3
                                    LEFT JOIN externalexammarks_finalized eef ON (eef.studentID = essd.studentID AND eef.examID = e.examID)
                                    LEFT JOIN exam_attendance et ON (et.studentID = essd.studentID AND et.examID = e.examID)
                                    INNER JOIN exam ex ON ex.batchID = e.batchID AND ex.subjectID = e.subjectID AND ex.semID = e.semID AND ex.examID = esss.examID AND ex.examregID IS NOT NULL
                                    $thirdValStudents
                                    WHERE esss.exam_supplementary_id = '$request->examRegId'
                                    AND e.batchID = '$request->batchId'
                                    AND e.subjectID='$request->subjectId'
                                    AND essd.paid=1
                                    AND e.examID = '$request->examId'
                                    order by sa.regNo";
        }
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * @author Sibin
     * get exam reg students by batch and subjectid
     */
    public function getExamRegisteredStudentsByBatchAndSubjectId($examRegId,$batchId,$subjectId,$excludeStudentsWithCourseMode =null)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $subjectId = $this->realEscapeString($subjectId);
        $conditions="";
        if($excludeStudentsWithCourseMode){
            $conditions .= "  AND (ers.courseMode != '$excludeStudentsWithCourseMode' || ers.courseMode is null)";
        }
            $sql = "SELECT e.examID,erb.batchID,ersb.subjectID,ers.studentID from exam_registration_batches erb
                            INNER JOIN exam_reg_studentchallan ers on ers.examregID = erb.examregID
                            INNER JOIN exam_reg_studentsubject ersb ON ersb.examregID=erb.examregID and ersb.studentID = ers.studentID
                            INNER JOIN exam e on e.examregID =erb.examregID AND e.subjectID = ersb.subjectID and e.batchID=erb.batchID
                            INNER JOIN studentaccount sa ON sa.studentID = ers.studentID AND sa.batchID=erb.batchID
                            where erb.examregID='$examRegId' and erb.batchID='$batchId' and ersb.subjectID='$subjectId' and ers.paid=1
                            $conditions
                            order by sa.regNo";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    public function getAllExamMarksByRequest($request){
        $request = $this->realEscapeObject($request);
        $where = [];
        $request->batchId?$where[] = " e.batchID = $request->batchId ":"";
        $request->semId?$where[] = " e.semID = $request->semId ":"";
        $request->examTypeId?$where[] = " e.examTypeID = $request->examTypeId ":"";
        $request->subjectId?$where[] = " e.subjectID = $request->subjectId ":"";
        $request->subBatchIds?$where[] = " e.subbatchID in (".implode(',',$request->subBatchIds).") ":"";
        if($request->pseudoSubjectId){
            $request->studentId?$where[] = " pstd.studentID = '$request->studentId":"";
            $where[] = " psbs.pseudosubjectID = $request->pseudoSubjectId ";
            $sql="SELECT e.examID,
                        GROUP_CONCAT(distinct e.examID) as examIds,
                        e.examName,
                        e.examTypeID,
                        e.examTotalMarks,
                         e.subbatchID,
                        sm.markID,
                         sm.batchID,
                         sm.studentID,
                         sm.examID,
                        if(sm.marksObtained=-1,
                        'A',
                        if(sm.marksObtained<0,
                        'MAL',
                        sm.marksObtained)) as marksObtained,
                         sm.staffID,
                        sm.percentage,
                        e.examDate as dateOfTest,
                        im.internalMarks as final_converted,
                        ims.maxInternalMarks as max_final_converted
            FROM sbs_relation sbs
            INNER JOIN pseudosubjects_sbs psbs ON psbs.sbsID = sbs.sbsID
            INNER JOIN subbatch_sbs ssbs ON ssbs.sbsID = psbs.sbsID
            INNER JOIN subbatches sb ON sb.batchID = sbs.batchID 
                AND sb.semID = sbs.semID 
                AND ssbs.subbatchID = sb.subbatchID 
                AND psbs.pseudosubjectID = sb.psID
            INNER JOIN pseudosubjects_students pstd ON pstd.pseudosubjectID = psbs.pseudosubjectID
            INNER JOIN exam e ON e.subjectID = sbs.subjectID 
                AND e.batchID = sbs.batchID 
                AND e.semID = sbs.semID 
                AND e.subbatchID IN (sb.subbatchID , 0)
            INNER JOIN exam_type et ON et.typeID = e.examTypeID
            LEFT JOIN student_marks sm ON sm.studentID = pstd.studentID 
                AND sm.batchID = sbs.batchID 
                AND sm.examID = e.examID 
                AND sm.examTypeID = et.typeID 
                AND sm.subjectID = sbs.subjectID 
                AND sm.semID = sbs.semID
            LEFT JOIN internal_marks im on im.studentID = sm.studentID 
                and im.batchID = e.batchID 
                and im.semID = e.semID 
                and im.subjectID  = e.subjectID 
                LEFT JOIN internal_marks_settings ims on ims.batchID = e.batchID 
                and ims.semID = e.semID 
                and ims.subjectID  = e.subjectID 
            WHERE ".($where?implode(' AND ',$where):"")."
            GROUP BY e.examTypeID, pstd.studentID, sm.markID;";
        }else{
            $request->studentId?$where[] = " sm.studentID = '$request->studentId":"";
            $sql = "SELECT e.examID,
                        GROUP_CONCAT(distinct e.examID) as examIds,
                        e.examName,
                        e.examTypeID,
                        e.examTotalMarks,
                         e.subbatchID,
                        sm.markID,
                         sm.batchID,
                         sm.studentID,
                         sm.examID,
                        if(sm.marksObtained=-1,
                        'A',
                        if(sm.marksObtained<0,
                        'MAL',
                        sm.marksObtained)) as marksObtained,
                         sm.staffID,
                        sm.percentage,
                        e.examDate as dateOfTest,
                        im.internalMarks as final_converted,
                        ims.maxInternalMarks as max_final_converted
                     FROM exam e 
                    LEFT JOIN student_marks sm on e.examID = sm.examID 
                    and e.subjectID = sm.subjectID 
                    and e.examTypeID = sm.examTypeID 
                    and e.batchID = sm.batchID 
                    LEFT JOIN internal_marks im on im.studentID = sm.studentID 
                    and im.batchID = e.batchID 
                    and im.semID = e.semID 
                    and im.subjectID  = e.subjectID 
                    LEFT JOIN internal_marks_settings ims on ims.batchID = e.batchID 
                    and ims.semID = e.semID 
                    and ims.subjectID  = e.subjectID ".($where?" WHERE ".implode(' AND ',
                        $where):"")."
            GROUP BY e.examTypeID,e.batchID,e.semID,sm.studentID;";
        }
        try {
            if(empty($where)){
                return [];
            }else{
                return $this->executeQueryForList($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @author Sibin
     *update exam external marks by student
     */
    public function updateExamExternalMarks($request,$valCount)
    {
        $request = $this->realEscapeObject($request);
        $valCount= $this->realEscapeString($valCount);
        $result="";
        $sql="";
            if($valCount == 1){
                $sql = "UPDATE exammarks_external set mark = '$request->mark1'
                        WHERE examID='$request->examID' AND studentID='$request->studentID'";
            }
            elseif($valCount == 2){
                $sql = " UPDATE external_exammarks set mark = '$request->mark2'
                        WHERE examID = '$request->examID' AND studentID = '$request->studentID' AND valuationCount = '2'";
            }
            elseif($valCount == 3){
                $sql = " UPDATE external_exammarks set mark = '$request->mark3'
                        WHERE examID = '$request->examID' AND studentID = '$request->studentID' AND valuationCount = '3'";
            }
        try {
            if($sql){
                $this->executeQueryForObject($sql);
                $result=true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * @author Sibin
     * get examMarks by examId
     */
    public function getStudentMarksExistByExamId($isPg,$examId)
    {
        $examId = $this->realEscapeString($examId);
        $isPg = $this->realEscapeString($isPg);
        $examEntry="";
        if($isPg){
            $sql = "SELECT distinct examID from externalexammarks_finalized WHERE examID ='$examId'";
        }
        else{
            $sql = "SELECT distinct examID from exammarks_external WHERE examID ='$examId'";
        }
        try {
            $examEntry = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examEntry;
    }
     /**
     * @param $batchId
     * @param $month
     * @param $year
     * save program result month and year
     */
    public function saveProgramResultMonthAndYear($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 program_result_date WHERE batchID ='$batchId'";
        try {
            $result = $this->executeQueryForList($sql);
            if(empty($result)){
                $sql1 = "INSERT INTO program_result_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 program_result_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 getProgramResultMonthAndYear($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT examMonth, examYear from program_result_date WHERE batchID ='$batchId'";
        try {
            $result = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result [0];
    }
     /**
     * get category code by batch sem relation
     */
    public function getSubjectTypeByBatchSemSubjectID($batchId , $semId, $subjectId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "SELECT
            cc.categoryCode
        FROM
            batch_sem_subjectCategory_relation bssr
        INNER JOIN batches b ON
            b.batchID = bssr.batchID
        INNER JOIN categoryCode cc ON
            bssr.subjectcatID = cc.subject_category_id
            AND cc.course_type_id = b.courseTypeID
        WHERE
            bssr.batchID = $batchId
            AND bssr.semID = $semId
            AND bssr.subjectID = $subjectId";
        try {
            $result  = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result->categoryCode;
    }
    /**
     * @author Sibin
     * get Exams By ExamRegistration,Sem
     */
    public function getExamsByExamRegistrationAndSem($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        $examRegField = ($request->examType == ExamType::SUPPLY) ? "supply_examreg_id": "examregID";
        if ($request->examRegId) {
            $whereConditions .= " AND e.$examRegField IN ($request->examRegId)";
        }
        if ($request->semId) {
            $whereConditions .= " AND e.semID IN ($request->semId)";
        }
        if ($request->batchId) {
            $whereConditions .= " AND e.batchID IN ($request->batchId)";
        }
        if($request->examDate){
            $whereConditions .= " AND e.examDate IN ('$request->examDate')";
        }
        $sql = "SELECT
                    e.batchID as 'batchId',
                    b.batchName,
                    b.batchDesc,
                    e.semID as 'semId',
                    e.examID AS examId,
                    e.examName AS examName,
                    e.subjectID as 'subjectId',
                    s.subjectName,
                    s.subjectDesc,
                    e.examDate
                FROM
                    exam e
                    INNER JOIN batches b ON b.batchID = e.batchID
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                WHERE
                    1 = 1
                    $whereConditions";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
    * Get details of exam of a subject
    * @throws ProfessionalException
    * @author Sibin
    */
        public function getExamDetailsByRequest( $examRequest ) {
            $examRequest = $this->realEscapeObject ( $examRequest );
            $sql = null;
            $condition = null;
            $exam = null;
            if(!$examRequest->examType || !$examRequest->examRegId || !$examRequest->subjectId || !$examRequest->semId){
                return;
            }
            if ( $examRequest->examType === ExamType::REGULAR ) {
                $condition = " AND e.examRegId = '$examRequest->examRegId";
            }
            else if ( $examRequest->examType === ExamType::SUPPLY ) {
                $condition = " AND e.supply_examreg_id = '$examRequest->examRegId";
            }
            try {
                $sql = "SELECT distinct s.subjectName, s.subjectDesc, sem.semName, IF(e.examRegId, er.examregName, es.supplyDesc) AS examRegName
                            FROM exam e INNER JOIN subjects s ON s.subjectID = e.subjectID
                            INNER JOIN semesters sem ON sem.semID = e.semID
                            LEFT JOIN exam_registration er ON er.examregID = e.examregID
                            LEFT JOIN exam_supplementary es ON es.id = e.supply_examreg_id
                            WHERE e.subjectId = '$examRequest->subjectId' AND e.semId = '$examRequest->semId'
                            $condition
                            ";
                $exam = $this->executeQueryForObject($sql);
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(),$e->getMessage());
            }
            return $exam;
        }
     /**
     * Get exam registration details
     * @param  $request
     * @return Array
     * @throws ProfessionalException
     */
    public function getDistinctExamRegistrationByBatchStartYear($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if ($request->courseType){
            $condition = " and ct.course_Type='$request->courseType'";
        }
        if ($request->avoidSem){
            $condition .= " and s.semName not in ('$request->avoidSem')";
        }
        $sql = "SELECT DISTINCT erb.examregID, er.examregName from exam_registration_batches erb inner join batches bt on (erb.batchID =bt.batchID ) Inner join exam_registration er on (er.examregID = erb.examregID ) inner join course_type ct on(ct.courseTypeID =bt.courseTypeID ) inner join semesters s on (s.semID = erb.semID ) where bt.batchStartYear =$request->batchStartYear".$condition;
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
     /**
     * Get distinct semesters by examRegId
     * @param  $examRegId
     * @return array
     * @throws ProfessionalException
     */
    public function getDistinctSemesteresFromExamRegId($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $sql = "SELECT DISTINCT s.semID , s.semName from exam_registration_batches erb inner join semesters s ON (erb.semID = s.semID) where erb.examregID=$examRegId ORDER BY s.semName ASC ";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
     /**
     * Get Batches by examRegId
     * @param  $examRegId
     * @return array
     * @throws ProfessionalException
     */
    public function getBatchesFromExamRegId($examRegId,$semId,$skipYear)
    {
        $examRegId = $this->realEscapeString($examRegId);
        if($semId){
            $condition = " and erb.semID  in ('$semId')";
        }
        if($skipYear){
            $condition .= " and bt.batchStartYear not in ('$skipYear')";
        }
        $sql = "SELECT bt.batchID ,bt.batchName, erb.semID from exam_registration_batches erb inner join batches bt ON (erb.batchID = bt.batchID ) where erb.examregID=$examRegId".$condition;
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
     /**
     * change batches exam registration
     * @param  $request
     * @return array
     * @throws ProfessionalException
     */
    public function changeBatchesExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $sql = "INSERT INTO exam_registration (examregName, examregDesc ,examMonth ,examYear, shortCourse ) VALUES('$request->examRegName', '$request->examRegName', '$request->examMonth', '$request->examYear', 0)";
        try {
            $examRegId = $this->executeQueryForObject($sql,true);
            $sql1 = " INSERT INTO exam_registration_fees (examregID, examfeesID, examfeesAmount) SELECT $examRegId, examfeesID, 0 FROM exam_feestype WHERE everySubject = 1";
            $this->executeQuery($sql1);
            foreach($request->batchList as $batch){
                $batch = (object) $batch;
                $sql2 = " UPDATE exam_registration_batches set examregID =$examRegId WHERE batchID =$batch->batchID and semID =$batch->semID and examregID=$request->oldExamRegId";
                $this->executeQuery($sql2);
                $sql3 = " UPDATE exam_registration_subject_fees set examregID =$examRegId WHERE batchID =$batch->batchID and semID =$batch->semID and examregID=$request->oldExamRegId";
                $this->executeQuery($sql3);
                $sql4 = " UPDATE exam_reg_studentchallan ers inner join studentaccount sa on (ers.studentID = sa.studentID ) set ers.examregID =$examRegId WHERE sa.batchID =$batch->batchID and ers.examregID =$request->oldExamRegId";
                $this->executeQuery($sql4);
                $sql5 = " UPDATE exam_reg_studentsubject ers inner join studentaccount sa on (ers.studentID = sa.studentID ) set ers.examregID =$examRegId WHERE sa.batchID =$batch->batchID and ers.examregID =$request->oldExamRegId";
                $this->executeQuery($sql5);
                $sql6 = " UPDATE exam set examregID =$examRegId WHERE batchID =$batch->batchID and semID =$batch->semID  and examregID=$request->oldExamRegId";
                $this->executeQuery($sql6);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
            /**
     * Get supply exam absent status by studentID and regular examID
     */
    public function getSupplyAbsentStatusByStudentAndRegularExamId($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$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;
    }
    /**
     * @param $batchId,$semId,$month,$year
     * get supply registration by month and year
     */
    public function getSupplyRegistrationBybatchIdAndMonthYear($batchId,$semId,$month,$year)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $month = $this->realEscapeString($month);
        $year = $this->realEscapeString($year);
        $sql = "
        SELECT es.id, es.supplyDesc, es.examDate FROM exam_supplementary es inner join supply_improve_batches sib on (es.id =sib.exam_supplementary_id ) where es.semID =$semId and sib.batchID =$batchId and es.examMonth ='$month' and es.examYear ='$year'";
        try {
            $result = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result [0];
    }
    /**
     * @param $studentId
     * @param $subjectId
     * @return mixed
     * @throws ProfessionalException
     */
    public function subjectSupplyAttemptCount($studentId, $subjectId)
    {
        $studentId = $this->realEscapeString($studentId);
        $subjectId = $this->realEscapeString($subjectId);
        if (empty($studentId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid student");
        }
        if (empty($subjectId)) {
            throw new ProfessionalException(ProfessionalException::INVALID_REQUEST, "Invalid subject");
        }
        $sql = "SELECT
            COUNT(esss.exam_supplementary_id) AS supplyAttemptCount
        FROM
            exam_supplementary_student_subjects esss
        INNER JOIN exam e ON
            e.examID = esss.examID
        INNER JOIN exam_supplementary_student_details essd ON
            essd.studentID = esss.studentID
            AND essd.exam_supplementary_id = esss.exam_supplementary_id
        WHERE
            essd.isSupply = 1
            AND esss.studentID = $studentId
            AND e.subjectID = $subjectId";
        try {
            return $this->executeQueryForObject($sql)->supplyAttemptCount;
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @author Sibin
     *update exam external marks by student
     */
    public function saveExamExternalMarks($request,$extraDetails)
    {
        $request = $this->realEscapeObject($request);
        $extraDetails= $this->realEscapeObject($extraDetails);
        $result="";
        $finalisedMark="";
        $finaliseMarkSql="";
        $sql="";
            if($extraDetails->valCount == 1){
                $sql = "INSERT INTO exammarks_external (examID, studentID,mark,staffID,false_number)
                            VALUES('$request->examID','$request->studentID','$request->mark1','$extraDetails->adminId','$request->falseNumber')
                            ON DUPLICATE KEY UPDATE
                            mark = VALUES(mark),
                            staffID = VALUES(staffID),
                            false_number = VALUES(false_number)";
            }
            elseif($extraDetails->valCount == 2){
                $sql = "INSERT INTO external_exammarks (examID,studentID,mark,false_number,valuationCount)
                            VALUES('$request->examID','$request->studentID','$request->mark2','$request->falseNumber','$extraDetails->valCount')
                                ON DUPLICATE KEY UPDATE
                                mark = VALUES(mark),
                                false_number = VALUES(false_number)";
                //delete from finalised marks if eligible for 3rd valuation
                if($request->eligibleForThirdVal == 1){
                    $finaliseMarkSql = "DELETE from externalexammarks_finalized WHERE examID='$request->examID' AND studentID='$request->studentID'";
                }
                //Finalie the marks if not eligible for 3rd valuation
                elseif($request->eligibleForThirdVal == 0){
                    $finalisedMark = round(($request->mark1 + $request->mark2) / 2,2);
                    $finaliseMarkSql = "INSERT INTO externalexammarks_finalized (examID,studentID,mark)
                                VALUES('$request->examID','$request->studentID','$finalisedMark')
                                    ON DUPLICATE KEY UPDATE
                                    mark = VALUES(mark)";
                }
                if($finaliseMarkSql){
                    $this->executeQueryForObject($finaliseMarkSql);
                }
            }
            elseif($extraDetails->valCount == 3){
                $sql = "INSERT INTO external_exammarks (examID,studentID,mark,false_number,valuationCount)
                            VALUES('$request->examID','$request->studentID','$request->mark3','$request->falseNumber','$extraDetails->valCount')
                                ON DUPLICATE KEY UPDATE
                                mark = VALUES(mark),
                                false_number = VALUES(false_number)";
            }
        try {
            if($sql){
                $this->executeQueryForObject($sql);
                $result=true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
        /**
     * @param $supplyRegId
     * @param $batchId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getSupplyExamPublishDate($supplyRegId, $batchId)
    {
        $supplyRegId = $this->realEscapeString($supplyRegId);
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT fromDate, publish FROM supplyexam_publishresult where exam_supplementary_id =$supplyRegId and batchID =$batchId ";
        try {
            $supplyDate = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyDate[0];
    }
    /**
     * @param $studentId
     * @param $examregId
     * @param $batchId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getHallTicketDetails($studentId, $batchId,$examregId)
    {
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $examregId = $this->realEscapeString($examregId);
        $sql = "SELECT
        s.subjectName,
        s.subjectDesc,
        e.examDate,
        e.examStartTime AS startTime,
        e.examEndTime AS endTime
        FROM
            exam_reg_studentchallan ersc
            INNER JOIN
            exam_reg_studentsubject ers ON ers.studentID = ersc.studentID AND ers.examregID = ersc.examregID
                INNER JOIN
            exam e ON e.subjectID = ers.subjectID
                AND e.examregID = ers.examregID
                INNER JOIN
            subjects s ON s.subjectID = ers.subjectID
                AND s.subjectID = e.subjectID
        WHERE
            ers.studentID = $studentId
                AND ers.examregID = $examregId
                AND e.batchID = $batchId
                AND ersc.paid=1 ORDER BY e.examDate ASC";
        try {
            $response = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    /**
     * @param  $request
     * @return array|Object
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamRegistrationsByBatchRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $batchId = $request->batchId;
        $condition = null;
        $orderBycondition="";
        if ($request->examRegId) {
            $condition .= " AND er.examregID = '$request->examRegId";
        }
        if ($request->examYear) {
            $condition .= " AND er.examYear = '$request->examYear";
        }
        if ($request->examYearFrom) {
            $condition .= " AND er.examYear >= '$request->examYearFrom";
        }
        if($request->orderByExamYear){
            $orderBycondition = " ORDER BY IF(CAST(er.examYear AS SIGNED) = 0, 99999, CAST(er.examYear AS SIGNED)) DESC,IF(CAST(er.examMonth AS SIGNED) = 0, 99999, CAST(er.examMonth AS SIGNED)) DESC";
        }
        $sql = null;
        $examRegistrations = [];
        try {
            $sql = "SELECT er.examregID AS id, er.examregName AS name, erb.semID AS semId,er.examYear,er.examMonth,er.enable_hlticket as enableHallTicket
            FROM exam_registration er INNER JOIN exam_registration_batches erb ON (er.examregID = erb.examregID)
            WHERE erb.batchID = '$batchId$condition
            $orderBycondition";
            $examRegistrations = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examRegistrations;
    }
    /**
     * Get student exam subjects
     * @param Object
     * @return Array Exam subject list
     * @throws ProfessionalException
     * @author sibin
     */
    public function getStudentExamSubjects($request)
    {
        $request = $this->realEscapeObject($request);
        $subjects = [];
        $sql = "SELECT ers.studentID,ers.examregID,e.semID,e.examID,e.examName,e.examTotalMarks,e.examDate,e.examStartTime,e.examEndTime,ers.subjectID,s.syllabusName,s.subjectName,s.subjectDesc
                    from exam_reg_studentsubject ers
                    INNER JOIN exam e ON e.examregID = ers.examregID AND e.subjectID = ers.subjectID
                    INNER JOIN subjects s ON s.subjectID = ers.subjectID
                    where ers.examregID='$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 student exam reg paid status
     * @param Object
     * @throws ProfessionalException
     * @author sibin
     */
    public function getStudentExamRegPaidStatus($request)
    {
        $request = $this->realEscapeObject($request);
        $paid = null;
        $sql = "SELECT paid from exam_reg_studentchallan
                    where examregID='$request->examRegId'
                    and studentID='$request->studentId'";
        try {
            $paid = $this->executeQueryForObject($sql)->paid;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $paid;
    }
    /**
     * Get student exam reg paid status
     * @param Object
     * @throws ProfessionalException
     * @author sibin
     */
    public function getStudentExamsInAttendanceMarked($request)
    {
        $request = $this->realEscapeObject($request);
        $exams = [];
            $sql = "SELECT e.examID,ea.isAbsent from exam e
                        INNER JOIN exam_attendance ea ON ea.examID = e.examID
                        WHERE e.examregID ='$request->examRegId' and e.batchID = '$request->batchId' and e.semID = '$request->semId'
                        and ea.studentID ='$request->studentId'";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
    /**
     * Get exam details by Requesest
     * @param Object $request
     * @return object|NULL|$objectList[]
     * @throws ProfessionalException
     */
    public function getExamDetailsForOEExamsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $semId = $request->semID;
        $batchId = $request->batchId;
        $examTypeId = $request->examTypeId;
        $subjectId = $request->subjectId;
        $innerJoinTables = "";
        $whereConditions = "";
        if ($semId) {
            $whereConditions .= " AND e.semID IN ($semId)";
        }
        if ($batchId) {
            $whereConditions .= " AND e.batchID IN ($batchId)";
        }
        if ($examTypeId) {
            $whereConditions .= " AND e.examTypeID IN ($examTypeId)";
        }
        if ($subjectId) {
            $whereConditions .= " AND e.subjectID IN ($subjectId)";
        }
        if ($request->examRegId) {
            $whereConditions .= " AND e.examregID IN ($request->examRegId)";
        }
        if ($request->supplyExamRegId) {
            $whereConditions .= " AND e.supply_examreg_id IN ($request->supplyExamRegId)";
        }
        if ($request->subBatchId) {
            $whereConditions .= " AND e.subbatchID IN ($request->subBatchId)";
        }
        $sql = "SELECT
            e.examID AS id,
            e.examTotalMarks,
            e.examName AS name,
            e.examregID,
            e.supply_examreg_id as supplyExamRegId,
            e.batchID,
            e.semID,
            e.subjectID,
            e.examTypeID,
            e.subbatchID,
            e.examDate,
            e.examStartTime,
            e.examEndTime,
            e.examTotalMarks,
            CONCAT(e.examDate ,' ',e.examStartTime) as examStartDateTime,
            CONCAT(e.examDate ,' ',e.examEndTime) as examEndDateTime,
            e.created_by
        FROM
            exam e
            $innerJoinTables
        WHERE
            1=1
            $whereConditions";
        try {
            if ($request->getList) {
                $exams = $this->executeQueryForList($sql);
            } else {
                $exams = $this->executeQueryForObject($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
     * save online examinations
     * @param Object
     * @throws ProfessionalException
     * @author sibin
     */
    public function saveOnlineExaminations($request,$examDetails)
    {
        $exams = $this->realEscapeObject($request);
        $examDetails = $this->realEscapeObject($examDetails);
        $isSupply = (int)$examDetails->isSupply;
        $staffId = $_SESSION['adminID'];
        $result = null;
        try {
            foreach ($exams as $exam) {
                $existingExam = null;
                $onlineExamId = null;
                $identifyingContext = new \StdClass;
                $properties =  new \StdClass;
                $existingExam = ExamService::getInstance()->getExamDetailsForOEExamsByRequest($exam);
                if ($existingExam) {
                    $subjectDetails =  SubjectService::getInstance()->getSubject($existingExam->subjectID);
                    $batchDetails =  BatchService::getInstance()->getBatchNameById($existingExam->batchID);
                    $existingExam->name =$subjectDetails->syllabusName."-". $subjectDetails->description."-". $batchDetails->name;
                    $onlineExamId = SecurityUtils::getRandomString();
                    $from_time = strtotime($existingExam->examStartTime);
                    $to_time = strtotime($existingExam->examEndTime);
                    $onlineExamId = SecurityUtils::getRandomString();
                    $identifyingContext->examId    = $existingExam->id;
                    if($isSupply){
                        $identifyingContext->supplyExamRegId = $existingExam->supplyExamRegId;
                        $identifyingContext->isSupply = true;
                    }else{
                        $identifyingContext->examRegId = $existingExam->examregID;
                    }
                    $identifyingContext->batchId   = $existingExam->batchID;
                    $identifyingContext->semId     = $existingExam->semID;
                    $identifyingContext->subjectId = $existingExam->subjectID;
                    $identifyingContext->staffId   = $staffId;
                    $identifyingContext->type      = $examDetails->onlineExamType;
                    $identifyingContext            = json_encode($identifyingContext);
                    $properties->timeLimit          = round(abs($to_time - $from_time) / 60, 2);;
                    $properties->startTime          = date("Y-m-d H:i:s", strtotime($existingExam->examStartDateTime));;
                    $properties->endTime            = date("Y-m-d H:i:s", strtotime($existingExam->examEndDateTime));
                    $properties->passPercentage     = null;
                    $properties->maxMark            = $existingExam->examTotalMarks;
                    $properties->isLocked           = "1";
                    $properties->instructions       = null;
                    $properties->reviewPercentage   = $examDetails->reviewPercentage ? $examDetails->reviewPercentage : null;
                    $propertiesJson                 = json_encode($properties);
                    if($isSupply){
                        $isOeExamExistSql ="SELECT id,name from oe_exams
                                            WHERE JSON_CONTAINS(identifying_context, '{\"examId\":\"$existingExam->id\",\"supplyExamRegId\":\"$existingExam->supplyExamRegId\",\"batchId\":\"$existingExam->batchID\", \"semId\":\"$existingExam->semID\", \"subjectId\":\"$existingExam->subjectID\"}')
                                            AND type ='EXAM_CONTROLLER' AND (properties ->> '$.isMockExam' != 'true' OR properties ->> '$.isMockExam' is null)";
                    }else{
                        $isOeExamExistSql ="SELECT id,name from oe_exams
                                            WHERE JSON_CONTAINS(identifying_context, '{\"examId\":\"$existingExam->id\",\"examRegId\":\"$existingExam->examregID\",\"batchId\":\"$existingExam->batchID\", \"semId\":\"$existingExam->semID\", \"subjectId\":\"$existingExam->subjectID\"}')
                                            AND type ='EXAM_CONTROLLER' AND (properties ->> '$.isMockExam' != 'true' OR properties ->> '$.isMockExam' is null)";
                    }
                    $isOeExamExists = $this->executeQueryForObject($isOeExamExistSql);
                    if (empty ($isOeExamExists)){
                        //insert
                        $onlineExamValues[] = "(
                                '$onlineExamId',
                                '$existingExam->name',
                                '$existingExam->name',
                                'EXAM_CONTROLLER',
                                '$identifyingContext',
                                '$propertiesJson',
                                'STAFF',
                                '$staffId'
                            )";
                    }
                     else{
                    //update
                        $oeExamUpdateSql = "UPDATE oe_exams set name = '$existingExam->name ',updated_by='$staffId',
                                                properties = JSON_SET(properties,\"$.endTime\",'$properties->endTime',
                                                \"$.startTime\", '$properties->startTime',
                                                \"$.timeLimit\", '$properties->timeLimit',
                                                \"$.maxMark\", '$properties->maxMark'),
                                                identifying_context = JSON_SET(identifying_context,\"$.type\",'$examDetails->onlineExamType')
                                                    WHERE id='$isOeExamExists->id'";
                        $this->executeQuery($oeExamUpdateSql);
                        $result = true;
                    }
                        unset($existingExam);
                        unset($from_time);
                        unset($to_time);
                        unset($isOeExamExists);
                        unset($subjectDetails);
                        unset($batchDetails);
                }
            }
            if (!empty($onlineExamValues)) {
                $sql = "INSERT into oe_exams(id, name, description, type, identifying_context, properties, user_type,created_by) VALUES " . implode(", ", $onlineExamValues);
                $this->executeQuery($sql);
                $result=true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * Method for getting last registered exam stduents for a batchId
     * @input $batchId $examRegId
     * @author Sibin
     */
    public function lastRegisteredExamStudentsByBatch($batchId, $examRegId)
    {
        $sql = null;
        $batchId = $this->realEscapeString($batchId);
        $examRegId = $this->realEscapeString($examRegId);
        $lastRegisteredExamStudents = null;
        $sql = "SELECT ersc.studentID,sa.studentGender FROM exam_reg_studentchallan ersc INNER JOIN studentaccount sa ON ersc.studentID = sa.studentID WHERE ersc.examregID = $examRegId AND ersc.paid = 1 AND sa.batchID = $batchId";
        try {
            $lastRegisteredExamStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $lastRegisteredExamStudents;
    }
    /**
     * get student internal Mark by sem
     * @input $batchId $semID $subjectID $studentID
     * @author Sibin
     */
    public function studentInteranlMarksBySubject($batchId, $semId,$subjectId,$studentId)
    {
        $sql = null;
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $studentId= $this->realEscapeString($studentId);
        $internalMark = null;
        $sql = "SELECT im.internalMarkID,im.internalMarks as internalMark,ims.maxInternalMarks as internalMaxMark from internal_marks im
                    INNER JOIN internal_marks_settings ims ON ims.batchID = im.batchID AND ims.semID = im.semID AND ims.subjectID = im.subjectID
                    WHERE im.batchID='$batchId' AND im.semID='$semId' AND im.subjectID='$subjectId' AND im.studentID='$studentId'";
        try {
            $internalMark = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $internalMark;
    }
       /**
     * @param $batchId
     * @param $semId
     * @param $startDate
     * @param $endDate
     * save audit course Dates
     */
    public function saveAuditCouseDates($batchId,$semId,$startDate,$endDate)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $startDate = $this->realEscapeString($startDate);
        $endDate = $this->realEscapeString($endDate);
        $sql = "SELECT * from audit_course_date_settings WHERE batchID ='$batchId' and semID=$semId";
        try {
            $result = $this->executeQueryForList($sql);
            if(empty($result)){
                $sql1 = "INSERT INTO audit_course_date_settings(batchID,semID,startDate,endDate) VALUES('$batchId',$semId,'$startDate','$endDate')";
            }
            else{
                $sql1 = "UPDATE audit_course_date_settings set startDate = '$startDate' , endDate = '$endDate' WHERE batchID =$batchId and semID = $semId";
            }
            $this->executeQuery($sql1);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
        /**
     * @param $batchId
     * @param $semId
     * get audit course Dates
     */
    public function getAuditCouseDates($batchId,$semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT endDate,startDate from audit_course_date_settings WHERE batchID ='$batchId' and semID=$semId";
        try {
            $result = $this->executeQueryForList($sql);
            return $result[0];
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
     /**
     * get exam reg students by examRegId, batchid and subjectid
     */
    public function getExamRegisteredStudentsByBatchIdAndSubjectId($examRegId,$batchId,$subjectId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $subjectId = $this->realEscapeString($subjectId);
            $sql = "SELECT ers.studentID, sa.regNo ,sa.studentName, sa.rollNo from  exam_reg_studentchallan ers
            INNER JOIN exam_reg_studentsubject ersb ON ersb.examregID=ers.examregID and ersb.studentID = ers.studentID
            INNER JOIN studentaccount sa ON sa.studentID = ers.studentID AND sa.studentID = ersb.studentID
            where ers.examregID='$examRegId' and sa.batchID='$batchId' and ersb.subjectID='$subjectId' and ers.paid=1
            order by sa.regNo";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
           /**
     * @param $studentId
     * @param $semId
     * @param $subjectId
     * @param $flag
     * save audit course Dates
     */
    public function saveAuditCoursePassDetails($studentId,$semId,$subjectId,$flag)
    {
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $flag = $this->realEscapeString($flag);
        $sql = "SELECT * from audit_course_student_pass_details WHERE studentID ='$studentId' and semID = $semId and subjectID = $subjectId";
        try {
            $result = $this->executeQueryForList($sql);
            if(empty($result)){
                $sql1 = "INSERT INTO audit_course_student_pass_details(studentID,semID,subjectID,flag) VALUES('$studentId',$semId,'$subjectId','$flag')";
            }
            else{
                $sql1 = "UPDATE audit_course_student_pass_details set flag = '$flag'  WHERE studentID ='$studentId' and semID = $semId and subjectID = $subjectId";
            }
            $this->executeQuery($sql1);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
               /**
     * @param $studentId
     * @param $semId
     * @param $subjectId
     * save audit course Dates
     */
    public function getAuditCoursePassDetails($studentId,$semId,$subjectId)
    {
        $studentId = $this->realEscapeString($studentId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $sql = "SELECT flag from audit_course_student_pass_details WHERE studentID ='$studentId' and semID = $semId and subjectID = $subjectId";
        try {
            $result = $this->executeQueryForList($sql);
            return $result[0]->flag;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
        /**
     * get student grace mark details
     * @param $studentId
     * @param $semId
     */
    public function getGraceMarkDetailsByStudentIdAndSemid($studentId, $semId)
    {
        $studentId = (int)$this->realEscapeString($studentId);
        $semId = (int)$this->realEscapeString($semId);
        $sql = "SELECT marks FROM gracemarks_student_marks WHERE studentID = $studentId AND semID = $semId ";
        try {
            $graceMarkDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $graceMarkDetails;
    }
    /**
     * get reserve Category ExamFees
     * @param $request
     * @author sibin
     */
    public function getReserveCategoryExamFees($request)
    {
        $examFeesIds=[];
        $request = $this->realEscapeObject($request);
        if($request->examRegId){
            $condition ="and ersr.examRegId='$request->examRegId'";
        }
        else if($request->supplyExamRegId){
            $condition = "and ersr.supplyExamRegId='$request->supplyExamRegId'";
        }
        $sql = "SELECT ersr.examRegId,ersr.supplyExamRegId,ersr.reservID,ersr.examfeesID from examFeesReservationCategoryRelation ersr
                    INNER JOIN studentaccount sa ON sa.reservID = ersr.reservID where  sa.studentID='$request->studentId$condition";
        try {
            $examFeesIds = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examFeesIds;
    }
    /**
     * get Exams By ExamRegId And ExamDate
     * @param $request
     * @author sibin
     */
    public function getExamsByExamRegIdAndExamDate($request)
    {
        $exams = [];
        $request = $this->realEscapeObject($request);
        $examReg= $condition = "";
        if ($request->examRegId) {
            $examReg ="er.examregName";
            $condition .= " and e.examRegId='$request->examRegId";
        } else if ($request->supplyExamRegId) {
            $examReg = "es.supplyDesc as examregName";
            $condition .= " and e.supply_examreg_id='$request->supplyExamRegId";
        }
        if($request->isTheory){
            $condition .= ($request->isTheory == 1) ? " AND s.isTheory = '$request->isTheory" :  " AND s.isTheory = '0' ";
        }
        if ($request->batchId) {
            $condition .= " AND e.batchID IN ($request->batchId)";
        }
        if ($request->subjectId) {
            $condition .= " AND e.subjectID IN ($request->subjectId)";
        }
        if($request->examDate){
            $condition .= " AND e.examDate='$request->examDate'";
        }
        $sql = "SELECT e.examregID,e.supply_examreg_id,$examReg,e.examID,e.examName,e.examdate,e.batchID,b.batchName, e.examStartTime, e.examEndTime,e.subjectID,s.subjectName,s.subjectDesc,s.isTheory from exam e
                    INNER JOIN batches b ON b.batchID=e.batchID
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                    LEFT JOIN exam_registration er ON er.examregID = e.examregID
                    LEFT JOIN exam_supplementary es ON es.id = e.supply_examreg_id
                    where 1=1
                    $condition order by e.batchID";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
      /**
     * get Supply Registration By BatchId
     * @param $batchId
     */
    public function getSupplyRegistrationByBatchId($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = "SELECT sib.exam_supplementary_id ,es.supplyDesc, es.examMonth , es.examYear, es.semID from supply_improve_batches sib inner join exam_supplementary es on (es.id = sib.exam_supplementary_id) where sib.batchID = $batchId";
        try {
            $supplyList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyList;
    }
    /**
     * get Regular Exam Details By BatchId
     * @param $batchId, $semId
     */
    public function getRegularExamDetailsByBatchIdAndSemId($batchId,$semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT er.examregID, er.examregName, er.examMonth, er.examYear from exam_registration er inner join exam_registration_batches erb on (er.examregID = erb.examregID ) where erb.batchID =$batchId and erb.semID = $semId";
        try {
            $examDetail = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetail[0];
    }
      /**
     * get supply registration by month and year
     * @param $month, $year
     */
    public function getSupplyRegistrationByMonthAndYear($month,$year)
    {
        $month = $this->realEscapeString($month);
        $year = $this->realEscapeString($year);
        $sql = "SELECT id,semID  from exam_supplementary es where examMonth='$month' and examYear ='$year'";
        try {
            $supplyRegistration = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyRegistration;
    }
    /**
     * @param $studentId
     * @param $examRegId
     * @param $isPaid
     * @throws ProfessionalException
     * @author Sibin
     */
    public function updateStudentExamRevaluationPaidStatus($studentId, $examRegId, $isPaid)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $isPaid = $this->realEscapeString($isPaid);
        $sql = null;
        try {
            $sql = "UPDATE exam_revaluation_student_details SET paid = $isPaid WHERE studentID = $studentId AND exam_revaluation_id = $examRegId ";
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
        /**
     * @param $studentId
     * @param $examRegId
     * @param $isSupply
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamRegReceiptDetails($studentId, $examRegId)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $receiptDetails = null;
        $sql = null;
        try {
            $sql = "SELECT sa.regNo,sa.rollNo,sa.studentName,ers.challanNo,ers.examtotalFees,ers.payment_method as paymentMethod,ers.paid,ers.dateofPay,er.examregName,b.batchName,erb.semID, DATE_FORMAT(sa.studentBirthday, '%d-%m-%Y') AS studentBirthday,ers.dateofRegistration
                        from exam_reg_studentchallan ers
                        INNER JOIN studentaccount sa ON sa.studentID = ers.studentID
                        INNER JOIN batches b on b.batchID = sa.batchID
                        LEFT JOIN exam_registration er ON er.examregID = ers.examregID
                        LEFT JOIN exam_registration_batches erb ON erb.examregID = ers.examregID AND erb.batchID = sa.batchID
                        where ers.examregID='$examRegId' and ers.studentID='$studentId'";
            $receiptDetails =  $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $receiptDetails;
    }
    /**
     * @param $studentId
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getSupplyExamRegReceiptDetails($studentId, $examRegId)
    {
        $studentId = $this->realEscapeString($studentId);
        $examRegId = $this->realEscapeString($examRegId);
        $receiptDetails = null;
        $sql = null;
        try {
            $sql = "SELECT sa.regNo,sa.rollNo,sa.studentName,ers.challanNo,ers.total_fees as examtotalFees,ers.payment_method as paymentMethod,ers.paid,ers.fee_paidDate as dateofPay,ers.approved,er.supplyDesc as examregName,b.batchName,er.semID, DATE_FORMAT(sa.studentBirthday, '%d-%m-%Y') AS studentBirthday,ers.appliedDate AS dateofRegistration,ers.isSupply
                    from exam_supplementary_student_details ers 
                    INNER JOIN studentaccount sa ON sa.studentID = ers.studentID 
                    INNER JOIN batches b on b.batchID = sa.batchID
                    LEFT JOIN exam_supplementary er ON er.id = ers.exam_supplementary_id
                        where ers.exam_supplementary_id='$examRegId' and ers.studentID='$studentId'";
            $receiptDetails =  $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $receiptDetails;
    }
    /**
     * @param $request
     * @throws ProfessionalException
     * @author Sibin
     */
    public function assignAllInternalValuationDates($request)
    {
        $batchIds = $this->realEscapeArray($request->batchArray);
        $request->examRegId = $this->realEscapeString($request->examRegId);
        $request->examType = $this->realEscapeString($request->examType);
        $dates = (object) $this->realEscapeObject($request->dates);
        $insertSql = [];
        $sql = null;
        $result = null;
        $batchIdString = "";
        if($request->examType){
            $deleteCondition =" AND examType = '$request->examType'";
        }
        try {
            if (!empty($batchIds)) {
                foreach ($batchIds as $batch) {
                    if($dates->secondStartDate && $dates->secondEndDate){
                        $insertSql[] = "(\"$request->examRegId\", \"$batch\", \"$dates->firstStartDate\", \"$dates->firstEndDate\", \"$dates->secondStartDate\", \"$dates->secondEndDate\",\"$request->examType\")";
                    }else{
                        $insertSql[] = "(\"$request->examRegId\", \"$batch\", \"$dates->firstStartDate\", \"$dates->firstEndDate\",\"$request->examType\")";
                    }
                }
                $insertSql = implode(",", $insertSql);
                $batchIdString = implode(",",
                    $batchIds
                );
                $deleteSql = "DELETE from valuationdates where examregID = '$request->examRegId' and batchID in ($batchIdString$deleteCondition";
                $this->executeQueryForObject($deleteSql);
                 if($dates->secondStartDate && $dates->secondEndDate){
                    $sql = "INSERT into valuationdates(examregID, batchID, firstval_Datestart, firstval_Dateend, secondval_Datestart, secondval_Dateend,examType) values " . $insertSql;
                 }else{
                    $sql = "INSERT into valuationdates(examregID, batchID, firstval_Datestart, firstval_Dateend,examType) values " . $insertSql;
                 }
                $this->executeQueryForObject($sql);
                $result = true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * Get Student Details By falseNo
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamDatesByExamRegistration($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $examDates = null;
        $sql = null;
        try {
            $sql = "SELECT distinct examDate as id ,DATE_FORMAT(examDate,'%d-%m-%Y') AS name,batchID as batchId from exam where examregID ='$examRegId'
            group by examDate";
            $examDates =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDates;
    }
    /**
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamStudentAttendanceCount($exam)
    {
        $exam = $this->realEscapeObject($exam);
        $count = null;
        $sql = null;
        try {
            if ($exam->internalExternalStaffSame) {
                if($exam->examType == ExamType::SUPPLY){
                    $sql = "SELECT count(distinct erss.studentID) as studentCount FROM exam e
                            INNER JOIN exam_supplementary_student_subjects erss ON erss.examID = e.examID
                            INNER JOIN exam_supplementary_student_details ersd ON ersd.exam_supplementary_id = erss.exam_supplementary_id AND ersd.studentID = erss.studentID
                            WHERE erss.exam_supplementary_id IN ($exam->examRegId)  AND e.batchID IN ($exam->batchId) AND e.subjectID IN ($exam->subjectId) AND e.examregID IS NOT NULL AND ersd.paid=1";
                }else{
                    $sql = "SELECT count(distinct ers.studentID) as studentCount from exam_registration_batches erb
                            INNER JOIN exam_reg_studentchallan ers on ers.examregID = erb.examregID
                            INNER JOIN exam_reg_studentsubject ersb ON ersb.examregID=erb.examregID and ersb.studentID = ers.studentID
                            INNER JOIN exam e on e.examregID =erb.examregID AND e.subjectID = ersb.subjectID and e.batchID=erb.batchID
                            INNER JOIN studentaccount sa ON sa.studentID = ers.studentID AND sa.batchID=erb.batchID
                                WHERE erb.examregID='$exam->examRegId' and erb.batchID='$exam->batchId' and ersb.subjectID='$exam->subjectId' and ers.paid=1";
                }
            }
            else{
                $sql = "SELECT count(studentID) as studentCount from exam_attendance where examID='$exam->examId' and isAbsent= 0 ";
            }
            $count =  $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $count;
    }
    /**
     * @author Sibin
     * get Exams By ExamRegistration,Sem
     */
    public function getExamsByExamRegistrationRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        $groupBy ="";
        $examRegField = ($request->examType == ExamType::SUPPLY) ? "supply_examreg_id" : "examregID";
        if (!$request->includeAllExams) {
            $whereConditions .= " AND e.examID not in (select exam_id from assignstaff_exam_group_relation)";
        }
        if ($request->examRegId) {
            $whereConditions .= " AND e.$examRegField IN ($request->examRegId)";
        }
        if ($request->semId) {
            $whereConditions .= " AND e.semID IN ($request->semId)";
        }
        if ($request->batchId) {
            $whereConditions .= " AND e.batchID IN ($request->batchId)";
        }
        if ($request->examDate) {
            $whereConditions .= " AND e.examDate IN ('$request->examDate')";
        }
        if ($request->subjectId) {
            $whereConditions .= " AND e.subjectID IN ($request->subjectId)";
        }
        if ($request->examDateDMY) {
            $whereConditions .= "AND DATE_FORMAT(e.examDate, \"%d-%m-%Y\") = '$request->examDateDMY'";
        }
        if ($request->getGroupedBySubject) {
            $groupBy = " GROUP BY e.subjectID";
        }
        $invalidDate = "0000-00-00";
        $sql = "SELECT 
                    e.batchID as 'batchId',
                    b.batchName,
                    b.batchDesc,
                    e.semID as 'semId',
                    e.examID AS examId,
                    e.examName AS examName,
                    e.subjectID as 'subjectId',
                    s.subjectName,
                    s.subjectDesc,
                    e.examTotalMarks,
                    e.examTypeID as examTypeId,
                    e.examStartTime as startTime,
                    e.examEndTime as endTime,
                    IF(e.examDate NOT IN ('$invalidDate'), DATE_FORMAT(e.examDate, \"%d-%m-%Y\"), '-') AS examDate
                FROM
                    exam e
                    INNER JOIN batches b ON b.batchID = e.batchID
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                WHERE
                    1 = 1
                    $whereConditions
                    $groupBy";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamValuationStaffs($examId,$valuationCount = NULL,$valuationType = NULL)
    {
        $examId = $this->realEscapeString($examId);
        $valuationCount = $this->realEscapeString($valuationCount);
        $staffIds = null;
        $sql = null;
        $condtions = $valuationType ? "AND valuationType ='$valuationType":" AND valuationType is null";
        try {
            if($valuationCount == 2 || $valuationCount == 3){
                $sql = "SELECT  examID,staffIDs from externalexam_valuation_staffs where examID='$examId' and valuationCount='$valuationCount$condtions";
            }else{
                $sql = "SELECT  examID,staffIDs from exam_valuation_staffs where examID='$examId$condtions";
            }
            $staffIds =  $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $staffIds;
    }
    /**
     * @author Sibin
     * get exam reg students by batch and subjectid
     */
    public function getExamRegisteredStudentsDetailsForValuationByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $thirdValStudentsCondition = $thirdValStudentStaffCondition = "";
        $filterStudentsByValuer  = "";
        $excludeAlreadyAssignedStudents = " AND ers.studentID NOT IN (select studentID from examValuationStaffAssignedStudents where examRegId ='$request->examRegId' and subjectId='$request->subjectId' and valuationCount='$request->valuationCount' and staffId NOT IN('$request->staffId') AND examType = '$request->examType') ";
        if($request->includeAlreadyAssignedStudents){
            $excludeAlreadyAssignedStudents = "";
        }
        if($request->valuerSelected && $request->filterByValuerStaff){
            $filterStudentsByValuer = " AND ers.studentID IN (select studentID from examValuationStaffAssignedStudents where examRegId ='$request->examRegId' and subjectId='$request->subjectId' and valuationCount='1' and staffId IN('$request->valuerSelected') AND examType = '$request->examType') ";
        }
        if($request->valuationCount == 3){
            $thirdValStudentsCondition = " INNER JOIN externalexam_thirdvalstudents eth ON eth.examID = e.examID AND eth.studentID = ers.studentID ";
            $thirdValStudentStaffCondition = "AND ers.studentID NOT IN (select studentID from examValuationStaffAssignedStudents where examRegId ='$request->examRegId' and subjectId='$request->subjectId'
                        and valuationCount NOT IN ($request->valuationCount) and staffId IN('$request->staffId') and examType ='$request->examType' )";
        }
        $falseNoCondition = "";
        $falseNoField = "";
        if($request->getFalseNoStudentsOnly){
            $falseNoCondition = " INNER JOIN examcontroller_false_number efn ON efn.examID = e.examID AND efn.studentID = sa.studentID ";
            $falseNoField = " , efn.false_number as falseNumber ";
        }
        if($request->examType == ExamType::SUPPLY){
            $sql = "SELECT e.examID,e.batchID,e.subjectID,erss.studentID,sa.regNo,sa.studentName,esas.staffId as staffAssigned  $falseNoField FROM exam ex
                    INNER JOIN exam_supplementary_student_subjects erss ON erss.examID = ex.examID
                    INNER JOIN exam_supplementary_student_details ers ON ers.exam_supplementary_id = erss.exam_supplementary_id AND ers.studentID = erss.studentID
                    INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                    INNER JOIN exam e ON e.supply_examreg_id = erss.exam_supplementary_id AND e.batchID = ex.batchID AND e.subjectID = ex.subjectID
                    $falseNoCondition 
                    $thirdValStudentsCondition
                    LEFT JOIN examValuationStaffAssignedStudents esas ON esas.examRegId = erss.exam_supplementary_id AND esas.subjectId = e.subjectID AND esas.studentId = erss.studentID AND esas.examType = '$request->examType'
                    AND esas.staffId = '$request->staffId' AND esas.valuationCount='$request->valuationCount'
                    WHERE erss.exam_supplementary_id IN ($request->examRegId)  AND ex.batchID IN ($request->batchId) AND ex.subjectID IN ($request->subjectId) AND ex.examregID IS NOT NULL AND ers.paid=1
                    $excludeAlreadyAssignedStudents
                    $thirdValStudentStaffCondition
                    $filterStudentsByValuer
                    order by sa.regNo";
        }else{
            $sql = "SELECT e.examID,erb.batchID,ersb.subjectID,ers.studentID,sa.regNo,sa.studentName,esas.staffId as staffAssigned  $falseNoField from exam_registration_batches erb
                    INNER JOIN exam_reg_studentchallan ers on ers.examregID = erb.examregID 
                    INNER JOIN exam_reg_studentsubject ersb ON ersb.examregID=erb.examregID and ersb.studentID = ers.studentID
                    INNER JOIN exam e on e.examregID =erb.examregID AND e.subjectID = ersb.subjectID and e.batchID=erb.batchID
                    INNER JOIN studentaccount sa ON sa.studentID = ers.studentID AND sa.batchID=erb.batchID
                    $falseNoCondition
                    $thirdValStudentsCondition
                    LEFT JOIN examValuationStaffAssignedStudents esas ON esas.examRegId = erb.examregID AND esas.subjectId = ersb.subjectID AND esas.studentId = ers.studentID AND esas.examType = '$request->examType'
                        AND esas.staffId = '$request->staffId' AND esas.valuationCount='$request->valuationCount'
                        where erb.examregID='$request->examRegId' and erb.batchID='$request->batchId' and ersb.subjectID='$request->subjectId' and ers.paid=1
                        $excludeAlreadyAssignedStudents
                        $thirdValStudentStaffCondition
                        $filterStudentsByValuer
                        order by sa.regNo";
        }
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    /**
     * Get Student Details for exam By falseNo
     * @author Sibin
     * @param int $falseNo
     * @throws ProfessionalException
     */
    public function getStudentDetailsForRegExam($falseNo)
    {
        $falseNo = $this->realEscapeString($falseNo);
        $qry = "SELECT
                sa.regNo,
                sa.studentID,
                sa.studentName,
                er.examregID AS exID,
                er.examregName AS exName,
                e.examID,
                e.examName,
                eme.mark,
                stff.staffName,
                aseg.group_name,
                aseg.examTypeFlag,
                e.examDate,
                e.examregID,
                e.subjectID,
                e.semID,
                s.subjectName,
                s.subjectDesc
            FROM
                studentaccount sa
                    INNER JOIN
                examcontroller_false_number efn ON sa.studentID = efn.studentID
                    INNER JOIN
                exam_registration er ON er.examregID = efn.examregID
                    INNER JOIN
                exam e ON e.examID = efn.examID
                INNER JOIN subjects s ON s.subjectID = e.subjectID
                    LEFT JOIN
                exammarks_external eme ON e.examID = eme.examID
                    AND eme.studentID = efn.studentID
                    LEFT JOIN
                staffaccounts stff ON eme.staffID = stff.staffID
                    LEFT JOIN
                assignstaff_exam_group_relation aser ON e.examID = aser.exam_id
                    AND efn.examregID = aser.exam_registration_id
                    LEFT JOIN
                assignstaff_exam_groupname aseg ON aser.assignstaff_exam_groupname_id = aseg.id
            WHERE
                efn.false_number = '$falseNo'";
        try {
            $response = $this->executeQueryForList($qry);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    /**
     * Get Student Details for supply exam By falseNo
     * @author Sibin
     * @param int $falseNo
     * @throws ProfessionalException
     */
    public function getStudentDetailsForSupplementaryExam($falseNo)
    {
        $falseNo = $this->realEscapeString($falseNo);
        $qry = "SELECT
                sa.regNo,
                sa.studentID,
                sa.studentName,
                es.id AS exID,
                es.supplyDesc AS exName,
                e.examID,
                e.examName,
                eme.mark,
                stff.staffName,
                aseg.group_name,
                aseg.examTypeFlag,
                e.examDate,
                e.supply_examreg_id,
                e.subjectID,
                e.semID
            FROM
                studentaccount sa
                    INNER JOIN
                examcontroller_false_number efn ON sa.studentID = efn.studentID
                    INNER JOIN
                exam_supplementary es ON efn.exam_supplementary_id = es.id
                    INNER JOIN
                exam e ON e.examID = efn.examID
                    LEFT JOIN
                exammarks_external eme ON e.examID = eme.examID
                    AND eme.studentID = efn.studentID
                    LEFT JOIN
                staffaccounts stff ON eme.staffID = stff.staffID
                    LEFT JOIN
                assignstaff_exam_group_relation aser ON e.examID = aser.exam_id
                    AND efn.exam_supplementary_id = aser.exam_supplementary_id
                    LEFT JOIN
                assignstaff_exam_groupname aseg ON aser.assignstaff_exam_groupname_id = aseg.id
            WHERE
                efn.false_number = '$falseNo'";
        try {
            $response = $this->executeQueryForList($qry);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
    /**
     * Method to edit exam total mark by exam id
     * @param Integer examid, mark
     * @return Boolean
     */
    public function editExamTotalMarkById($examID, $mark)
    {
        $sql = "UPDATE `exam` SET `examTotalMarks`='$mark' WHERE `examID`='$examID";
        try {
            if($this->executeQuery($sql)){
                return true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return false;
    }
    /**
     * @param $hallId
     * @param $groupId
     * @return array|Object
     * @throws ProfessionalException
     */
    public function getHallAsssignedSubjectDetails($hallId, $groupId)
    {
        $hallId = $this->realEscapeString($hallId);
        $groupId = $this->realEscapeString($groupId);
        $sql = "SELECT
                    DISTINCT ehrs.examID,
                    s.subjectName,
                    s.subjectDesc
                FROM
                    exam_hall_arranged_students ehrs
                        INNER JOIN
                    exam ex on (ex.examID = ehrs.examID)
                        INNER JOIN
                    subjects s on (s.subjectID = ex.subjectID)
                WHERE
                    hallID =$hallId and groupID =$groupId";
        try {
            $response = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $response;
    }
        /**
     * @param $semId
     * @param $examYear
     * @param $courseTypeId
     * @throws ProfessionalException
     */
    public function getsupplyRegistrationBySemIddAndExamYear($semId,$examYear,$courseTypeId)
    {
        $sql = '';
        $courseTypeId = $this->realEscapeString($courseTypeId);
        $semId = $this->realEscapeString($semId);
        $examYear = $this->realEscapeString($examYear);
        $sql = "SELECT DISTINCT es.id as supplyExamId, es.supplyDesc as supplyDesc FROM exam_supplementary es inner join supply_improve_batches sib on (sib.exam_supplementary_id = es.id ) INNER JOIN batches bt on (bt.batchID = sib.batchID ) WHERE es.examYear =$examYear and es.semID =$semId and bt.courseTypeID =$courseTypeId";
        try {
            $supplyExamDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $supplyExamDetails;
    }
    /**
     * get students pass count by batch,sem
     * author sibin
     * @throws ProfessionalException
     */
    public function getStudentsSgpaPassCountByRequest($request)
    {
        $sql = "";
        $count= "";
        $request = $this->realEscapeObject($request);
        $sql = "SELECT count(distinct ersc.studentID) as totalStudents,count(sssp.studentID) as passedStudents from exam_reg_studentchallan ersc
                    INNER JOIN studentaccount sa ON sa.studentID = ersc.studentID
                    LEFT JOIN student_semwise_sgpa sss ON sss.studentID = ersc.studentID AND sss.batchID = sa.batchID AND sss.semID='$request->semId'
                    LEFT JOIN student_semwise_sgpa sssp ON sssp.studentID = ersc.studentID AND sssp.batchID = sa.batchID AND sssp.semID='$request->semId' AND sssp.sgpa !='0.00'
                    WHERE ersc.examregID='$request->examRegId' AND sa.batchID = '$request->batchId'   AND ersc.paid = 1";
        try {
            $count = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $count;
    }
    /**
     * save ExamQpCodes by sem,examregistration,subjectid,qpcode
     * author sibin
     * @throws ProfessionalException
     */
    public function saveExamQpCodes($request)
    {
        $request = $this->realEscapeObject($request);
        if($request->isSupply){
            $request->supplyRegId = $request->supplyRegId ? $request->supplyRegId : $request->examRegId;
            $sql = "INSERT INTO  examQpCodes(supplyRegId,semId,subjectId,qpCode,created_by) values('$request->supplyRegId','$request->semId','$request->subjectId','$request->qpCode','$request->staffId')
                    ON DUPLICATE KEY UPDATE
                                    qpCode = VALUES(qpCode),
                                    updated_by = VALUES(created_by)";
        }else{
            $sql = "INSERT INTO  examQpCodes(examRegId,semId,subjectId,qpCode,created_by) values('$request->examRegId','$request->semId','$request->subjectId','$request->qpCode','$request->staffId')
                    ON DUPLICATE KEY UPDATE
                                    qpCode = VALUES(qpCode),
                                    updated_by = VALUES(created_by)";
        }
        try {
            $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * get  ExamQpCodes by sem,examregistration,subjectid
     * author sibin
     * @throws ProfessionalException
     */
    public function getExamQpCodes($request)
    {
        $request = $this->realEscapeObject($request);
        $qpCode = null;
        if($request->isSupply){
            $request->supplyRegId = $request->supplyRegId ? $request->supplyRegId : $request->examRegId;
            $sql = "SELECT qpCode from examQpCodes WHERE supplyRegId='$request->supplyRegId' AND semId ='$request->semId' AND subjectId='$request->subjectId'";
        }else{
            $sql = "SELECT qpCode from examQpCodes WHERE examRegId='$request->examRegId' AND semId ='$request->semId' AND subjectId='$request->subjectId'";
        }
        try {
            $qpCode = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $qpCode;
    }
        /**
     * get Exams By ExamRegistration
     */
    public function getExamsByExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        if ( $request->examType === ExamType::REGULAR ) {
            $whereConditions = " AND e.examRegId = '$request->examRegId";
        }
        else if ( $request->examType === ExamType::SUPPLY ) {
            $whereConditions = " AND e.supply_examreg_id = '$request->examRegId";
        }
        if ($request->semId) {
            $whereConditions .= " AND e.semID IN ($request->semId)";
        }
        if ($request->batchId) {
            $whereConditions .= " AND e.batchID IN ($request->batchId)";
        }
        if ($request->subjectId) {
            $whereConditions .= " AND e.subjectID IN ($request->subjectId)";
        }
        if ($request->groupBy) {
            $whereConditions .= " GROUP BY e.subjectID";
        }
        $sql = "SELECT
                    e.batchID as 'batchId',
                    b.batchName,
                    b.batchDesc,
                    e.semID as 'semId',
                    e.examID AS examId,
                    e.examName AS examName,
                    e.subjectID as 'subjectId',
                    s.subjectName,
                    s.subjectDesc,
                    e.examDate
                FROM
                    exam e
                    INNER JOIN batches b ON b.batchID = e.batchID
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                WHERE
                    1 = 1
                    $whereConditions";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
     * get exam registered student details by regId and  sujectId
     */
    public function getExamRegisteredStudentDetails($isSupply,$examRegId,$subjectId)
    {
        $isSupply = $this->realEscapeString($isSupply);
        $examRegId = $this->realEscapeString($examRegId);
        $subjectId = $this->realEscapeString($subjectId);
        $studentDetails = [];
        if (!$isSupply) {
            $sql = "SELECT DISTINCT sa.studentID as studentId,sa.regNo,sa.studentName,sa.batchID,e.examID, e.semId FROM studentaccount sa 
                        INNER JOIN exam_reg_studentsubject erss ON (sa.studentID = erss.studentID) 
                        INNER JOIN exam e ON (e.examregID = erss.examregID AND e.subjectID = erss.subjectID) 
                        LEFT JOIN failed_students fs ON fs.studentID = erss.studentID AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                        INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = sa.studentID AND ersc.examregID ='$examRegId'
                        WHERE erss.examregID = '$examRegId' AND e.subjectID='$subjectId' AND ersc.paid=1 AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID) order by sa.regNo";
        } else  {
            $sql = "SELECT DISTINCT sa.studentID as studentId,sa.regNo,sa.studentName,sa.batchID,es.examID, es.semId
            FROM studentaccount sa 
                        INNER JOIN exam_supplementary_student_subjects esss ON (sa.studentID = esss.studentID) 
                        INNER JOIN exam e ON (e.examID = esss.examID) 
                        LEFT JOIN failed_students fs ON fs.studentID = esss.studentID AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                        INNER JOIN exam es ON (e.subjectID = es.subjectID AND es.supply_examreg_id = esss.exam_supplementary_id AND es.batchID = e.batchID)
                        INNER JOIN exam_supplementary_student_details essd ON essd.studentID = sa.studentID AND essd.exam_supplementary_id ='$examRegId'
                        WHERE esss.exam_supplementary_id = '$examRegId' AND es.subjectID='$subjectId' AND essd.paid=1 AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID) order by sa.regNo";
        }
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
     /**
     * getAttendance details
     * @param $examId
     * @param $studentId
     * @throws ProfessionalException
     */
    public function getExamAttendance($examId, $studentId)
    {
        $examId = $this->realEscapeString($examId);
        $sql = "SELECT isAbsent FROM exam_attendance WHERE studentId = $studentId AND examID = $examId";
        try {
            return $this->executeQueryForObject($sql)->isAbsent;
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
      /**
     * insert exam attendance
     * @param $examId
     * @param $studentId
     * @throws ProfessionalException
     */
    public function insertStudentAttendanceInExam($studentId,$examId,$isAbsent){
        $studentId = $this->realEscapeString($studentId);
        $examId = $this->realEscapeString($examId);
        $isAbsent = $this->realEscapeString($isAbsent);
        $sql_insert = "INSERT INTO exam_attendance (examID, studentID, isAbsent) VALUES (".$examId.", ".$studentId.", ".$isAbsent.") ON DUPLICATE KEY UPDATE isAbsent = VALUES(isAbsent)";
        try {
            return $this->executeQuery($sql_insert);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $request
     * @throws ProfessionalException
     *update exam external marks by student
     */
    public function saveExamMarkMigration($request)
    {
        $request = $this->realEscapeObject($request);
        $sql="";
            if($request->courseType == CourseTypeConstants::UG ){
                $sql = "INSERT INTO exammarks_external (examID, studentID,mark,staffID,false_number)
                            VALUES('$request->examId','$request->studentId','$request->mark','$request->staffId','$request->falseNo')
                            ON DUPLICATE KEY UPDATE
                            mark = VALUES(mark),
                            staffID = VALUES(staffID),
                            false_number = VALUES(false_number)";
            }
            if($request->courseType == CourseTypeConstants::PG || $request->courseType == CourseTypeConstants::PGD ){
                $sql = "INSERT INTO externalexammarks_finalized (examID,studentID,mark)
                            VALUES('$request->examId','$request->studentId','$request->mark')
                                ON DUPLICATE KEY UPDATE
                                mark = VALUES(mark)";
            }
        try {
                $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get Exam MarkEntry For ExamRegistration
     * @param $request
     * @throws ProfessionalException
     */
    public function getExamMarkEntryForExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $examIdsSql="";
        $exams=[];
        if($request->isSupply == 1){
            $examIdsSql = " SELECT examID from exam where supply_examreg_id = '$request->examRegId'";
        }
        else if($request->isSupply == 2){
            $examIdsSql = " SELECT examID from exam where examregID  = '$request->examRegId' OR supply_examreg_id = '$request->examRegId'";
        }
        else{
            $examIdsSql = " SELECT examID from exam where examregID  = '$request->examRegId";
        }
        $sql = "SELECT distinct examID from exammarks_external where examID in ($examIdsSql)";
        $sqlPg = "SELECT distinct examID from externalexammarks_finalized where examID in ($examIdsSql)";
        try {
            $exams =  $this->executeQueryForList($sql);
            if($request->isPg){
                $examsPg =  $this->executeQueryForList($sqlPg);
            }
            if($exams){
                $exams = array_merge($exams,$examsPg);
            }else{
                $exams = $examsPg;
            }
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
    /**
     * get Exam MarkEntry For ExamRegistration
     * @param $request
     * @throws ProfessionalException
     */
    public function getExamsDetailsByExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $examIdsSql = "";
        $exams = [];
        $whereConditions = "";
        if ($request->isSupply == 1) {
            $whereConditions = " e.supply_examreg_id = '$request->examSupplyRegId'";
            $examRegTables = "INNER JOIN exam_supplementary es ON es.id = e.supply_examreg_id";
        } else if ($request->isSupply == 2) {
            $whereConditions = " e.examregID  = '$request->examRegId'";
            $examRegTables = "INNER JOIN exam_registration es ON es.examregID = e.examregID";
        } else {
            $whereConditions = " e.examregID  = '$request->examRegId";
            $examRegTables = "INNER JOIN exam_registration es ON es.examregID = e.examregID";
        }
        $sql = "SELECT
                    e.examID,
                    e.batchID as 'batchId',
                    b.batchName,
                    b.batchDesc,
                    d.deptID,
                    d.departmentDesc,
                    d.departmentSpecialization,
                    e.semID as 'semId',
                    e.examID AS examId,
                    e.examName AS examName,
                    e.subjectID as 'subjectId',
                    s.subjectName,
                    s.subjectDesc,
                    s.subjectPriority as slot,
                    es.examYear,
                    RIGHT(es.examYear, 2) as yearFormat,
                    e.examregID as examRegId,
                    e.supply_examreg_id as supplyRegId,
                    ex.examID as regularExamId,
                    b.batchStartYear,
                    sem.orderNo as semOrderNo,
                    s.isTheory
                FROM
                    exam e
                    INNER JOIN batches b ON b.batchID = e.batchID
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                    INNER JOIN department d ON d.deptID = b.deptID
                    INNER JOIN exam ex ON ex.batchID = e.batchID AND ex.subjectID = e.subjectID AND ex.semID = e.semID AND ex.examregID IS NOT NULL
                    INNER JOIN semesters sem ON sem.semID = e.semID";
           $sqlA =  " $examRegTables
                    WHERE
                    1 = 1 AND
                    $whereConditions";
        try {
            $sqlForExamReg = $sql.$sqlA;
            $exams =  $this->executeQueryForList($sqlForExamReg);
            //for both regular and supply
            if($request->isSupply == 2){
            $sqlB =  " INNER JOIN exam_supplementary es ON es.id = e.supply_examreg_id
                        WHERE
                        1 = 1 AND
                        e.supply_examreg_id = '$request->examSupplyRegId'";
                $sqlForBoth = $sql . $sqlB;
                $exams =  array_merge($exams, $this->executeQueryForList($sqlForBoth));
            }
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
    /**
     * get Students For Exam By Exam Details
     * @param $request
     * @throws ProfessionalException
     */
    public function getStudentsForExamByExamDetails($request)
    {
        $request = $this->realEscapeObject($request);
        $studentList = [];
        $condition="";
        if($request->paid){
            $condition .=" AND ersc.paid IN (1)";
        }
        if($request->examRegId){
            if ($request->excludeStudentsWithCourseMode) {
                $condition .= "  AND (ersc.courseMode != '$request->excludeStudentsWithCourseMode' || ersc.courseMode is null)";
            }
            $sql ="SELECT distinct esss.studentID,e.examID from exam_reg_studentsubject esss 
                    INNER JOIN studentaccount sa ON sa.studentID = esss.studentID 
                    INNER JOIN exam e ON e.subjectID = esss.subjectID AND e.batchID = sa.batchID AND e.examregID = esss.examregID
                    INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = sa.studentID AND ersc.examregID = esss.examregID
                    WHERE esss.examregID = '$request->examRegId' AND esss.subjectID = '$request->subjectId' AND sa.batchID ='$request->batchId'
                    $condition";
        }
        else if ($request->supplyRegId){
            $sql = "SELECT distinct esss.studentID,essd.isSupply from exam_supplementary_student_subjects esss
                    INNER JOIN exam_supplementary_student_details essd ON essd.exam_supplementary_id = esss.exam_supplementary_id AND essd.studentID = esss.studentID
                    INNER JOIN studentaccount sa ON sa.studentID = esss.studentID
                    INNER JOIN exam_supplementary_student_details ersc ON ersc.studentID = sa.studentID AND ersc.exam_supplementary_id = esss.exam_supplementary_id
                    WHERE esss.exam_supplementary_id = '$request->supplyRegId' AND esss.examID = '$request->regularExamId' AND sa.batchID ='$request->batchId'
                    $condition";
        }
        try {
            $studentList =  $this->executeQueryForList($sql);
        } catch (Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentList;
    }
    /**
     * @param $batchid,examregId,isSupply
     * @throws ProfessionalException
     */
    public function getResultPublishDate($batchId, $examRegId,$isSupply)
    {
        $batchId = $this->realEscapeString($batchId);
        $examRegId = $this->realEscapeString($examRegId);
        $isSupply = $this->realEscapeString($isSupply);
        $sql = "";
        if ($isSupply) {
            $sql = "SELECT resultPublishDate from trDates WHERE batchId = '$batchId' AND supplyExamRegId = ' $examRegId'";
        }else{
            $sql = "SELECT resultPublishDate from trDates WHERE batchId = '$batchId' AND examRegId = ' $examRegId'";
        }
        try {
            $resultpublishDate = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $resultpublishDate;
    }
    /**
     * @author Sibin
     */
    public function getExamRegisteredStudentsWithHeldStatus($request)
    {
        $request = $this->realEscapeObject($request);
        $studentDetails = [];
        if ($request->examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT DISTINCT sa.studentID as id,sa.regNo,sa.studentName,sa.batchID as batchId,esw.withheld,esw.reason FROM studentaccount sa
                        INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = sa.studentID
                        LEFT JOIN exam_students_withheld esw ON esw.studentID = ersc.studentID AND esw.examregID = ersc.examregID
                        WHERE ersc.examregID = '$request->examRegId' AND sa.batchID= '$request->batchId' AND ersc.paid=1  order by sa.regNo;";
        }
        try {
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
    /**
     * Method for getting student cgpa
     * @input $batchId
     */
    public function getFinalCgpa($batchId)
    {
        $batchId = $this->realEscapeString($batchId);
        $sql = '';
        $finalCgpa = null;
        try {
            $sql = "SELECT DISTINCT studentID, cgpa , overallgrade AS grade FROM student_final_cgpa_credits  WHERE batchID = $batchId";
            $finalCgpa = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $finalCgpa;
    }
    /**
     * Method for getting student cgpa
     * @input $batchId
     */
    public function getFinalCgpaStudentWise($studentId)
    {
        $studentId = $this->realEscapeString($studentId);
        
        $sql = '';
        
        $finalCgpa = null;
        
        try {
            $sql = "SELECT cgpa AS studentCGPA FROM student_final_cgpa_credits  WHERE studentID = $studentId";
            
            $finalCgpa = $this->executeQueryForObject($sql)->studentCGPA;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        
        return $finalCgpa;
    }
    /**
     * @author Sibin
     */
    public function getRegularExamSubjectListByBatch($examRegId, $batchId)
    {
        $examRegId = (int)$this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $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 ($batchId) AND e.examregID = '$examRegId' ORDER BY s.subjectName ASC";
        try {
            $subjectDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectDetails;
    }
    /*
     * Get all exam types
     * @return ARRAY $batch_exam_types
     */
    public function getAllExamTypes($request)
    {
        $request = $this->realEscapeObject($request);
        try {
            $sql = "SELECT typeID AS id, typeName AS name, typeDesc AS description
            FROM exam_type et
            INNER JOIN exam e ON e.examTypeID = et.typeID
            WHERE e.batchID = '$request->batchId' AND e.semID = '$request->semId'
            GROUP BY et.typeID;";
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTypes;
    }
    public function getStudentRanksForProgressReports($request){
        $request = $this->realEscapeObject($request);
        $where = [];
        try {
            $request->subjectId ? $where [] = " sm.subjectID = '$request->subjectId" : null;
            if($request->excludeSubjectCategoryIds && count($request->excludeSubjectCategoryIds))
            {
                $where [] = " s.subjectcatID NOT IN (".implode(',',$request->excludeSubjectCategoryIds).") ";
            }
            if($request->weightedAvg)
            {
                if($request->rank)
                {
                    $sql = "SELECT DISTINCT(sm.studentID) AS stid, SUM(sm.percentage)/count(e.examID) AS fieldname
                        FROM student_marks sm
                        INNER JOIN exam e ON e.examID = sm.examID
                        INNER JOIN subjects s ON e.subjectID = s.subjectID
                        WHERE sm.semID='$request->semID'
                            AND sm.batchID='$request->batchId'
                            AND sm.examTypeID= '$request->examTypeId'
                            ".($where?" AND ".implode(' AND ',$where):"")."
                            AND sm.studentID NOT IN (
                                SELECT studentID
                                from student_marks sm
                                WHERE examTypeID = '$request->examTypeId'
                                    AND percentage < '$request->passPercent'
                                    AND batchID='$request->batchId'
                                    AND semID='$request->semID'
                            ) GROUP BY sm.studentID ORDER BY fieldname DESC ;";
                }
                else
                {
                    $sql = "SELECT DISTINCT(sm.studentID) AS stid, SUM(sm.percentage)/count(e.examID) AS fieldname
                        FROM student_marks sm
                        INNER JOIN exam e on e.examID = sm.examID
                        INNER JOIN subjects s ON e.subjectID = s.subjectID
                        WHERE sm.semID='$request->semId'
                            AND sm.batchID='$request->batchId'
                            AND sm.examTypeID='$request->examTypeId'
                            ".($where?" AND ".implode(' AND ',$where):"")."
                        GROUP BY sm.studentID ORDER BY fieldname DESC;";
                }
            }
            else
            {
                if($request->rank)
                {
                    $sql = "SELECT DISTINCT(sm.studentID) AS stid,(SUM(IF(sm.marksObtained != '-.001' AND sm.marksObtained !='-1',sm.marksObtained,0))/SUM(e.examTotalMarks))*100 AS fieldname  FROM student_marks sm
                    INNER JOIN exam e ON e.examID = sm.examID
                    INNER JOIN subjects s ON e.subjectID = s.subjectID
                    WHERE sm.semID='$request->semId'
                        AND sm.batchID='$request->batchId'
                        AND sm.examTypeID='$request->examTypeId'
                        ".($where?" AND ".implode(' AND ',$where):"")."
                        AND sm.studentID NOT IN (
                            SELECT studentID FROM student_marks
                            WHERE examTypeID = '$request->examTypeId'
                                AND percentage < '$request->passPercent'
                                AND batchID = '$request->batchId'
                                AND semID = '$request->semId'
                        ) GROUP BY sm.studentID ORDER BY fieldname DESC;";
                }
                else
                {
                    $sql = "SELECT DISTINCT(sm.studentID) AS stid, (SUM(if(sm.marksObtained != '-.001' AND sm.marksObtained !='-1',sm.marksObtained,0))/SUM(e.examTotalMarks))*100 AS fieldname
                    FROM student_marks sm
                    INNER JOIN exam e ON e.examID = sm.examID
                    INNER JOIN subjects s ON e.subjectID = s.subjectID
                    WHERE sm.semID='$request->semId'
                        AND sm.batchID='$request->batchId'
                        AND sm.examTypeID='$request->examTypeId'
                        ".($where?" AND ".implode(' AND ',$where):"")."
                        GROUP BY sm.studentID ORDER BY fieldname DESC";
                }
            }
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTypes;
    }
    /*
     * get nominal roll remarks
     * @param $request
     */
    public function getNominalRollRemarks($request)
    {
        $request = $this->realEscapeObject($request);
        $subjectDetails = null;
        if($request->examregID){
            $sql = "SELECT remarks from nominal_roll_remarks WHERE examregID = $request->examregID and  batchID = $request->batchID and semID = $request->semID and studentID = $request->studentID";
        }
        elseif($request->supplyregID){
            $sql = "SELECT remarks from nominal_roll_remarks WHERE supplyregID = $request->supplyregID and  batchID = $request->batchID and semID = $request->semID and studentID = $request->studentID";
        }
        try {
             return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getPseudoSubjectExamTypeList($pseudoSubjectId){
        $pseudoSubjectId = $this->realEscapeObject($pseudoSubjectId);
        try {
            $sql = "SELECT et.typeID,et.typeName,e.examTotalMarks FROM sbs_relation sbs
            INNER JOIN pseudosubjects_sbs psbs ON psbs.sbsID = sbs.sbsID
            INNER JOIN exam e ON e.subjectID = sbs.subjectID AND sbs.batchID = e.batchID AND e.semID = sbs.semID
            INNER JOIN exam_type et ON et.typeID = e.examTypeID
            WHERE psbs.pseudosubjectID = '$pseudoSubjectId'
            GROUP BY et.typeID;";
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTypes;
    }
    /*
     * save nominal roll remarks
     * @param $request
     */
    public function saveNominalRollRemarks($request)
    {
        $request = $this->realEscapeObject($request);
        $subjectDetails = null;
        if($request->examregID){
            $remarks = $this->getNominalRollRemarks($request);
            if($remarks){
                $sql = "UPDATE nominal_roll_remarks set remarks = '$request->remarks' WHERE examregID = $request->examregID and  batchID = $request->batchID and semID = $request->semID and studentID = $request->studentID";
            }
            else{
                $sql = "INSERT INTO nominal_roll_remarks(examregID, batchID, semID, studentID, remarks) VALUES($request->examregID$request->batchID$request->semID$request->studentID, '$request->remarks') ON DUPLICATE KEY UPDATE remarks = VALUES(remarks)";
            }
        }
        elseif($request->supplyregID){
            $remarks = $this->getNominalRollRemarks($request);
            if($remarks){
                $sql = "UPDATE nominal_roll_remarks set remarks = '$request->remarks' WHERE supplyregID = $request->supplyregID and  batchID = $request->batchID and semID = $request->semID and studentID = $request->studentID";
            }
            else{
                $sql = "INSERT INTO nominal_roll_remarks(supplyregID, batchID, semID, studentID, remarks) VALUES($request->supplyregID$request->batchID$request->semID$request->studentID, '$request->remarks')";
            }
        }
        try {
             $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @author Sibin
     * get Exams Subjects By ExamRegistration
     */
    public function getDistinctExamSubjectsByExamRegistrationRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        $examRegField = ($request->examType == ExamType::SUPPLY) ? "supply_examreg_id" : "examregID";
        if ($request->examRegId) {
            $whereConditions .= " AND e.$examRegField IN ($request->examRegId)";
        }
        if ($request->semId) {
            $whereConditions .= " AND e.semID IN ($request->semId)";
        }
        if ($request->batchId) {
            $whereConditions .= " AND e.batchID IN ($request->batchId)";
        }
        if ($request->examDate) {
            $whereConditions .= " AND e.examDate IN ('$request->examDate')";
        }
        $sql = "SELECT distinct
                    e.subjectID as 'subjectId',
                    s.subjectName,
                    s.subjectDesc,
                    e.semID as 'semId',
                    s.syllabusName,
                    e.examTotalMarks,
                    e.valuationMaxMark
                FROM
                    exam e
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                WHERE
                    1 = 1
                    $whereConditions";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
     * @author Sibin
     * get oe exam reg students by examregid and subjectid
     */
    public function getExamRegisteredStudentsDetailsBySubject($request)
    {
        $request = $this->realEscapeObject($request);
        //new digital valuation properties
        $digitalValuationProperties = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_CONTROLLER, SettingsConstents::DIGITAL_VALUATION_PROPERTIES);
        $digitalValuationProperties = $digitalValuationProperties ? json_decode($digitalValuationProperties) : "";
        if($digitalValuationProperties->isReviewerEnabled && !$request->isPg){
            return $this->getExamRegisteredStudentsDetailsBySubjectForReviewer($request);
        }
        $condition = "";
        if ($request->studentId && $request->getSingleStudent) {
            $condition = " AND sa.studentID IN ($request->studentId";
        }
        $examRegField = ($request->examType == ExamType::SUPPLY) ? "exam_supplementary_id" : "examregID";
        $falseNumberJoin = $request->includeStudentWithoutFalseNumber ? " LEFT JOIN " : " INNER JOIN ";
        if ($request->showStudentsByFalseNumber) {
            if ($request->getRegularExamFalseNumber) {
                $getFalseNumber = "$falseNumberJoin examcontroller_false_number efn ON efn.studentID = sa.studentID AND efn.examregID = $request->regularExamRegId AND efn.examID = ex.examID";
            } else {
                $getFalseNumber = "$falseNumberJoin examcontroller_false_number efn ON efn.studentID = sa.studentID AND efn.$examRegField = $request->examRegId AND efn.examID = e.examID";
                //$getFalseNumber = "";
            }
            $falseNoField = $getFalseNumber ? " , efn.false_number AS falseNumber" : "";
        }
        //To get marks in excontroller side mark  table
        $controllerSideMarkJoin ="";
        $controllerSideMarkField = "";
        if($request->getExamControllerMark){
             $marksTable = $request->isPg ? 'externalexammarks_finalized':'exammarks_external';
             $controllerSideMarkJoin = "LEFT JOIN $marksTable ee 
                                        ON (ee.examID = e.examID AND erss.studentID = ee.studentID)";
            $controllerSideMarkField = " ,ee.mark as controllerSideMark";
        }
        if ($request->examType == ExamType::SUPPLY) {
            $sql = "SELECT erss.studentID,sa.regNo,sa.studentName,e.examID,e.batchID,e.semID,e.subjectID,e.examTotalMarks,
                    oe.id as oeExamId,oec1.exam_mark as mark1,oec1.is_confirmed as mark1Confirm,oec2.exam_mark as mark2,oec2.is_confirmed as mark2Confirm
                    ,oec3.exam_mark as mark3,oec3.is_confirmed as mark3Confirm ,
                    IF(oec1.valuation_count,1,0) as valuation1,IF(oec2.valuation_count,1,0) as valuation2,IF(oec3.valuation_count,1,0) as valuation3,
                    oec1.valuation_details as valuation1Details,oec2.valuation_details as valuation2Details,oec3.valuation_details as valuation3Details,oe.id as oeExamId
                    $falseNoField
                    $controllerSideMarkField
                    FROM exam ex
                    INNER JOIN exam_supplementary_student_subjects erss ON erss.examID = ex.examID
                    INNER JOIN exam_supplementary_student_details ers ON ers.exam_supplementary_id = erss.exam_supplementary_id AND ers.studentID = erss.studentID
                    INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                    INNER JOIN exam e ON e.supply_examreg_id = erss.exam_supplementary_id AND e.batchID = ex.batchID AND e.subjectID = ex.subjectID
                    INNER JOIN oe_exams oe ON JSON_UNQUOTE(JSON_EXTRACT(oe.identifying_context, '$.examId')) = e.examID AND (oe.properties ->> '$.isMockExam' != 'true' OR oe.properties ->> '$.isMockExam' is null) AND oe.is_archived = 0
                    LEFT JOIN oe_exam_marks_confirm oec1 ON oec1.oe_exams_id = oe.id AND oec1.oe_users_id = erss.studentID AND oec1.valuation_count = 1 AND (oec1.revaluation_id IS NULL OR oec1.revaluation_id = '' )
                    LEFT JOIN oe_exam_marks_confirm oec2 ON oec2.oe_exams_id = oe.id AND oec2.oe_users_id = erss.studentID AND oec2.valuation_count = 2 AND (oec2.revaluation_id IS NULL OR oec2.revaluation_id = '' )
                    LEFT JOIN oe_exam_marks_confirm oec3 ON oec3.oe_exams_id = oe.id AND oec3.oe_users_id = erss.studentID AND oec3.valuation_count = 3 AND (oec3.revaluation_id IS NULL OR oec3.revaluation_id = '' )
                    $getFalseNumber
                    $controllerSideMarkJoin
                    WHERE erss.exam_supplementary_id IN ($request->examRegId)  AND ex.subjectID IN ($request->subjectId) AND ex.examregID IS NOT NULL AND ers.paid=1 AND oe.is_deleted = 0
                    $condition
                    group by sa.studentID order by sa.regNo";
        } else {
            $sql = "SELECT distinct erss.studentID,sa.regNo,sa.studentName,e.examID,e.batchID,e.semID,e.subjectID,e.examTotalMarks,
                oe.id as oeExamId,oec1.exam_mark as mark1,oec1.is_confirmed as mark1Confirm,oec2.exam_mark as mark2,oec2.is_confirmed as mark2Confirm
                ,oec3.exam_mark as mark3,oec3.is_confirmed as mark3Confirm,
                IF(oec1.valuation_count,1,0) as valuation1,IF(oec2.valuation_count,1,0) as valuation2,IF(oec3.valuation_count,1,0) as valuation3,
                oec1.valuation_details as valuation1Details,oec2.valuation_details as valuation2Details,oec3.valuation_details as valuation3Details,oe.id as oeExamId
                $falseNoField
                $controllerSideMarkField
                FROM exam_reg_studentsubject erss
                INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = erss.studentID AND ersc.examregID = erss.examregID
                INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                INNER JOIN exam_registration_batches erb ON erb.examregID = erss.examregID AND erb.batchID = sa.batchID
                INNER JOIN exam e ON e.examregID = erss.examregID AND e.subjectID = erss.subjectID AND e.batchID = sa.batchID AND e.semID = erb.semID
                INNER JOIN oe_exams oe ON JSON_UNQUOTE(JSON_EXTRACT(oe.identifying_context, '$.examId')) = e.examID AND (oe.properties ->> '$.isMockExam' != 'true' OR oe.properties ->> '$.isMockExam' is null) AND oe.is_archived = 0
                LEFT JOIN oe_exam_marks_confirm oec1 ON oec1.oe_exams_id = oe.id AND oec1.oe_users_id = erss.studentID AND oec1.valuation_count = 1 AND (oec1.revaluation_id IS NULL OR oec1.revaluation_id = '' )
                LEFT JOIN oe_exam_marks_confirm oec2 ON oec2.oe_exams_id = oe.id AND oec2.oe_users_id = erss.studentID AND oec2.valuation_count = 2 AND (oec2.revaluation_id IS NULL OR oec2.revaluation_id = '' )
                LEFT JOIN oe_exam_marks_confirm oec3 ON oec3.oe_exams_id = oe.id AND oec3.oe_users_id = erss.studentID AND oec3.valuation_count = 3 AND (oec3.revaluation_id IS NULL OR oec3.revaluation_id = '' )
                $getFalseNumber
                $controllerSideMarkJoin
                WHERE erss.examregID = '$request->examRegId' AND erss.subjectID = '$request->subjectId' AND ersc.paid=1 AND oe.is_deleted = 0 
                $condition
                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;
    }
    /**
     * @author Sibin
     * get exam reg students with valuation marks by examregid and subjectid
     */
    public function getExamRegisteredUgStudentsWithMarksBySubject($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_reg_studentsubject erss
                INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = erss.studentID AND ersc.examregID = erss.examregID
                INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                INNER JOIN exam_registration_batches erb ON erb.examregID = erss.examregID
                INNER JOIN exam e ON e.examregID = erss.examregID AND e.subjectID = erss.subjectID AND e.batchID = erb.batchID AND e.semID = erb.semID
                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
                LEFT JOIN failed_students fs ON fs.studentID = sa.studentID
                AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                WHERE erss.examregID = '$request->examRegId' AND erss.subjectID = '$request->subjectId' AND ersc.paid=1
                AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID)
                $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;
    }
    /**
     * get exam theory subjects
     */
    public function getExamTheorySubjectsByBatch($examType,$examRegId,$batchId)
    {
        $examType = $this->realEscapeString($examType);
        $examRegId = $this->realEscapeString($examRegId);
        $batchId = $this->realEscapeString($batchId);
        $subjectList = [];
        if ($examType == ExamTypeConstant::REGULAR) {
            $sql = "SELECT e.examID,s.subjectID,s.subjectName,s.subjectDesc,e.examregID,e.supply_examreg_id from exam e
                        INNER JOIN subjects s ON s.subjectID= e.subjectID
                        WHERE e.examregID = '$examRegId' and e.batchID = '$batchId' and s.isTheory = 1 order by e.examID";
        } else if ($examType == ExamTypeConstant::SUPPLY) {
            $sql = "SELECT e.examID,s.subjectID,s.subjectName,s.subjectDesc,e.examregID,e.supply_examreg_id from exam e
                        INNER JOIN subjects s ON s.subjectID= e.subjectID
                        WHERE e.supply_examreg_id = '$examRegId' and e.batchID = '$batchId' and s.isTheory = 1 order by e.examID";
        }
        try {
            $subjectList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectList;
    }
        /**
     * @param $request
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamTimeByExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $examTime = [];
        $sql = null;
        $whereConditions="";
        $examRegIdField = $request->isSupply ? "supply_examreg_id": "examregID";
        if ($request->examDate) {
            $whereConditions .= " AND e.examDate IN ('$request->examDate')";
        }
        try {
            $sql = "SELECT distinct concat(e.examStartTime ,' - ',e.examEndTime) as id,concat(e.examStartTime ,' - ',e.examEndTime) as name from exam e where e.$examRegIdField ='$request->examRegId'
            $whereConditions";
            $examTime =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTime;
    }
    /**
     * @author Sibin
     * get Exams Subjects ,valiation dates By ExamRegistration
     */
    public function getExamSubjectsAndValuationDatesByExamRegistrationRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $whereConditions = "";
        $examRegIdField = $request->isSupply ? "supply_examreg_id": "examregID";
        $valuationDateExamRegField = $request->isSupply ? "supplyRegId": "examRegId";
        if ($request->examRegId) {
            $whereConditions .= " AND e.$examRegIdField IN ($request->examRegId";
        }
        if ($request->semId) {
            $whereConditions .= " AND e.semID IN ($request->semId";
        }
        if ($request->batchId) {
            $whereConditions .= " AND e.batchID IN ($request->batchId";
        }
        if ($request->examDate) {
            $whereConditions .= " AND e.examDate IN ('$request->examDate') ";
        }
        $sql = "SELECT distinct
                    e.subjectID as 'subjectId',
                    s.subjectName,
                    s.subjectDesc,
                    s.subjectPriority,
                    s.isTheory,
                    e.semID as 'semId',
                    vds.firstval_Datestart as firstStartDate,
                    vds.firstval_Dateend as firstEndDate,
                    vds.secondval_Datestart as secondStartDate,
                    vds.secondval_Dateend as secondEndDate,
                    vds.thirdval_Datestart as thirdStartDate,
                    vds.thirdval_Dateend as thirdEndDate
                FROM
                    exam e
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                    LEFT JOIN valuationDatesSubjectWise vds ON vds.$valuationDateExamRegField = e.$examRegIdField AND vds.subjectId = e.subjectID
                WHERE
                    1 = 1
                    $whereConditions ORDER BY e.subjectID";
        try {
            $exams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $exams;
    }
    /**
     * @param $request
     * @throws ProfessionalException
     * @author Sibin
     */
    public function assignAllInternalValuationDatesSubjectWise($request)
    {
        $subjectIds = $this->realEscapeArray($request->subjectArray);
        $request->examRegId = $this->realEscapeString($request->examRegId);
        $dates = (object) $this->realEscapeObject($request->dates);
        $insertSql = [];
        $sql = null;
        $result = null;
        $examRegField = $request->isSupply ? "supplyRegId" : "examRegId";
        try {
            if (!empty($subjectIds)) {
                foreach ($subjectIds as $subjectId) {
                    $insertSql[] = "(\"$request->examRegId\", \"$subjectId\", \"$dates->firstStartDate\", \"$dates->firstEndDate\", \"$dates->secondStartDate\", \"$dates->secondEndDate\", \"$dates->thirdStartDate\", \"$dates->thirdEndDate\",\"$request->adminId\")";
                }
                $insertSql = implode(",", $insertSql);
                $sql = "INSERT into valuationDatesSubjectWise($examRegField,subjectId, firstval_Datestart, firstval_Dateend, secondval_Datestart, secondval_Dateend, thirdval_Datestart, thirdval_Dateend,created_by) values " . $insertSql. "
                ON DUPLICATE KEY UPDATE
                firstval_Datestart = VALUES(firstval_Datestart),
                firstval_Dateend = VALUES(firstval_Dateend),
                secondval_Datestart = VALUES(secondval_Datestart),
                secondval_Dateend = VALUES(secondval_Dateend),
                thirdval_Datestart = VALUES(thirdval_Datestart),
                thirdval_Dateend = VALUES(thirdval_Dateend),
                updated_by = VALUES(created_by),
                updated_date = VALUES(updated_date)";
                $this->executeQueryForObject($sql);
                $result = true;
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /* get ug exam reg students with valuation marks by examregid and subjectid
    */
    public function getExamRegisteredStudentsWithMarksBySubject($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_reg_studentsubject erss
                INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = erss.studentID AND ersc.examregID = erss.examregID
                INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                INNER JOIN exam_registration_batches erb ON erb.examregID = erss.examregID
                INNER JOIN exam e ON e.examregID = erss.examregID AND e.subjectID = erss.subjectID AND e.batchID = erb.batchID AND e.semID = erb.semID
                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
                LEFT JOIN failed_students fs ON fs.studentID = sa.studentID
                AND FIND_IN_SET(e.semID, fs.hisSemestersInThisbatch)
                WHERE erss.examregID = '$request->examRegId' AND erss.subjectID = '$request->subjectId' AND ersc.paid=1
                AND e.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID)
                $whereConditions
                order by sa.regNo";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    /* get get Absen StudentList By Exam
    */
    public function getAbsentStudentListByExam($request){
        $request = $this->realEscapeObject($request);
        $condition =" AND ea.isAbsent NOT IN(0) ";
        if($request->getAbsentMarkedOnly){
            $condition =" AND ea.isAbsent IN(1) ";
        }
        else if($request->getPresentMarkedOnly){
            $condition =" AND ea.isAbsent IN(0) ";
        }
        $studentList=[];
        try {
            $sql = "SELECT sa.studentID,sa.regNo,sa.studentName,ea.isAbsent from exam_attendance ea
                    INNER JOIN studentaccount sa ON sa.studentID = ea.studentID
                    WHERE ea.examID IN ($request->examId)  $condition ORDER BY sa.regNo,ea.isAbsent";
            $studentList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentList;
    }
       /** for get published examDetails by sem,batch
     *
     * @param $semId
     * @param $batchId
     * @return List $exams
     */
    public function getSupplyExamsFromPublishExamTimeTable($batchId,$semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $condition="";
        $exams="";
        $sql = "SELECT pet.id,
                        pet.batchID,
                        b.batchName,
                        pet.examTypeID,
                        et.typeName,
                        pet.semID,
                        pet.examregID,
                        pet.startDate,
                        pet.endDate,
                        pet.publish,
                        pet.subjectDetails,
                        pet.supplyregID
                        from publish_exam_time_table pet
                        inner join batches b
                            on b.batchID=pet.batchID
                        inner join exam_type et
                            on et.typeID=pet.examTypeID
                        where pet.batchID ='$batchId'
                        and pet.semID ='$semId'
                        -- and pet.publish=1
                        and pet.supplyregID is not null";
        try{
            $exams = $this->executeQueryForList($sql);
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
        /**
     * Get examId by subjectId
     * @param int $subjectId
     * @param int $batchId
     * @param int $semId
     * @param int $examTypeId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getSupplyPublishExamDetailsBySubjectId($subjectId, $batchId, $semId, $examTypeId, $supplyId, $subbatchId = NULL)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $supplyId = $this->realEscapeString($supplyId);
        $subbatchId = $this->realEscapeString($subbatchId);
        $whereCondition = "";
        if ($subbatchId) {
            $whereCondition .= "AND subbatchID IN ( $subbatchId )";
        }
        $sql = "SELECT e.examID,
                            s.subjectDesc,
                            e.subjectID,
                            e.examTotalMarks,
                            e.examStartTime,
                            e.examEndTime,
                            DATE_FORMAT(e.examDate,'%d-%m-%Y') AS examDate,
                            s.subjectName,
                            s.syllabusName,
                            e.subbatchID,
                            s.subjectPriority,
                            es.id as supplyRegId,
                            es.supplyDesc
                                FROM exam e
                                    inner join subjects s
                                    on s.subjectID=e.subjectID
                                    INNER JOIN exam_supplementary es
                                    ON es.id = e.supply_examreg_id
                                    WHERE e.subjectID = $subjectId
                                    AND e.batchID = $batchId
                                    AND e.semID = $semId
                                    AND e.supply_examreg_id = $supplyId
                                    and e.examTypeID = $examTypeId $whereCondition";
        try {
            $examId = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
        return $examId;
    }
    /* get exam by exam reg details
    */
    public function getExamByExamRegDetails($request){
        $request = $this->realEscapeObject($request);
        $examRegFiled = $request->isSupply ? "supply_examreg_id" : "examregID";
        $exam=null;
        try {
            $sql = "SELECT examID,semID,examTotalMarks from exam where $examRegFiled='$request->examRegId' and subjectID ='$request->subjectId' AND batchID = '$request->batchId'";
            $exam = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exam;
    }
    /**
     * Get all supplementary registered students by batchId and supplyExamregId
     * @param $supplyExamregId
     * @param $batchId
     * @param $semId
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentsRegisteredForSupplyExaminationByBatchSem($supplyExamregId, $batchId, $semId)
    {
        $sql = '';
        $batchId = $this->realEscapeString($batchId);
        $supplyExamregId = $this->realEscapeString($supplyExamregId);
        $studentDetails = null;
        try {
            $sql = "SELECT sa.studentID, sa.studentName, sa.regNo FROM studentaccount sa INNER JOIN exam_supplementary_student_details essd ON (sa.studentID = essd.studentID) WHERE sa.batchID = '$batchId' AND essd.exam_supplementary_id = '$supplyExamregId' UNION SELECT sa.studentID, sa.studentName, sa.regNo 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 = $supplyExamregId AND fs.failedInSemester > '$semId' AND FIND_IN_SET('$semId', fs.hisSemestersInThisbatch) order by regNo asc";
            $studentDetails = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentDetails;
    }
        /**
     * 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 getStudentSupplySubjectsForRegistrationSupply($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 = $this->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 = $this->getStudentExamBatchBySemester ($studentID, $examSupplementary->semID);
            if(!empty( $studentBatchId)){
               $batchID =  $studentBatchId;
            }
            $improvementSubjects = ExamSupplementaryService::getInstance()->getSupplyImproveRegisteredStudentSubjectDetails($supplyregID, $studentID);
            $studentImprovementSubjects=[];
            $considerImprovment = ($COLLEGE_CODE == "SJC") ? true :false;
            foreach($improvementSubjects as $improvementSubject){
                $studentImprovementSubjects[$improvementSubject->subjectID] =  $improvementSubject;
            }
            $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,
                                e2.examID as supplyExamId
                            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' ) ) ) 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 = $this->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;
                            }
                            else if (!$failedSubjects[$details->studentID]->details[$details->subjectID] && $considerImprovment && $batchCourseType == CourseTypeConstants::PG && $studentImprovementSubjects[$details->subjectID]) {
                                $failedSubjects[$details->studentID]->examID[] = $studentImprovementSubjects[$details->subjectID]->examID;
                                $failedSubjects[$details->studentID]->details[$details->subjectID] = $details;
                            }
                        }
                    }
                }
            } catch (\Exception $e) {
                throw new ProfessionalException($e->getCode(), $e->getMessage());
            }
            $failedSubjectsList =$failedSubjects + $failedSubjectsList;
        }
        return $failedSubjectsList;
    }
    /*
     * save footer details
     * @param $request
     */
    public function saveResultSheetFooter($batchId, $examRegId, $array, $isSupply)
    {
        $batchId = $this->realEscapeString($batchId);
        $examRegId = $this->realEscapeString($examRegId);
        $array = $this->realEscapeArray($array);
        $isSupply = $this->realEscapeString($isSupply);
        $array = json_encode($array);
        if($isSupply){
            $footerDetails = $this->getResultSheetFooter($batchId, $examRegId, $isSupply);
            if($footerDetails){
                $sql = "UPDATE exam_result_footer_details set value = '$array' WHERE supplyregID = $examRegId and  batchID = $batchId";
            }
            else{
                $sql = "INSERT INTO exam_result_footer_details(supplyregID, batchID, value) VALUES($examRegId$batchId, '$array')";
            }
        }
        else{
            $footerDetails = $this->getResultSheetFooter($batchId, $examRegId, $isSupply);
            if($footerDetails){
                $sql = "UPDATE exam_result_footer_details set value = '$array' WHERE examregID = $examRegId and  batchID = $batchId";
            }
            else{
                $sql = "INSERT INTO exam_result_footer_details(examregID, batchID, value) VALUES($examRegId$batchId,'$array')";
            }
        }
        try {
             $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
     /*
     * get footer details
     * @param $request
     */
    public function getResultSheetFooter($batchId, $examRegId, $isSupply)
    {
        $batchId = $this->realEscapeString($batchId);
        $examRegId = $this->realEscapeString($examRegId);
        $isSupply = $this->realEscapeString($isSupply);
        if($isSupply){
                $sql = "SELECT value FROM exam_result_footer_details WHERE supplyregID = $examRegId AND  batchID= $batchId";
        }
        else{
            $sql = "SELECT value FROM exam_result_footer_details WHERE examregID = $examRegId AND  batchID= $batchId";
        }
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /* get published exam registration by batchId
    */
    public function getPublishedRegularExamRegistration($batchId){
        $batchId = $this->realEscapeString($batchId);
        try {
            $sql = "SELECT DISTINCT examregID , semID from exam_registration_batches WHERE batchID =$batchId and publish =1";
            $exam = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exam;
    }
     /**
     * Get student supply exam marks of aregular exam
     */
    public function getStudentPublishedSupplyMarksOfRegularExam($studentId, $examId, $request = NULL)
    {
        $examId = (int)$this->realEscapeString($examId);
        $studentId = (int)$this->realEscapeString($studentId);
        $request = $this->realEscapeObject($request);
        $type = $request->type;
        $yearUpperLimit = $request->yearUpperLimit;
        $monthUpperLimit = $request->monthUpperLimit;
        $supplyMarks = [];
        $conditions = "";
        if($yearUpperLimit && $monthUpperLimit){
            $conditions .= " AND UNIX_TIMESTAMP(CONCAT (es.examYear,'-',es.examMonth,'-01')) <=  UNIX_TIMESTAMP('$yearUpperLimit-$monthUpperLimit-01') ";
        }
        $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 || $batchCourseType == CourseTypeConstants::MPHIL || $batchCourseType == CourseTypeConstants::PHD) {
            $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";
        }
        $marksTableJoin = " INNER JOIN ";
        if(!(int)$request->isExternal){
            $marksTableJoin = " LEFT JOIN ";
        }
        $sql = "SELECT
                ee.mark,
                es.examMonth,
                es.examYear,
                es.isSpecialExam,
                ea.isAbsent,
                esss.exam_supplementary_id AS supplyRegId,
                essd.isSupply AS isSupply,
                e.examID AS examId,
                e.examTotalMarks AS maxMark
            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)
            $marksTableJoin $marksTable ee ON
                (ee.studentID = sa.studentID
                AND ee.examID = e.examID)
            INNER JOIN supplyexam_publishresult sep ON
                (sep.exam_supplementary_id = esss.exam_supplementary_id
                AND sep.batchID = e.batchID)
            LEFT JOIN exam_attendance ea ON ea.examID = e.examID
                AND ea.studentID = sa.studentID
                AND ea.examID =  ee.examID
            WHERE
                esss.studentID = '$studentId'
                AND esss.examID = '$examId'
                AND sep.publish =1
                $conditions $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 published exam registration by batchId
    */
    public function getPublishedSupplyExamRegistration($batchId){
        $batchId = $this->realEscapeString($batchId);
        try {
            $sql = "SELECT DISTINCT exam_supplementary_id , semID from supplyexam_publishresult WHERE batchID =$batchId and publish =1";
            $exam = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exam;
    }
    /* get published exam registration by studentId
    */
    public function getPublishedSupplyExamRegistrationByStudentId($studentId){
        $studentId = $this->realEscapeString($studentId);
        try {
            $sql = "SELECT DISTINCT essd.exam_supplementary_id from exam_supplementary_student_details essd INNER JOIN supplyexam_publishresult sep ON (essd.exam_supplementary_id = sep.exam_supplementary_id) INNER JOIN studentaccount sa ON (sa.studentID = essd.studentID) LEFT JOIN failed_students fs ON (sa.studentID = fs.studentID  AND FIND_IN_SET(sep.semID, fs.hisSemestersInThisbatch)) WHERE essd.studentID IN ($studentId) AND sep.batchID = IF (fs.previousBatch, fs.previousBatch, sa.batchID) and sep.publish =1";
            $exam = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exam;
    }
    /* get published exam registration by studentId
    */
    public function getPublishedRegularExamRegistrationOfFailedStudent($studentId){
        $studentId = $this->realEscapeString($studentId);
        try {
            $sql = "SELECT DISTINCT erb.examregID FROM failed_students fs INNER JOIN exam_reg_studentchallan ers ON (fs.studentID = ers.studentID ) INNER JOIN exam_registration_batches erb ON (fs.previousBatch = erb.batchID AND ers.examregID = erb.examregID AND FIND_IN_SET(erb.semID, fs.hisSemestersInThisbatch)) WHERE ers.studentID in($studentId) AND publish =1";
            $exam = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exam;
    }
    /**
     * @author Sibin
     */
    public function getStudentExamRegBlockedStatusList($studentId, $examregId, $subjectId, $isSupply)
    {
        $studentId = (int)$this->realEscapeString($studentId);
        $examregId = (int)$this->realEscapeString($examregId);
        $subjectId = (int)$this->realEscapeString($subjectId);
        $isSupply = (int)$this->realEscapeString($isSupply);
        $condition = null;
        if ($isSupply == 1) {
            $condition = " AND erbs.supplyreg_id = '$examregId";
        } else {
            $condition = " AND erbs.examreg_id = '$examregId";
        }
        $blockStatus = null;
        $sql = "SELECT erbr.id, erbr.reason, erbr.contact_person_id, erbr.reason_type,sa.staffName,erbr.otherDetails FROM exam_reg_blocked_student erbs
                INNER JOIN exam_reg_block_reason erbr ON (erbs.reason_id = erbr.id)
                LEFT JOIN staffaccounts sa ON sa.staffID = erbr.contact_person_id
                WHERE erbs.student_id = '$studentId' AND erbs.subject_id = '$subjectId$condition ORDER BY FIELD(erbr.reason_type, 'SUBJECT_WISE') DESC";
        try {
            $blockStatus = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $blockStatus;
    }
    /**
     * Get oe exam result
     * @param request
     * @return Object|null
     * @author sibin
     */
    public function getOeExamResult ($examResultRequest) {
        $examResultRequest = $this->realEscapeObject($examResultRequest);
        $examUserResult = null;
        $examUserPoints = null;
        $examUserMarks = null;
        $userTable = $userColumns = $userIdColumn =  null;
        $userTable = "studentaccount";
        $userColumns = "user.studentName AS userName, user.studentEmail AS email, user.studentPhone AS phoneNo, user.rollNo, user.regNo";
        $userIdColumn = "studentID";
        $answerCondition = $logCondition = null;
        $examResultRequest->userId = $examResultRequest->userId ? $examResultRequest->userId : $examResultRequest->studentID;
        $examResultRequest->examId = $examResultRequest->examId ? $examResultRequest->examId : $examResultRequest->examID;
        if ( $examResultRequest->userId ) {
            $answerCondition = " AND oeua.user_id = '$examResultRequest->userId";
            $markCondition = " AND oeum.user_id = '$examResultRequest->userId";
            $logCondition = " AND oeul.user_id = '$examResultRequest->userId";
        }
        if ( $userTable && $userColumns && $userIdColumn ) {
            $sqloeExam = "SELECT id from oe_exams oe where JSON_UNQUOTE(JSON_EXTRACT(oe.identifying_context, '$.examId')) ='$examResultRequest->examId'";
            $examResultRequest->oeExamId = $this->executeQueryForObject($sqloeExam)->id;
            if($examResultRequest->oeExamId){
                $sql1 = "SELECT
                            oeua.id,
                            oeua.oe_exams_id AS examId,
                            SUM(IF(oeum.id IS NOT NULL,
                                0,
                                oea.point)) AS points,
                            oeua.user_id AS userId,
                            oeua.user_type AS userType,
                            oeru.exam_end_time AS retestEndTime,
                            count(oeua.id) AS questionsAttended,
                            $userColumns
                        FROM
                            oe_exam_user_answers oeua
                                INNER JOIN
                            $userTable user ON (user.$userIdColumn = oeua.user_id)
                                LEFT JOIN
                            oe_exam_answers oea ON (oeua.oe_exams_id = oea.oe_exams_id
                                AND oeua.oe_exam_questions_id = oea.oe_exam_questions_id
                                AND oeua.oe_exam_answers_id = oea.id
                                AND oeua.user_type = 'STUDENT')
                                LEFT JOIN
                            oe_exam_user_mark oeum ON (oeum.oe_exams_id = oeua.oe_exams_id
                                AND oeum.oe_exam_questions_id = oeua.oe_exam_questions_id
                                AND oeua.user_id = oeum.user_id
                                AND oeum.user_type = 'STUDENT')
                                LEFT JOIN
                            oe_exam_retest_users oeru ON (oeru.user_id = user.$userIdColumn AND oeru.oe_exams_id = oeua.oe_exams_id )
                        WHERE
                            oeua.oe_exams_id = '$examResultRequest->oeExamId'
                            $answerCondition
                            GROUP BY oeua.user_id
                    UNION
                        SELECT
                            oeul.id,
                            oeul.oe_exams_id AS examId,
                            0,
                            oeul.user_id AS userId,
                            oeul.user_type AS userType,
                            oeru.exam_end_time AS retestEndTime,
                            0,
                            $userColumns
                        FROM
                            oe_exam_user_log oeul
                                INNER JOIN
                            $userTable user ON (user.$userIdColumn = oeul.user_id)
                                LEFT JOIN
                            oe_exam_retest_users oeru ON (oeru.user_id = user.$userIdColumn AND oeru.oe_exams_id = oeul.oe_exams_id )
                        WHERE
                            oeul.oe_exams_id = '$examResultRequest->oeExamId'
                                $logCondition
                                AND oeul.is_submitted = 1
                                AND oeul.user_id NOT IN (SELECT
                                    user_id
                                FROM
                                    oe_exam_user_answers
                                WHERE
                                    oe_exams_id = '$examResultRequest->oeExamId')
                        GROUP BY
                            oeul.user_id
                        ORDER BY
                            rollNo ASC, regNo ASC, userName ASC";
                $sql2 = "SELECT
                        oeum.user_id AS userId,
                        SUM(oeum.mark) AS marks,
                        $userColumns
                    FROM
                        oe_exam_user_mark oeum
                            INNER JOIN
                        $userTable user ON (user.$userIdColumn = oeum.user_id)
                    WHERE
                        oeum.oe_exams_id = '$examResultRequest->oeExamId'
                        AND oeum.user_type = 'STUDENT'
                        $markCondition
                    GROUP BY
                        oeum.user_id
                    ORDER BY
                        rollNo ASC, regNo ASC, userName ASC";
                if ($examResultRequest->userId) {
                    $examUserResult = $this->executeQueryForObject($sql1);
                    $examUserMarks = $this->executeQueryForObject($sql2);
                    $examUserResult->markObtained = ($examUserMarks->marks !== null ? $examUserResult->points + $examUserMarks->marks : ($examUserResult->points !== null ? $examUserResult->points : 0));
                }
            }
            return $examUserResult;
        }
    }
    /**
     * Get students additional credits by batch
     * @param $request
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentsAdditionalCreditsByBatch($request)
    {
        $sql = '';
        $request = $this->realEscapeObject($request);
        $studentList = null;
        try {
            $sql = "SELECT sac.semester_id as semId,
                    b.batchStartYear,
                    b.final_semester as finalSemester,
                    sa.studentID as studentId,
                    sa.regNo,
                    sa.studentName,
                    sac.additional_credit,
                    IF(sac.semester_id % 2,b.batchStartYear + FLOOR(sac.semester_id / 2),(b.batchStartYear + FLOOR(sac.semester_id / 2) -1)) as academicYearStart,
                    SUM(sac.additional_credit) as credits
                    from studentaccount sa
                    INNER JOIN batches b ON b.batchID = sa.batchID
                    LEFT JOIN semester_additional_credit sac ON sac.student_id = sa.studentID
                    WHERE b.batchID IN ($request->batchId)
                    group by sa.studentID,academicYearStart
                    order by sa.regNo";
            $studentList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentList;
    }
    /**
     * Get all student exam mark edit logs by date range
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentExamMarkEditLogs($request)
    {
        $sql = '';
        $dateRequest = $this->realEscapeObject($request);
        $studentLogList = null;
        try {
            $sql = "SELECT esml.student_id as studentId,sa.regNo,sa.studentName,s.subjectID,s.subjectName,s.subjectDesc,esml.log,e.semID as semId,s.syllabusName from ec_student_mark_edit_log esml
                    INNER JOIN studentaccount sa ON sa.studentID = esml.student_id
                    INNER JOIN exam e ON e.examID = esml.exam_id
                    INNER JOIN subjects s ON s.subjectID = e.subjectID
                    WHERE CAST(esml.created_date AS Datetime) >= '$dateRequest->startDate' AND CAST(esml.created_date AS Datetime) <= '$dateRequest->endDate'
                    OR CAST(esml.updated_date AS Datetime) >= '$dateRequest->startDate' AND CAST(esml.updated_date AS Datetime) <= '$dateRequest->endDate'
                    ORDER BY esml.updated_date DESC,esml.created_date DESC";
            $studentLogList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentLogList;
    }
    /**
     * Get all student internal mark edit logs by date range
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getStudentInternalMarkEditLogs($request)
    {
        $sql = '';
        $dateRequest = $this->realEscapeObject($request);
        $studentLogList = null;
        try {
            $sql = "SELECT esml.student_id as studentId,sa.regNo,sa.studentName,s.subjectID,s.subjectName,s.subjectDesc,esml.log,esml.semId,s.syllabusName from im_student_mark_edit_log esml
                    INNER JOIN studentaccount sa ON sa.studentID = esml.student_id
                    INNER JOIN subjects s ON s.subjectID = esml.subjectId
                    WHERE CAST(esml.created_date AS Datetime) >= '$dateRequest->startDate' AND CAST(esml.created_date AS Datetime) <= '$dateRequest->endDate'
                    OR CAST(esml.updated_date AS Datetime) >= '$dateRequest->startDate' AND CAST(esml.updated_date AS Datetime) <= '$dateRequest->endDate'
                    ORDER BY esml.updated_date DESC,esml.created_date DESC";
            $studentLogList = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $studentLogList;
    }
    /**
     * get regular exam date
     * @return Object|null
     * @throws ProfessionalException
     */
    public function getRegularExamDate($batchId, $semId, $isTheory)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $isTheory = $this->realEscapeString($isTheory);
        try {
            $sql = " SELECT ex.examDate from exam ex INNER JOIN subjects s ON (ex.subjectID = s.subjectID ) WHERE ex.batchID = $batchId AND ex.semID = $semId AND ex.examregID IS NOT NULL AND s.isTheory = $isTheory";
            $examDates = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDates;
    }
    /**
     * Get exam dates of exam registration
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamDatesByRegularSupplyExamRegistration($request)
    {
        $request = $this->realEscapeObject($request);
        $examDates = null;
        $sql = null;
        $examRegIdField = $request->isSupply ? "supply_examreg_id": "examregID";
        try {
            $sql = "SELECT distinct examDate as id ,DATE_FORMAT(examDate,'%d-%m-%Y') AS name,batchID as batchId from exam where  $examRegIdField ='$request->examRegId'
            group by examDate";
            $examDates =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDates;
    }
    /**
     * get Regular Exam publish details By BatchId
     * @param $batchId, $semId
     */
    public function getRegularExamPublishDetailsByBatchIdAndSemId($batchId,$semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT er.examregID, er.examregName, er.examMonth, er.examYear, erb.publish_fromDate from exam_registration er inner join exam_registration_batches erb on (er.examregID = erb.examregID ) where erb.batchID =$batchId and erb.semID = $semId and erb.publish = 1";
        try {
            $examDetail = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDetail[0];
    }
    /**
     * for get exam type ($canFacultyEdit flag if true fetch exam types which staff can create exams under them.)
     *
     * @return object $examType
     */
    public function getExamTypes($request){
        $request = $this->realEscapeObject($request);
        $conditions = NULL;
        if ($request->showHidden) {
            $conditions = 'WHERE canShow IN(1,0) ';
        } else {
            $conditions = 'WHERE canShow = 1 ';
        }
        if ($request->canFacultyEdit) {
            $conditions .= ' AND can_faculty_create=1';
        }
        if ($request->isInternal) {
            $conditions .= " AND isInternal = 1";
        }
        if ($request->hasParantExamTypeId) {
            $conditions .= " AND parent_exam_typeID IS NOT NULL";
        }
        if ($request->isSupply!=null) {
            $conditions .= " AND isSupply = $request->isSupply";
        }
        $sql = "SELECT typeID, typeName, typeDesc, can_faculty_create, canShow, isInternal, isSupply, parent_exam_typeID
        FROM exam_type $conditions ORDER BY typeName ASC";
        $examType = $this->executeQueryForList($sql);
        return $examType;
    }
   /**
     * update examTotalMarks
     * @param int $batchId
     * @param int $examTypeId
     * @param int $semId
     * @param int $subjectId
     * @param int $maxMark
     */
    public function updateExamMaxMarkByExamTypeId($batchId, $semId, $subjectId, $examTypeId, $maxMark)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $sql = "UPDATE exam SET examTotalMarks = $maxMark where batchID = $batchId AND semID = $semId AND subjectID = $subjectId AND examTypeID = $examTypeId";
        try {
            $this->executeQuery($sql);
            $sql = "SELECT DISTINCT(studentID) as studentId, marksObtained FROM student_marks  WHERE semID='$semId' AND batchID='$batchId' AND examTypeID='$examTypeId' AND subjectID='$subjectId' AND marksObtained <>-1";
            $studentList = $this->executeQueryForList($sql);
            foreach($studentList as $student){
                $percentage = round(($student->marksObtained / $maxMark) * 100, 2);
                $sql2 = "UPDATE student_marks SET percentage = '$percentage' where batchID = $batchId AND semID = $semId AND subjectID = $subjectId AND examTypeID = $examTypeId AND studentID = '$student->studentId'";
                $this->executeQuery($sql2);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
      /**
     * Get examTypes defined for a subject
     * @param int $batchId
     * @param int $semId
     * @param int $subjectId
     * @return object|array|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamTypeBySubjectExceptSupply($batchId, $semId, $subjectId)
    {
        $sql = "SELECT exty.typeID,exty.typeName,ex.examTotalMarks,ex.examRegId,ex.examID FROM exam ex INNER JOIN exam_type exty ON ex.examTypeID = exty.typeID  WHERE semID = $semId AND batchID = $batchId AND subjectID = $subjectId AND exty.canShow=1 AND ex.supply_examreg_id IS NULL GROUP BY exty.typeID";
        try {
            $examTypes = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examTypes;
    }
    public function insertStudentMarks($request){
        $request = $this->realEscapeObject($request);
        $examTypeID = $request->examTypeID;
        $students = $request->students;
        $examTotalMarks = $request->examTotalMarks;
        $subjectID = $request->subjectID;
        $pssubID = $request->pssubID;
        $staffID = $request->staffID;
        $examID = $request->examID;
        foreach($students as $student){
            $batchID = $student['batchID'];
            $semID = $student['semID'];
            $studentID =$student['studentID'];
            $marksObtained = $student['marksObtained'];
            //$index = array_search($batchID, array_column($batchExamDetails, 'batchID'));
            //$examID = $batchExamDetails[$index]->exam->examID;
            if($marksObtained == ''){
                $sql = "DELETE FROM student_marks where batchID='$batchID' and examID= '$examID' and studentID='$studentID'";
                $this->executeQuery($sql);
            }
            if ($marksObtained == 'MAL' || $marksObtained == 'mal')
            {
                $marksObtained = - .001;
            }
            else if (preg_match ( "/[a-zA-Z]+/", $marksObtained ))
            {
                $marksObtained = - 1;
            }
            if ($examTotalMarks < $marksObtained){
                $marksObtained = $examTotalMarks;
            }
            if ($marksObtained != - 1 && $marksObtained != - .001){
                $percentage = ($marksObtained * 100) / $examTotalMarks;
            }
            else{
                $percentage = 0;
            }
            $sql = "SELECT markID from pseudosubjects_students t2 left join student_marks t1 on t1.studentID = t2.studentID where t1.batchID = '$batchID' and t1.subjectID = '$subjectID'  and t1.examID= '$examID' and t1.studentID=t2.studentID and t2.pseudosubjectID= '$pssubID' AND t2.studentID='$studentID'";
            $result = $this->executeQueryForObject($sql);
            if($result){
                $sql = "UPDATE student_marks set marksObtained='$marksObtained' , percentage='$percentage', semID='$semID',examTypeID='$examTypeID' where batchID='$batchID' and examID='$examID' and studentID='$studentID'";
            }
            else{
                $sql = "INSERT into student_marks (batchID, studentID, examID, marksObtained, subjectID, staffID,percentage,semID,examTypeID) values ('$batchID','$studentID','$examID','$marksObtained','$subjectID','$staffID','$percentage', '$semID', '$examTypeID')";
            }
            $this->executeQuery($sql);
        }
        return;
    }
    public function changeMarksConfirm($request){
        $request = $this->realEscapeObject($request);
        $examTypeID = $request->examTypeID;
        $staffID = $request->staffID;
        $isAproved = $request->isAproved;
        $batchExamDetail = $request->batchExamDetail;
        $batchID = $batchExamDetail['batchID'];
        $semID = $batchExamDetail['semID'];
        $examID = $batchExamDetail['exam']['examID'];
        $sql = "select isAproved from aprove_exam_marks where semID=".$semID." and batchID=".$batchID." and examTypeID=".$examTypeID." and examID = ".$examID."";
        $result = $this->executeQueryForObject($sql);
        if($result){
            $sql = "UPDATE aprove_exam_marks set isAproved=\"$isAproved\",staffID=\"$staffID\", updatedBy=".$_SESSION['staffID'].", updatedDate=utc_timestamp() where semID=$semID and batchID=$batchID and examTypeID=\"$examTypeID\" and examId = ".$examID."";
        }
        else{
            $sql = "INSERT into aprove_exam_marks (batchID, semID, isAproved, staffID,examTypeID, examId, createdBy, createdDate, updatedBy, updatedDate) values (".$batchID.",".$semID.",".$isAproved." ,".$staffID.",".$examTypeID.", ".$examID.", ".$staffID.", utc_timestamp(), ".$staffID.", utc_timestamp())";
        }
        try{
            $this->executeQuery($sql);
            if($isAproved == 1)
            {
                return true;
            }
            else
            {
                return true;
            }
        }
        catch(\Exception $e){
            return false;
        }
    }
    public function confirmMarkSubmitted($request){
        $request = $this->realEscapeObject($request);
        $examTypeID = $request->examTypeID;
        $staffID = $request->staffID;
        $exams = $request->exams;
        $batches = $request->batches;
        $sems = $request->sems;
        $saved_batch_count = 0;
        foreach($exams as $key => $examID){
            $batchID = $batches[$key];
            $semID = $sems[$key];
            $sql = "SELECT examID FROM student_marks WHERE semID = ".$semID." AND batchID = ".$batchID." AND examID = ".$examID." AND examTypeID = ".$examTypeID." AND staffID = ".$staffID."";
            $result = $this->executeQueryForObject($sql);
            if($result){
                $saved_batch_count++;
            }
        }
        if(count($exams) == $saved_batch_count)
        {
            foreach ($exams as $key => $examID)
            {
                $batchID = $batches[$key];
                $semID = $sems[$key];
                $sql = "INSERT INTO marks_submitted (batchID, semID, examID, staffID, confirmed) VALUES (".$batchID.",".$semID.",".$examID.",".$staffID.",1)";
                $result = $this->executeQueryForObject($sql);
                // echo $sql.";<br>";
            }
            return true;
        }
        else{
            return false;
        }
    }
    /**
     * Update exam table with imported details of oe_exam_id and imported timestamp
     * @param int|string $examID
     * @param int|string $onlineExamID
     * @param string $importedTime
     * @throws ProfessionalException
     */
    public function updateExamWithImportedExamdetails($examID,$onlineExamID,$importedTime){
        $examID = $this->realEscapeString($examID);
        $onlineExamID = $this->realEscapeString($onlineExamID);
        $importedTime = $this->realEscapeString($importedTime);
        $sql = "UPDATE exam SET `oe_exams_id` = '$onlineExamID' , `oe_exams_imported_timestamp` = '$importedTime' WHERE `examID` = '$examID'";
        try{
            $this->executeQuery($sql);
        }catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * 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
     * @author sibin
     */
    public function getStudentSupplyExamSubjectsForRegistration($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 = $this->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;
        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 = $this->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;
    }
    public function getExamMarkDetailsOfAStudent($studentId, $batchId, $semId, $subjectId, $examId, $examTypeId)
    {
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $subjectId = $this->realEscapeString($subjectId);
        $examId = $this->realEscapeString($examId);
        $examTypeId = $this->realEscapeString($examTypeId);
        $sql = "select marksObtained,percentage from student_marks WHERE batchID =$batchId  AND semID=$semId AND examID =$examId AND examTypeID=$examTypeId AND subjectID = $subjectId AND studentID = $studentId  ";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get distict student subjects by examRegId
     */
    public function getDistinctExamRegisterationSubjects($examRegId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $sql = "SELECT erss.subjectID as subjectId, s.subjectName, s.subjectDesc,s.isTheory, COUNT( DISTINCT ersc.studentID) AS studentCount FROM exam_reg_studentchallan ersc INNER JOIN exam_reg_studentsubject erss ON (ersc.studentID = erss.studentID AND ersc.examregID = erss.examregID) INNER JOIN subjects s ON (s.subjectID = erss.subjectID ) WHERE ersc.examregID = '$examRegId' AND ersc.paid =1 GROUP BY erss.subjectID ";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    /**
     * get exam reg students by examRegId and subjectid
     */
    public function getExamRegisteredStudentsByExamRegIdAndSubjectId($examRegId,$subjectId)
    {
        $examRegId = $this->realEscapeString($examRegId);
        $subjectId = $this->realEscapeString($subjectId);
            $sql = "SELECT ers.studentID, sa.regNo ,sa.studentName, sa.rollNo  from  exam_reg_studentchallan ers
            INNER JOIN exam_reg_studentsubject ersb ON ersb.examregID=ers.examregID and ersb.studentID = ers.studentID
            INNER JOIN studentaccount sa ON sa.studentID = ers.studentID AND sa.studentID = ersb.studentID
            INNER JOIN batches bt ON bt.batchID = sa.batchID
            where ers.examregID='$examRegId' and ersb.subjectID='$subjectId' and ers.paid=1 order by sa.rollNo ASC";
        try {
            $subjectStudents = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $subjectStudents;
    }
    /**
     * Get CGPA grade schemes by cgpaGradeSchemeId
     * @param int|string $cgpaGradeSchemeId
     * @throws ProfessionalException
     */
    public function getBatchAssignedCGPAGradeSchemes($cgpaGradeSchemeId){
        $cgpaGradeSchemeId = $this->realEscapeString($cgpaGradeSchemeId);
        $cgpaGradeSchemes = [];
        $sql = "SELECT t1.percentFrom, t1.percentTo , t1.letterGrade FROM exam_cgpa_gradepoints t1 INNER JOIN exam_cgpa_gradingscheme t2 ON t1.schemeID = t2.schemeID WHERE t1.schemeID = $cgpaGradeSchemeId ORDER BY t1.percentTo DESC";
        try{
            $cgpaGradeSchemes = $this->executeQueryForList($sql);
        }catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $cgpaGradeSchemes;
    }
    /**
     * Get exam registration details
     * @param int $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getExamRegistrationDetailsByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        if($request->isSupply){
            $sql ="SELECT id as examRegId,supplyDesc as examRegName,supplyDesc as examregName,examMonth, examYear from exam_supplementary WHERE id IN ($request->examRegId)";
        }else{
             $sql ="SELECT examregID as examRegId,examregName as examRegName,examregName as examregName,examMonth, examYear from exam_registration WHERE examregID IN ($request->examRegId)";
        }
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamDatesByExamRegistrationByRequest($request)
    {
        $request = $this->realEscapeObject($request);
        $examRegIdField = $request->isSupply ? "supply_examreg_id": "examregID";
        $examDates = null;
        $sql = null;
        try {
            $sql = "SELECT distinct examDate as id ,DATE_FORMAT(examDate,'%d-%m-%Y') AS name,batchID as batchId from exam where $examRegIdField ='$request->examRegId'
            group by examDate";
            $examDates =  $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $examDates;
    }
    /**
     * @param $semList
     * @param $studentId
     * @throws ProfessionalException
     */
    public function saveStudentAdditionalCredits($semList, $studentId){
        $semList = $this->realEscapeObject($semList);
        $studentId = $this->realEscapeString($studentId);
        $staffId = $_SESSION['adminID'];
        foreach($semList as $sem){
            $sem = (object) $sem;
            $sql = "SELECT id, additional_credit from semester_additional_credit WHERE student_id='$studentId' AND semester_id = '$sem->id'";
            $result = $this->executeQueryForObject($sql);
            if($result){
                $credit = $result->additional_credit + $sem->credit;
                $sql = "UPDATE semester_additional_credit SET additional_credit ='$credit', updated_by='$staffId' WHERE student_id='$studentId' AND semester_id = '$sem->id'";
            }
            else{
                $sql = "INSERT into semester_additional_credit (semester_id, student_id , additional_credit, created_by) values ('$sem->id','$studentId','$sem->credit','$staffId')";
            }
            $this->executeQuery($sql);
        }
        return;
    }
    /**
     * Get online exam by request
     * @param Object $request
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getOnlineExams($request)
    {
        $request = $this->realEscapeObject($request);
        if(!$request->pseudoSubjectId){
            $sql="SELECT id,name from oe_exams
                WHERE JSON_CONTAINS(identifying_context,
                 '{\"batchId\":\"$request->batchId\", \"semId\":\"$request->semId\", \"subjectId\":\"$request->subjectId\"}') and is_deleted = 0
            ";
        }
        else{
            $sql="SELECT id,name from oe_exams
                    WHERE JSON_CONTAINS(identifying_context,
                    '{\"pseudoSubjectId\":\"$request->pseudoSubjectId\"}') and is_deleted = 0
            ";
        }
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * get Internal exams
     * @return Array
     * @throws ProfessionalException
     */
    public function getInternalExamsByBatchIdAndSemId($batchId, $semId)
    {
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $sql = "SELECT examID as id, examName as name from exam where batchID =$batchId and semID = $semId and examregID is null and supply_examreg_id is null GROUP by examName";
        try {
            $internalExams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $internalExams;
    }
    public function createNewExamsForBatch($request)
    {
        $request = $this->realEscapeObject($request);
        $request->examStartTime = !empty($request->examStartTime)?$request->examStartTime:"NULL";
        $request->examEndTime = !empty($request->examEndTime)?$request->examEndTime:"NULL";
        $request->examDate = !empty($request->examDate)?$request->examDate:"NULL";
        $query = "INSERT INTO exam
                  (examName,batchID,subjectID,semID,subbatchID,examTotalMarks,examTypeID,examregID,supply_examreg_id,examDate,examStartTime,examEndTime,created_by)
                  SELECT DISTINCT s.subjectDesc,sbsr.batchID,sbsr.subjectID,sbsr.semID,IFNULL(sbsbs.subbatchID, 0),'$request->maxMark','$request->examTypeId',NULL,NULL,'".$request->examDate."','".$request->examStartTime."','".$request->examEndTime."','$request->createdBy'
                  FROM
                    sbs_relation sbsr
                    INNER JOIN subjects s ON sbsr.subjectID=s.subjectID
                  LEFT JOIN subbatch_sbs sbsbs ON
                    sbsr.sbsID = sbsbs.sbsID
                  WHERE
                  s.subjectID='$request->subjectId'
                  AND IFNULL(sbsbs.subbatchID, 0)
                  NOT IN (SELECT IFNULL(sbsbs.subbatchID, 0) FROM
                         exam
                         WHERE
                         batchID = '$request->batchId' AND semID = '$request->semesterId' AND examTypeID = '$request->examTypeId'
                         AND (subbatchID = IF(sbsbs.subbatchID IS NULL,0,sbsbs.subbatchID) OR subbatchID=0) AND subjectID = sbsr.subjectID
                    ) AND sbsr.batchID = '$request->batchId' AND sbsr.semID = '$request->semesterId';";
        try{
            $this->executeQuery($query);
            return true;
        }catch(\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Assign Attendance End Date
     * @param $request
     * @return void
     * @throws ProfessionalException
     */
    public function assignAttendanceEndDate($request){
        $request = $this->realEscapeObject($request);
        $where = ["1=1"];
        $request->batchId ? $where[] = " batchID = ".$request->batchId." ":"";
        $request->semId ? $where[] = " semID = ".$request->semId." ":"";
        $request->examTypeId ? $where[] = " examTypeID = ".$request->examTypeId. " ":"";
        $sql = "UPDATE exam ";
        $sql .= "SET attendanceEndDate = '".$request->attendanceEndDate."' ";
        $sql .= "WHERE ".implode(" AND ",$where);
        try{
            $this->executeQuery($sql);
        }catch(\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * get slow learner identification
     * @param int $examTypeId
     * @param in $batchId
     * @param int $subjectId
     * @param float $percenatge
     * @param int $semId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getAllSlowLearnerIdentification($request)
    {
        $request = $this->realEscapeObject($request);
        $where = [];
        $request->examTypeId? $where[] = " sld.exam_type_id = $request->examTypeId ":"";
        $request->batchId? $where[] = " sld.identifying_context->>'$.batchId' = $request->batchId ":"";
        $request->semId? $where[] = " sld.identifying_context->>'$.semId' = $request->semId ":"";
        $request->subjectId? $where[] = " sld.identifying_context->>'$.subjectId' = $request->subjectId ":"";
        $request->pseudoSubjectId? $where[] = " sld.identifying_context->>'$.pseudoSubjectId' = $request->pseudoSubjectId ":"";
        $request->id? $where[] = " sld.id = $request->id ":"";
        $request->date ? $where[] = " sld.date = '$request->date":"";
        $sql = "SELECT sld.*, sld.identifying_context->>'$.subjectId' as subjectID,sld.examId,sld.exam_type_id as examTypeID
        FROM slowLearnerIdentification sld
        WHERE ".($where?implode(' AND ',$where):"")."
        GROUP BY sld.id;";
        try {
            return $this->executeQueryForList($sql,$this->mapper[ExamServiceMapper::GET_ALL_SLOW_LEARNER_IDENTIFICATION]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Method to get all registered exams
     * 
     * @author Ranjith Balachandran
     */
    public function getAllRegisteredExams()
    {
        $registeredExams = null;
        
        $sql = "SELECT er.examregID as examRegId, er.examregName as examRegName FROM exam_registration er ORDER BY er.examYear DESC";
        try {
            $registeredExams = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            
            throw new AutonomousException($e->getCode(), $e->getMessage());
        }
        
        return $registeredExams;
    }
    /**
     * Method for getting student exams
     * 
     * @param unknown $examId
     * @param unknown $studentId
     * @throws AutonomousException
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @author Ranjith Balachandran
     */
    public function getStudentExams($examId, $studentId)
    {
        $sql = '';
        $examId = $this->realEscapeString($examId);
        $studentId = $this->realEscapeString($studentId);
        $hisExamOrNot = null;
        
        try {
            $sql = "SELECT e.examID as examId FROM exam e INNER JOIN subjects s ON e.subjectID = s.subjectID INNER JOIN exam_reg_studentsubject erss ON s.subjectID = erss.subjectID AND e.subjectID = erss.subjectID AND e.examID = $examId AND erss.studentID = $studentId";
            $hisExamOrNot = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new AutonomousException($e->getCode(), $e->getMessage());
        }
        
        return $hisExamOrNot;
    }
    /**
     * @param $examRegId
     * @throws ProfessionalException
     * @author Sibin
     */
    public function getExamStudentsBySubject($request)
    {
        $request = $this->realEscapeObject($request);
        $result = null;
        $sql = null;
        $selectFields = "";
        $condition = "";
        if ($request->examType == ExamType::SUPPLY) {
            if ($request->getCountOnly) {
                $selectFields = " count(distinct erss.studentID) as studentCount";
            } else {
                $selectFields = " es.examID,e.batchID,e.subjectID,erss.studentID,sa.regNo,sa.studentName,esas.staffId as staffAssigned ";
            }
        } else {
            if ($request->getCountOnly) {
                $selectFields = " count(distinct ers.studentID) as studentCount";
            } else {
                $selectFields = " e.examID,erb.batchID,ersb.subjectID,ers.studentID,sa.regNo,sa.studentName,esas.staffId as staffAssigned ";
            }
        }
        if($request->excludeAssignedStudents){
            $condition .= " AND esas.staffId IS NULL";
        }
        if($request->getStaffStudents){
            $condition .= " AND esas.staffId IN ($request->staffId)";
        }
        try {
            if ($request->examType == ExamType::SUPPLY) {
                $sql = "SELECT $selectFields FROM exam e
                        INNER JOIN exam_supplementary_student_subjects erss ON erss.examID = e.examID
                        INNER JOIN exam_supplementary_student_details ersd ON ersd.exam_supplementary_id = erss.exam_supplementary_id AND ersd.studentID = erss.studentID
                        INNER JOIN studentaccount sa ON sa.studentID = ersd.studentID
                        INNER JOIN exam es ON es.subjectID = e.subjectID AND es.batchID = e.batchID and es.semID = e.semID AND es.supply_examreg_id = erss.exam_supplementary_id
                        LEFT JOIN examValuationStaffAssignedStudents esas ON esas.examRegId = erss.exam_supplementary_id AND esas.subjectId = e.subjectID AND esas.studentId = erss.studentID AND esas.examType = '$request->examType' AND esas.valuationCount = $request->valuationCount
                        WHERE erss.exam_supplementary_id IN ($request->examRegId) AND e.subjectID IN ($request->subjectId) AND e.examregID IS NOT NULL AND ersd.paid=1
                        $condition
                        ORDER BY sa.regNo";
            } else {
                $sql = "SELECT  $selectFields from exam_registration_batches erb
                        INNER JOIN exam_reg_studentchallan ers on ers.examregID = erb.examregID 
                        INNER JOIN exam_reg_studentsubject ersb ON ersb.examregID=erb.examregID and ersb.studentID = ers.studentID
                        INNER JOIN exam e on e.examregID =erb.examregID AND e.subjectID = ersb.subjectID and e.batchID=erb.batchID
                        INNER JOIN studentaccount sa ON sa.studentID = ers.studentID AND sa.batchID=erb.batchID
                        LEFT JOIN examValuationStaffAssignedStudents esas ON esas.examRegId = erb.examregID AND esas.subjectId = ersb.subjectID AND esas.studentId = ers.studentID AND esas.examType = '$request->examType' AND esas.valuationCount = $request->valuationCount
                        WHERE erb.examregID='$request->examRegId'  and ersb.subjectID='$request->subjectId' and ers.paid=1 
                        $condition
                        ORDER BY sa.regNo";
            }
            if ($request->getCountOnly){
                $result =  $this->executeQueryForObject($sql);
            }else{
                $result =  $this->executeQueryForList($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $result;
    }
    /**
     * @author Sibin
     * get oe exam reg students by examregid and subjectid marks or reviewer+valuer
     */
    public function getExamRegisteredStudentsDetailsBySubjectForReviewer($request)
    {
        $request = $this->realEscapeObject($request);
        $condition = "";
        if ($request->studentId && $request->getSingleStudent) {
            $condition = " AND sa.studentID IN ($request->studentId";
        }
        $examRegField = ($request->examType == ExamType::SUPPLY) ? "exam_supplementary_id" : "examregID";
        $falseNumberJoin = $request->includeStudentWithoutFalseNumber ? " LEFT JOIN " : " INNER JOIN ";
        if ($request->showStudentsByFalseNumber) {
            if($request->getRegularExamFalseNumber){
                $getFalseNumber = "$falseNumberJoin examcontroller_false_number efn ON efn.studentID = sa.studentID AND efn.examregID = $request->regularExamRegId AND efn.examID = ex.examID";
            }else{
                $getFalseNumber = "$falseNumberJoin examcontroller_false_number efn ON efn.studentID = sa.studentID AND efn.$examRegField = $request->examRegId AND efn.examID = e.examID";
            }
            $falseNoField = " , efn.false_number AS falseNumber";
        }
        if ($request->examType == ExamType::SUPPLY) {
            $sql = "SELECT erss.studentID,sa.regNo,sa.studentName,e.examID,e.batchID,e.semID,e.subjectID,e.examTotalMarks,
                    oe.id as oeExamId,oec1.exam_mark as mark1,oec1.is_confirmed as mark1Confirm,oec2.exam_mark as mark2,oec2.is_confirmed as mark2Confirm,
                    IF(oec1.valuation_count,1,0) as valuation1,IF(oec2.valuation_count,1,0) as valuation2,oe.identifying_context ->> '$.examId' as examId
                    $falseNoField 
                    FROM exam ex
                    INNER JOIN exam_supplementary_student_subjects erss ON erss.examID = ex.examID
                    INNER JOIN exam_supplementary_student_details ers ON ers.exam_supplementary_id = erss.exam_supplementary_id AND ers.studentID = erss.studentID
                    INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                    INNER JOIN exam e ON e.supply_examreg_id = erss.exam_supplementary_id AND e.batchID = ex.batchID AND e.subjectID = ex.subjectID
                    INNER JOIN oe_exams oe ON JSON_UNQUOTE(JSON_EXTRACT(oe.identifying_context, '$.examId')) = e.examID AND (oe.properties ->> '$.isMockExam' != 'true' OR oe.properties ->> '$.isMockExam' is null) AND oe.is_archived = 0
                    LEFT JOIN oe_exam_marks_confirm oec1 ON oec1.oe_exams_id = oe.id AND oec1.oe_users_id = erss.studentID AND oec1.valuation_count = 1 AND (oec1.revaluation_id IS NULL OR oec1.revaluation_id = '' ) AND oec1.review_id IS NULL
                    LEFT JOIN oe_exam_marks_confirm oec2 ON oec2.oe_exams_id = oe.id AND oec2.oe_users_id = erss.studentID AND oec2.valuation_count = 1 AND (oec2.revaluation_id IS NULL OR oec2.revaluation_id = '' ) AND oec2.review_id = 1
                    $getFalseNumber
                    WHERE erss.exam_supplementary_id IN ($request->examRegId)  AND ex.subjectID IN ($request->subjectId) AND ex.examregID IS NOT NULL AND ers.paid=1 AND oe.is_deleted = 0
                    $condition
                    group by sa.studentID order by sa.regNo";
        } else {
            $sql = "SELECT distinct erss.studentID,sa.regNo,sa.studentName,e.examID,e.batchID,e.semID,e.subjectID,e.examTotalMarks,
                oe.id as oeExamId,oec1.exam_mark as mark1,oec1.is_confirmed as mark1Confirm,oec2.exam_mark as mark2,oec2.is_confirmed as mark2Confirm,
                IF(oec1.valuation_count,1,0) as valuation1,IF(oec2.valuation_count,1,0) as valuation2,oe.identifying_context ->> '$.examId' as examId
                $falseNoField 
                FROM exam_reg_studentsubject erss
                INNER JOIN exam_reg_studentchallan ersc ON ersc.studentID = erss.studentID AND ersc.examregID = erss.examregID
                INNER JOIN studentaccount sa ON sa.studentID = erss.studentID
                INNER JOIN exam_registration_batches erb ON erb.examregID = erss.examregID AND erb.batchID = sa.batchID
                INNER JOIN exam e ON e.examregID = erss.examregID AND e.subjectID = erss.subjectID AND e.batchID = sa.batchID AND e.semID = erb.semID
                INNER JOIN oe_exams oe ON JSON_UNQUOTE(JSON_EXTRACT(oe.identifying_context, '$.examId')) = e.examID AND (oe.properties ->> '$.isMockExam' != 'true' OR oe.properties ->> '$.isMockExam' is null) AND oe.is_archived = 0
                LEFT JOIN oe_exam_marks_confirm oec1 ON oec1.oe_exams_id = oe.id AND oec1.oe_users_id = erss.studentID AND oec1.valuation_count = 1 AND (oec1.revaluation_id IS NULL OR oec1.revaluation_id = '' ) AND oec1.review_id IS NULL
                LEFT JOIN oe_exam_marks_confirm oec2 ON oec2.oe_exams_id = oe.id AND oec2.oe_users_id = erss.studentID AND oec2.valuation_count = 1 AND (oec2.revaluation_id IS NULL OR oec2.revaluation_id = '' ) AND oec2.review_id = 1
                $getFalseNumber
                WHERE erss.examregID = '$request->examRegId' AND erss.subjectID = '$request->subjectId' AND ersc.paid=1 AND oe.is_deleted = 0 
                $condition
                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;
    }
    /**
     * get Exams By StudentId And ExamDate
     * @param $request
     */
    public function getExamsByStudentdAndExamDate($request)
    {
        $exams = [];
        $request = $this->realEscapeObject($request);
        $examReg= $condition = "";
        if ($request->batchId) {
            $condition .= " AND e.batchID IN ($request->batchId)";
        }
        if($request->examDate){
            $condition .= " AND e.examDate='$request->examDate'";
        }
        if ($request->examType === ExamType::REGULAR) {
            $condition .= " AND e.examRegId='$request->examRegId";
            $condition .= " AND ers.studentID='$request->studentId";
            $sql = "SELECT e.examID,e.subjectID as subjectId,e.batchID as batchId,e.semID as semId 
                FROM 
                    exam e
                INNER JOIN exam_registration er ON 
                    er.examregID = e.examregID
                INNER JOIN exam_reg_studentsubject ers ON 
                    ers.examregID = e.examregID AND
                    ers.subjectID = e.subjectID                  
                where 1=1 $condition";
        } else if ($request->examType === ExamType::SUPPLY) {
            $condition .= " AND esss.exam_supplementary_id='$request->examRegId";
            $condition .= " AND esss.studentID='$request->studentId";
            $sql = "SELECT 
                    e.examID  
                FROM 
                    exam_supplementary_student_subjects esss
                INNER JOIN exam er ON 
                    er.examID = esss.examID  
                INNER JOIN exam e ON 
                    e.subjectID = er.subjectID AND 
                    e.supply_examreg_id = esss.exam_supplementary_id AND 
                    e.batchID = er.batchID 
                WHERE 
                    1 = 1 $condition";
        }
        try {
            $exams = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
    /**
     * get Exams marks By StudentId and subject details
     * @param $request
     */
    public function getStudentExamMarksByArg($studentId,$batchId,$semId,$typeId)
    {
        $exams = [];
        $studentId = $this->realEscapeString($studentId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $typeId = $this->realEscapeString($typeId);
        $sql = "select t1.examID, t2.subjectName,t1.examTotalMarks, t2.subjectDesc from exam t1 inner join subjects t2 ON t1.subjectID=t2.subjectID left join subbatch_student ss ON ss.subbatchID=t1.subbatchID and ss.studentID=$studentId where t1.batchID=$batchId and t1.semID=$semId and t1.examTypeID=$typeId AND (ss.subbatchID is not null OR t1.subbatchID=0)";
        try {
            $exams = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $exams;
    }
    /**
     * get students avg marks of a batch subject
     * @param $request
     */
    public function getStudentAvgMarks($examId,$batchId,$semId,$typeId)
    {
        $exams = [];
        $examId = $this->realEscapeString($examId);
        $batchId = $this->realEscapeString($batchId);
        $semId = $this->realEscapeString($semId);
        $typeId = $this->realEscapeString($typeId);
        $sql = "select AVG(marksObtained) as avg_mark_obtain from student_marks where semID=$semId and batchID='$batchId' and examTypeID = $typeId and examID= ".$examId." and marksObtained!=-1";
        try {
            return $this->executeQueryForObject($sql)->avg_mark_obtain;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    public function getAllExamDetailsWithBatchAndSubject($batchID,$subjectID)
    {
        $batchID = $this->realEscapeString($batchID);
        $subjectID = $this->realEscapeString($subjectID);
        $sql = "SELECT
                    t1.examID,
                    t1.examName,
                    t1.subjectID,
                    t2.subjectName,
                    t1.isInternal,
                    t2.subjectDesc,
                    t1.semID 
                from
                    universityExams t1,
                    subjects t2
                where
                    t1.batchID = '$batchID'
                    and t1.subjectID = t2.subjectID
                    and t1.subjectID  = '$subjectID'
                order by
                    t1.examID;
                ";
        try {
            return $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    
    public function getStatusOfWorkflowRequest($studentId,$academicTermId,$workFlowId = '')
    {
        $studentId = $this->realEscapeString($studentId);
        $academicTermId = $this->realEscapeString($academicTermId);
        $workFlowId = $this->realEscapeString($workFlowId);
        $query = "SELECT `status` FROM wm_workflow_requests WHERE `student_id`='$studentId' AND `academic_term_id`='$academicTermId";
        if($workFlowId) {
            $query .= " AND `wm_workflow_id`='$workFlowId'";
        }
        $query .= " ORDER BY FIELD(`status`,'APPROVED','REJECTED','PENDING')";
        try{
            $data = $this->executeQueryForObject($query);
            return $data->status;
        }catch(\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    public function getExamDetailsByExamTypeForStudent($batchID, $semID, $examTypeID,$studentID)
    {
        $batchID = $this->realEscapeString($batchID);
        $semID = $this->realEscapeString($semID);
        $examTypeID = $this->realEscapeString($examTypeID);
        $studentID = $this->realEscapeString($studentID);
        $sql = "SELECT t1.examID, t1.examName, t1.examTotalMarks, t2.subjectName,t2.subjectID,t2.subjectDesc from exam t1, subjects t2 where t1.batchID=$batchID and t1.semID=$semID and t1.examTypeID=$examTypeID and t1.subjectID = t2.subjectID";
        try {
            $final = [];
            $subjects = $this->executeQueryForList($sql);
            foreach($subjects as $subject)
            {
                $sqlCheck = "SELECT sr.subjectID  
                                FROM subbatch_sbs ss 
                                inner join sbs_relation sr on sr.sbsID = ss.sbsID 
                                WHERE sr.subjectID = $subject->subjectID 
                                AND sr.batchID = $batchID 
                                AND sr.semID = $semID";
                $hasValues = $this->executeQueryForObject($sqlCheck)->subjectID;
                if($hasValues)
                {
                    $sqlStudentSubbatch = "SELECT
                                                sr.subjectID 
                                            FROM
                                                subbatch_sbs ss
                                            inner join sbs_relation sr on
                                                sr.sbsID = ss.sbsID
                                            inner join subbatch_student ss2 on ss2.subbatchID = ss.subbatchID 
                                            WHERE
                                                sr.subjectID = $subject->subjectID 
                                                and sr.batchID = $batchID
                                                and sr.semID = $semID and ss2.studentID = $studentID";
                    $hasSubbatch = $this->executeQueryForObject($sqlStudentSubbatch);
                    if($hasSubbatch)
                    {
                        $final[] = $subject;
                    }
                }
                else
                {
                    $final[] = $subject;
                }
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $final;
    }
     /**
     * get exam details by exam type id
     * @param int $examId
     * @return object|NULL
     * @throws ProfessionalException
     */
    public function getExamByExamTypeId($examTypeID)
    {
        $sql = "SELECT typeID,typeName,typeDesc FROM exam_type WHERE typeID=$examTypeID";
        try {
            $examDetails = $this->executeQueryForObject($sql);
            return  $examDetails;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getMessage(), $e->getCode());
        }
    }
    /**
     * Get exam registration details
     * @param int $batchId
     * @return object|NULL|\com\linways\base\util\$objectList[]
     * @throws ProfessionalException
     */
    public function getStudentExamDetails($batchId,$termId)
    {
        $batchId = $this->realEscapeString($batchId);
        $termId = $this->realEscapeString($termId);
        $sql = "SELECT 
            JSON_EXTRACT(eer.properties, '$.examMonth') AS examMonth,
            JSON_EXTRACT(eer.properties, '$.examYear') AS examYear
        FROM 
            ec_exam_registration eer 
        INNER JOIN 
            ec_exam_registration_batch eerb 
        ON 
            eer.id = eerb.ec_exam_registration_id 
        INNER JOIN 
            `groups` g 
        ON 
            eerb.groups_id = g.id
        INNER JOIN 
            batches b 
        ON 
            b.groups_id = g.id 
        WHERE 
            b.batchID = '$batchId' AND eerb.academicTermId = '$termId'";
        try {
            return $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
}
?>