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 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1753
Template15MigrationdResultGenerator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 11
148610.00
0.00% covered (danger)
0.00%
0 / 1753
 __construct
n/a
0 / 0
1
n/a
0 / 0
 processData
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 34
 getStudentsOverallMarkReport
0.00% covered (danger)
0.00%
0 / 1
29070.00
0.00% covered (danger)
0.00%
0 / 702
 markListProcessing
0.00% covered (danger)
0.00%
0 / 1
14520.00
0.00% covered (danger)
0.00%
0 / 588
 getStudentSubjectGradeDetailsForMarkHistory
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 37
 getGradeByPercentage
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 8
 getStudentImprovementExamDetailsForThisExam
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 16
 getStudentExamDetails
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 15
 getSupplyMarkHistory
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 22
 checkIsFailedByPassPercentCriteria
0.00% covered (danger)
0.00%
0 / 1
380.00
0.00% covered (danger)
0.00%
0 / 43
 getSemesterGradeDetials
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 9
 getStudentsSupplyMarkReport
0.00% covered (danger)
0.00%
0 / 1
2162.00
0.00% covered (danger)
0.00%
0 / 279
<?php
// For Carmel Mala
namespace com\linways\ec\core\service\MarkMigrationGenerator;
use com\linways\ec\core\service\StudentMarkListService;
use com\linways\ec\core\service\ExamRegistrationService;
use com\linways\ec\core\exception\ExamControllerException;
use com\linways\base\util\TwigRenderer;
use com\linways\core\ams\professional\util\PdfUtil;
use com\linways\ec\core\service\CommonExamService;
use com\linways\ec\core\service\MarkMigrationGenerator\MarkMigrationResultDataGenerator;
use com\linways\ec\core\service\StudentsOverAllMarkReportService;
use com\linways\ec\core\service\ExamRevaluationService;
use com\linways\ec\core\request\ConsolidatedOverAllMarkReportRequest;
use com\linways\core\ams\professional\dto\ExamType;
use com\linways\ec\core\service\GradeSchemeService;
use com\linways\core\ams\professional\constant\examcontroller\ExamSubjectTypeConstants;
use com\linways\ec\core\constant\ExamRegistrationTypeConstants;
class Template15MigrationdResultGenerator extends MarkMigrationResultDataGenerator
{
    public function __construct(){}
    
     /**
     * Process Student data college base
     * @param $request
     */
    protected function processData($searchReq){
        $request = new ConsolidatedOverAllMarkReportRequest();
        $request->isStudentWiseImport = $searchReq->isStudentWiseImport;
        $request->groupId = $searchReq->groupId;
        $request->isConsolidatedRequest = TRUE;
        $request->examRegistrationType = "REGULAR";
        $request->fetchMarkHistory = 1;
        $request->isRoundOff = 1;
        $request->considerSupplyImproveCombined = 1;
        // $request->academicTermId = 1;
        $request->studentId = $searchReq->studentId;
        // $request->studentId = 939;
        $request->staffId = $searchReq->staffId;
        $pulishedSupplyRegId = StudentsOverAllMarkReportService::getInstance()->getPublishedSupplyExamRegistrationByStudentId($request);
        $request->supplyRegIdArray = $pulishedSupplyRegId;
        $studentRegularExamDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
        if(empty($studentRegularExamDetails)){
            return;
            throw new ExamControllerException(ExamControllerException::NO_DETAILS_FOUND,"No Details Found");
        }
        $studentDetails = $this->getStudentsOverallMarkReport($request, $studentRegularExamDetails);
        $consolidatedMarkDetails = reset($this->markListProcessing($request, $studentDetails, $studentRegularExamDetails));
        if (!empty($consolidatedMarkDetails)) {
            StudentsOverAllMarkReportService::getInstance()->updateStudentSubjectActiveStatus($request);
            foreach ($consolidatedMarkDetails->semMarks as $semester) {
                foreach ($semester->subject as $subject) {
                    $subject->consolidated->staffId = $request->staffId;
                    StudentsOverAllMarkReportService::getInstance()->insertStudentSubjectConsolidatedMarkDetails($subject->consolidated);
                }
                $semester->consolidated->staffId = $request->staffId;
                StudentsOverAllMarkReportService::getInstance()->insertStudentSemesterConsolidatedMarkDetails($semester->consolidated);
            }
            $consolidatedMarkDetails->consolidated->staffId = $request->staffId;
            StudentsOverAllMarkReportService::getInstance()->insertStudentCourseConsolidatedMarkDetails($consolidatedMarkDetails->consolidated);
            StudentsOverAllMarkReportService::getInstance()->deleteStudentEditstatus($request);
        }
    }
    /**
     * @param ConsolidatedOverAllMarkReportRequest $request
     * @param $examDetails
     * @return array
     */
    protected function getStudentsOverallMarkReport ( ConsolidatedOverAllMarkReportRequest $request, $examDetails )
    {
        
        if ( empty ( $examDetails ) ) {
            return null;
        }
        if ($request->fetchOnlyMark) {
            $subjectMark = [];
        }
        $examGroupId = current($examDetails)->batch->groupId;
        $searchRequest = new \stdClass();
        $searchRequest->groupId = $examGroupId;
        $searchRequest->academicTermId = $request->academicTermId;
        // $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
        // $searchRequest->requestType = "SEMESTER";
        // $semesterGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
        $searchRequest->requestType = "CURRICULAM";
        $cgpaGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
        $cgpaGradeDetails = reset($cgpaGradeSchemeArray)->grades;
        if ( $request->considerImprovement ) {
            $request->examRegistrationType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
            $request->subjectRegistrationType = ExamRegistrationTypeConstants::IMPROVEMENT;
            $improvementExamDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
            $request->subjectRegistrationType = "";
        }
        if ( $request->considerSupplementary ) {
            $request->examRegistrationType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
            $request->subjectRegistrationType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
            $supplyExamDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
            $request->subjectRegistrationType = "";
            // if ( $request->considerCombinedRegistration ) {
            //     $request->examRegistrationType = "SUPPLEMENTARY";
            //     $request->considerSupplyImproveCombined = 1;
            //     $supplyCombinedExamDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
            //     $request->considerSupplyImproveCombined = "";
            // }
        }
        if ( $request->considerModerationMark ) {
            $request->examRegistrationType = "";
            $request->requestType = "MODERATION";
            $moderationMarkDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
        }
        if ( $request->considerGraceMark ) {
            $request->examRegistrationType = "";
            $request->requestType = "GRACEMARK";
            $graceMarkDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
        }
        $student = [];
        $passCriteriaArray = [];
        $creditGradePoint = 0;
        $aggregatePassCriteria = null;
        $batchStartYear = reset($examDetails)->batch->startYear;
        $courseTypeId = reset($examDetails)->batch->courseTypeId;
        $courseType = new \stdClass();
        $courseType->courseTypeMethod = reset($examDetails)->batch->courseType;
        $courseType->isPG = 0;
        if ($courseType->courseTypeMethod == 'PG') {
            $courseType->isPG = 1;
        }
        $failedSemMarks = [];
        $lastExamYear = $lastExamMonth = 0;
        foreach ($examDetails as $exam) {
            $lastSubjectExamYear = $lastSubjectExamMonth = 0;
            $searchRequest = new \stdClass();
            $searchRequest->groupId = $exam->batch->groupId;;
            $searchRequest->academicTermId = $exam->semester->academicTermId;
            $searchRequest->academicPaperSubjectId = $exam->subject->academicPaperSubjectId;
            $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
            $searchRequest->requestType = "SEMESTER";
            $semesterGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
            $lastSubjectExamYear = $exam->examRegistrations->year;
            $lastSubjectExamMonth = $exam->examRegistrations->month;
            if ($lastExamYear < $exam->examRegistrations->year) {
                $lastExamYear = $exam->examRegistrations->year;
                $lastExamMonth = $exam->examRegistrations->month;
            } else if ($lastExamYear == $exam->examRegistrations->year) {
                $lastExamMonth = $lastExamMonth < $exam->examRegistrations->month ? $exam->examRegistrations->month : $lastExamMonth;
            }
            $semesterGradeKey = array_search($exam->semester->academicTermId, array_column( $semesterGradeSchemeArray, "id"));
            if($semesterGradeKey || $semesterGradeKey === 0){
                $semesterGradeDetails = $semesterGradeSchemeArray[$semesterGradeKey]->grades;
            }
            $maxSemesterGradePercent = $semesterGradeDetails[0]->rangeTo;
            $subjectGradeKey = array_search($exam->subject->academicPaperSubjectId, array_column( $subjectGradeSchemeArray, "id"));
            $gradeDetails = '';
            if($subjectGradeKey || $subjectGradeKey === 0){
                $gradeDetails = $subjectGradeSchemeArray[$subjectGradeKey]->grades;
            }
            $maxGradePercent = $gradeDetails[0]->rangeTo;
            $maxGradePoint = max(array_column($gradeDetails,"gradePoint"));
            $academicTermId = $exam->semester->academicTermId;
            $academicPaperSubjectId = $exam->subject->academicPaperSubjectId;
            $schemeType = "PERCENTAGE";
            $passCriteriaArray[$academicPaperSubjectId] = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($academicPaperSubjectId, $schemeType);
            $internalPassCriteria = $externalPassCriteria = $overallPassCriteria = $aggregatePassCriteria = null;
            $internalPassCriteria = $passCriteriaArray[$academicPaperSubjectId]->internalPassCriteria;
            $externalPassCriteria = $passCriteriaArray[$academicPaperSubjectId]->externalPassCriteria;
            $overallPassCriteria = $passCriteriaArray[$academicPaperSubjectId]->overallPassCriteria;
            if (!empty ($exam->studentMarks)) {
                foreach ($exam->studentMarks as $studentMark) {
                    $isFailed = 0;
                    $isInternalFailed = 0;
                    $isExternalFailed = 0;
                    $examTotal = 0;
                    $studentExamTotal = 0;
                    $studentExternalMark = null;
                    $grade = null;
                    $studentId = $studentMark->student->studentId;
                    $isExempted = $studentMark->isExempted;
                    $student[$studentId]->semMarks[$academicTermId]->academicTermName = $exam->semester->academicTermName;
                        
                    $markHistory = [];
                    
                    $examMonth = $exam->examRegistrations->month;
                    $examYear = $exam->examRegistrations->year;
                    $monthYearOfPassing = date ( "M Y", strtotime ( $exam->examRegistrations->year . "-" . $exam->examRegistrations->month . "-01"));
                    $examRegTypeOfPassing = ExamType::REGULAR;
                    
                    if ( $isExempted == 0 ) {
                        $considerOverallPassCriteriaOnly = 0;
                        if ( $exam->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                            $exam->subject->subjectType == ExamSubjectTypeConstants::FOUNDATION_COURSE ||
                            $exam->subject->subjectType == ExamSubjectTypeConstants::TERM_PAPER ) {
                            $considerOverallPassCriteriaOnly = 1;
                        }
                        /**
                         * Object created for checking whether a student is passed for a subject by the pass percent 
                         * criteria
                         */
                        $checkPassPercentCriteria = new \stdClass(); 
                        $checkPassPercentCriteria->isInternal = $exam->subject->isInternal;
                        $checkPassPercentCriteria->internalMaxMark = $exam->internalMaxMark;
                        
                        $checkPassPercentCriteria->isExternal = $exam->subject->isExternal;
                        $checkPassPercentCriteria->externalMaxMark = $exam->externalMaxMark;
                        $checkPassPercentCriteria->internalMark = round($studentMark->internalMark);
                        $checkPassPercentCriteria->considerOverallPassCriteriaOnly = $considerOverallPassCriteriaOnly;
                        $checkPassPercentCriteria->passPercentConfig = $passCriteriaArray[$academicPaperSubjectId];
                        /** Code ends **/
                        
                        if ( !$student[$studentId]->lastExamYear || $student[$studentId]->lastExamYear < $lastExamYear ) {
                            $student[$studentId]->lastExamYear = $lastExamYear;
                            $student[$studentId]->lastExamMonth = $lastExamMonth;
                            $student[$studentId]->lastExamReg = ExamType::REGULAR;
                        } else if ( $student[$studentId]->lastExamYear == $lastExamYear && 
                        $student[$studentId]->lastExamMonth < $lastExamMonth ) {
                            $student[$studentId]->lastExamMonth = $lastExamMonth;
                            $student[$studentId]->lastExamReg = ExamType::REGULAR;
                        }
                        if ( !$student[$studentId]->semMarks[$academicTermId]->lastExamYear || $student[$studentId]->semMarks[$academicTermId]->lastExamYear < $lastSubjectExamYear ) {
                            $student[$studentId]->semMarks[$academicTermId]->lastExamYear = $lastSubjectExamYear;
                            $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $lastSubjectExamMonth;
                            $student[$studentId]->semMarks[$academicTermId]->lastExamReg = ExamType::REGULAR;
                        } else if ( $student[$studentId]->semMarks[$academicTermId]->lastSubjectExamYear == $lastSubjectExamYear && 
                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth < $lastSubjectExamMonth ) {
                            $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $lastSubjectExamMonth;
                            $student[$studentId]->semMarks[$academicTermId]->lastExamReg = ExamType::REGULAR;
                        }
                        $studentMark->externalAttendanceStatus =  $studentMark->externalAttendanceStatus?  $studentMark->externalAttendanceStatus : 'PRESENT';
                        $studentExternalMark = $studentMark->externalMark;
                        $checkPassPercentCriteria->externalMark = $studentExternalMark;
                        $isRegularFailed = $this->checkIsFailedByPassPercentCriteria (
                            $checkPassPercentCriteria );
                        $markHistory["REGULAR"]->isFailed = $isRegularFailed;
                        $markHistory["REGULAR"]->mark = $studentMark->externalMark;
                        $markHistory["REGULAR"]->markObtainedInExam = round($studentMark->externalMark);
                        $markHistory["REGULAR"]->examRegistrationId = $exam->examRegistrations->examRegistrationId;
                        $markHistory["REGULAR"]->month = $exam->examRegistrations->month;
                        $markHistory["REGULAR"]->year = $exam->examRegistrations->year;
                        $markHistory["REGULAR"]->assessmentId = $exam->assessmentId;
                        $markHistory["REGULAR"]->oeExamId = $exam->oeExamId;
                        $markHistory["REGULAR"]->externalAttendanceStatus = $studentMark->externalAttendanceStatus;
                        $markHistory["REGULAR"]->name = $exam->examRegistrations->examRegistartionName;
                        // Only if there is any significant improvement in the mark then only there will be entry in the revaluation mark table 
                        if ( $request->considerRevaluation) {
                            $revalRequest = new \stdClass();
                            $revalRequest->studentId = $studentId;
                            $revalRequest->assessmentId = $exam->assessmentId;
                            $revalRequest->orderByHighestMark = 1;
                            $studentRevaluationDetails = StudentsOverAllMarkReportService::getInstance()->getStudentFinalizedRevaluationMark($revalRequest);
                            if($studentRevaluationDetails){
                                $studentRevaluationDetail = current(current($studentRevaluationDetails)->students);
                                if($studentRevaluationDetail->revaluationMark){
                                    $studentExternalMark = $studentRevaluationDetail->revaluationMark;
                                    $markHistory["REGULAR"]->mark = $studentRevaluationDetail->revaluationMark;
                                    $markHistory["REGULAR"]->markType['REVALUATION']->mark = $studentRevaluationDetail->revaluationMark;
                                    // $markHistory["REVALUATION"]->examRegId = $studentRevaluationDetail->revaluationId;
                                    // $markHistory["REVALUATION"]->isAbsent = false;
                                    // $markHistory["REVALUATION"]->name = $studentRevaluationDetail->revalDesc;
                                }
                            }
                        }
                        if ( $request->considerModerationMark ) {
                            $studentModerationMark = $this->getStudentExamDetails($exam->assessmentId, $studentId, $moderationMarkDetails);
                            if($studentModerationMark){
                                $studentExternalMark += $studentModerationMark->externalMark;
                                $markHistory["REGULAR"]->markType['MODERATION']->mark =  $studentModerationMark->externalMark;
                                // $markHistory["REGULAR"]->mark = $studentMark->externalMark;
                            }
                        }
                        if ( $request->considerGraceMark ) {
                            $studentGraceMark = $this->getStudentExamDetails($exam->assessmentId, $studentId, $graceMarkDetails);
                            if($studentGraceMark){
                                $studentExternalMark+= $studentGraceMark->externalMark;
                                $markHistory["REGULAR"]->markType['GRACEMARK']->mark = $studentGraceMark->externalMark;
                            }   
                        }
                        if ( $request->considerImprovement ) {
                            $studentImproveExamMark = $this->getStudentImprovementExamDetailsForThisExam($academicPaperSubjectId, $studentId, $improvementExamDetails);
                            if ($studentImproveExamMark !== null){
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->mark = $studentImproveExamMark->externalMark;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->markObtainedInExam = round($studentImproveExamMark->externalMark);
                                $improveExamDetails = $studentImproveExamMark->examRegistrations;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->name = $improveExamDetails->examRegistartionName;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->id = $improveExamDetails->examRegistrationId;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->examMonth = $improveExamDetails->month;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->examYear = $improveExamDetails->year;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->externalAttendanceStatus = $studentImproveExamMark->externalAttendanceStatus;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->supplyName = $improveExamDetails->examRegistartionName;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->assessmentId = $studentImproveExamMark->assessmentId;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->oeExamId = $studentImproveExamMark->oeExamId;
                                if ($student[$studentId]->lastExamYear < $improveExamDetails->year) {
                                    $student[$studentId]->lastExamYear = $improveExamDetails->year;
                                    $student[$studentId]->lastExamMonth = $improveExamDetails->month;
                                    $student[$studentId]->lastExamReg = ExamType::IMPROVEMENT;
                                } else if ($student[$studentId]->lastExamYear == $improveExamDetails->year &&
                                    $student[$studentId]->lastExamMonth < $improveExamDetails->month) {
                                    $student[$studentId]->lastExamMonth = $improveExamDetails->month;
                                    $student[$studentId]->lastExamReg = ExamType::IMPROVEMENT;
                                }
                                if ($student[$studentId]->semMarks[$academicTermId]->lastExamYear < $improveExamDetails->year) {
                                    $student[$studentId]->semMarks[$academicTermId]->lastExamYear = $improveExamDetails->year;
                                    $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $improveExamDetails->month;
                                    $student[$studentId]->semMarks[$academicTermId]->lastExamReg = ExamType::IMPROVEMENT;
                                } else if ($student[$studentId]->semMarks[$academicTermId]->lastExamYear == $improveExamDetails->year &&
                                    $student[$studentId]->semMarks[$academicTermId]->lastExamMonth < $improveExamDetails->month) {
                                    $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $improveExamDetails->month;
                                    $student[$studentId]->semMarks[$academicTermId]->lastExamReg = ExamType::IMPROVEMENT;
                                }
                                $examMonth = $improveExamDetails->month;
                                $examYear = $improveExamDetails->year;
                                $monthYearOfPassing = date("M Y", strtotime($improveExamDetails->year . "-" . $improveExamDetails->month . "-01"));
                                $examRegTypeOfPassing = ExamType::IMPROVEMENT;
                            }
                            if ($studentImproveExamMark !== null && $studentImproveExamMark->externalMark > $studentExternalMark) {
                                $studentExternalMark = $studentImproveExamMark->externalMark;
                                
                                if ( $request->considerRevaluation) {
                                    $revalRequest = new \stdClass();
                                    $revalRequest->studentId = $studentId;
                                    $revalRequest->assessmentId = $studentImproveExamMark->assessmentId;
                                    $revalRequest->orderByHighestMark = 1;
                                    $studentRevaluationDetails = StudentsOverAllMarkReportService::getInstance()->getStudentFinalizedRevaluationMark($revalRequest);
                                    if($studentRevaluationDetails){
                                        $studentRevaluationDetail = current(current($studentRevaluationDetails)->students);
                                        if($studentRevaluationDetail->revaluationMark){
                                            $studentImproveExamMark->externalMark = $studentRevaluationDetail->revaluationMark;
                                            $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->mark = $studentRevaluationDetail->revaluationMark;
                                            $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->markType['REVALUATION']->mark = $studentRevaluationDetail->revaluationMark;
                                        }
                                    }
                                }
                                if ( $request->considerModerationMark ) {
                                    $studentModerationMark = $this->getStudentExamDetails($studentImproveExamMark->assessmentId, $studentId, $moderationMarkDetails);
                                    if($studentModerationMark){
                                        $studentImproveExamMark->externalMark += $studentModerationMark->externalMark;
                                        $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->markType['MODERATION']->mark =  $studentModerationMark->externalMark;
                                        // $markHistory["REGULAR"]->mark = $studentMark->externalMark;
                                    }
                                }
                                if ( $request->considerGraceMark ) {
                                    $studentGraceMark = $this->getStudentExamDetails($studentImproveExamMark->assessmentId, $studentId, $graceMarkDetails);
                                    if($studentGraceMark){
                                        $studentImproveExamMark->externalMark += $studentGraceMark->externalMark;
                                        $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->markType['GRACEMARK']->mark =  $studentModerationMark->externalMark;
                                    }
                                }
                                $studentExternalMark = $studentImproveExamMark->externalMark;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->mark = $studentImproveExamMark->externalMark;
                                $improveExamDetails = $studentImproveExamMark->examRegistrations;
                                $markHistory["IMPROVEMENT"]->supplyMarks['IMPROVEMENT']->name = $improveExamDetails->examRegistartionName;
                            }
                        }
                        if ( $request->considerSupplementary ) {
                            $studentSupplyExam = null;
                            // Get the mark of the last supplementary exam registered by that student
                            $supplyRequest = new ConsolidatedOverAllMarkReportRequest();
                            $supplyRequest->groupId = $request->groupId;
                            $supplyRequest->isConsolidatedRequest = TRUE;
                            $supplyRequest->examRegistrationType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
                            $supplyRequest->academicPaperSubjectId = $academicPaperSubjectId;
                            $supplyRequest->studentId = $studentId;
                            $supplyRequest->orderBy = "HIGHEST"; 
                            $supplyRequest->yearUpperLimit = $request->supplementaryYearUpperLimit;
                            $supplyRequest->monthUpperLimit = $request->supplementaryMonthUpperLimit;
                            $supplyRequest->considerSupplyImproveCombined = $request->considerSupplyImproveCombined;
                            $supplyRequest->studentSupplyRequest = true;
                            $studentSupplyExam = reset(StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($supplyRequest));
                            $supplyRequest->studentSupplyRequest = false;
                        
                            $studentExternalMark = round($studentExternalMark, 2);
                            if (!empty ($studentSupplyExam)) {
                                $supplyStudentDetails = current($studentSupplyExam->studentMarks);
                                $studentSupplyExamMark = round($supplyStudentDetails->externalMark, 2);
                                if( $supplyStudentDetails->studentExamRegType  == ExamType::IMPROVEMENT){
                                    $lastSupplyRegType = ExamType::IMPROVEMENT;
                                    $supplyExamMonth = (int)$studentSupplyExam->examRegistrations->month;
                                    $supplyExamYear = (int)$studentSupplyExam->examRegistrations->year;
                                    if ($student[$studentId]->lastExamYear < $supplyExamYear) {
                                        $student[$studentId]->lastExamYear = $supplyExamYear;
                                        $student[$studentId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->lastExamReg = $lastSupplyRegType;
                                    } else if ($student[$studentId]->lastExamYear == $supplyExamYear &&
                                        $student[$studentId]->lastExamMonth < $supplyExamMonth) {
                                        $student[$studentId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->lastExamReg = $lastSupplyRegType;
                                    }
                                    if ($student[$studentId]->semMarks[$academicTermId]->lastExamYear < $supplyExamYear) {
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamYear = $supplyExamYear;
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamReg = $lastSupplyRegType;
                                    } else if ($student[$studentId]->semMarks[$academicTermId]->lastExamYear == $supplyExamYear &&
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth < $supplyExamMonth) {
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamReg = $lastSupplyRegType;
                                    }
                                    $examMonth = $supplyExamMonth;
                                    $examYear = $supplyExamYear;
                                    $monthYearOfPassing = date("M Y", strtotime($supplyExamYear . "-" . $supplyExamMonth . "-01"));
                                    $examRegTypeOfPassing = $lastSupplyRegType;
                                }
                                if ($studentSupplyExamMark && $studentSupplyExamMark > $studentExternalMark) {
                                    $studentExternalMark = $studentSupplyExamMark;
                                    $studentMark->externalAttendanceStatus = $supplyStudentDetails->externalAttendanceStatus ? $supplyStudentDetails->externalAttendanceStatus : $studentMark->externalAttendanceStatus;
                                    if ( $request->considerRevaluation) {
                                        $revalRequest = new \stdClass();
                                        $revalRequest->studentId = $studentId;
                                        $revalRequest->assessmentId = $studentSupplyExam->assessmentId;
                                        $revalRequest->orderByHighestMark = 1;
                                        $studentRevaluationDetails = StudentsOverAllMarkReportService::getInstance()->getStudentFinalizedRevaluationMark($revalRequest);
                                        if($studentRevaluationDetails){
                                            $studentRevaluationDetail = current(current($studentRevaluationDetails)->students);
                                            if($studentRevaluationDetail->revaluationMark){
                                                $studentExternalMark = $studentRevaluationDetail->revaluationMark;
                                            }
                                        }
                                    }
                                    if ( $request->considerModerationMark ) {
                                        $studentModerationMark = $this->getStudentExamDetails($studentSupplyExam->assessmentId, $studentId, $moderationMarkDetails);
                                        if($studentModerationMark){
                                            $studentExternalMark += $studentModerationMark->externalMark;
                                            // $markHistory["REGULAR"]->mark = $studentMark->externalMark;
                                        }
                                    }
                                    
                                    if ( $request->considerGraceMark ) {
                                        $studentGraceMark = $this->getStudentExamDetails($studentSupplyExam->assessmentId, $studentId, $graceMarkDetails);
                                        if($studentGraceMark){
                                            $studentExternalMark += $studentGraceMark->externalMark;
                                        }
                                    }
                                    $lastSupplyRegType = ExamType::SUPPLY;
                                    if( $supplyStudentDetails->studentExamRegType  == ExamType::IMPROVEMENT){
                                        $lastSupplyRegType = ExamType::IMPROVEMENT;
                                    }
                                    $supplyExamMonth = (int)$studentSupplyExam->examRegistrations->month;
                                    $supplyExamYear = (int)$studentSupplyExam->examRegistrations->year;
                                    if ($student[$studentId]->lastExamYear < $supplyExamYear) {
                                        $student[$studentId]->lastExamYear = $supplyExamYear;
                                        $student[$studentId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->lastExamReg = $lastSupplyRegType;
                                    } else if ($student[$studentId]->lastExamYear == $supplyExamYear &&
                                        $student[$studentId]->lastExamMonth < $supplyExamMonth) {
                                        $student[$studentId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->lastExamReg = $lastSupplyRegType;
                                    }
                                    if ($student[$studentId]->semMarks[$academicTermId]->lastExamYear < $supplyExamYear) {
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamYear = $supplyExamYear;
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamReg = $lastSupplyRegType;
                                    } else if ($student[$studentId]->semMarks[$academicTermId]->lastExamYear == $supplyExamYear &&
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth < $supplyExamMonth) {
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamMonth = $supplyExamMonth;
                                        $student[$studentId]->semMarks[$academicTermId]->lastExamReg = $lastSupplyRegType;
                                    }
                                    $examMonth = $supplyExamMonth;
                                    $examYear = $supplyExamYear;
                                    $monthYearOfPassing = date("M Y", strtotime($supplyExamYear . "-" . $supplyExamMonth . "-01"));
                                    $examRegTypeOfPassing = $lastSupplyRegType;
                                }
                            }
                        }
                        $studentExamTotal = 0;
                        $examTotal = 0;
                    
                        if ($exam->subject->isInternal) {
                            $studentExamTotal = round($studentMark->internalMark);
                            $examTotal = $exam->internalMaxMark;
                            if (!empty ($internalPassCriteria)) {
                                $internalPercent = $exam->internalMaxMark ? (100 * $studentMark->internalMark/ $exam->internalMaxMark) : 0;
                                if ( $considerOverallPassCriteriaOnly == 0 ) {
                                    $isFailed = $internalPassCriteria <= $internalPercent ? $isFailed : 1;
                                    $isInternalFailed = $internalPassCriteria <= $internalPercent ? 0 : 1;
                                }
                            }
                        }
                        $markNeededToPass = $markNeededToPassExternal = $passMark = 0;
                        if ($exam->subject->isExternal) {
                            $studentExamTotal += round($studentExternalMark);
                            $examTotal += $exam->externalMaxMark;
                            if (!empty ($externalPassCriteria)) {
                                $externalPassMark = $exam->externalMaxMark * ($externalPassCriteria /100);
                                if($request->isRoundOff){
                                    $externalPercent = $exam->externalMaxMark ? (100 * round($studentExternalMark) / $exam->externalMaxMark) : 0;
                                }else{
                                    $externalPercent = $exam->externalMaxMark ? (100 * $studentExternalMark / $exam->externalMaxMark) : 0;
                                }
                                if ( $considerOverallPassCriteriaOnly == 0 ) {
                                    $isFailed = $externalPassCriteria <= $externalPercent ? $isFailed : 1;
                                    $isExternalFailed = $externalPassCriteria <= $externalPercent ? 0 : 1;
                                }
                                $markNeededToPass = $markNeededToPassExternal  = $isFailed ? ($externalPassMark - $studentExternalMark ): 0;
                            }
                        }
                        else{
                            $studentExternalMark = 0;
                        }
                        if (!empty ($overallPassCriteria)) {
                            $overallPercent = $examTotal ? 100 * $studentExamTotal / $examTotal : 0;
                            $isFailed = $overallPassCriteria <= $overallPercent ? $isFailed : 1;
                            $overallPassMark = round($overallPassCriteria * ($examTotal / 100),2);
                            $markNeededToPassOverAll  = $isFailed ? ($overallPassMark - $studentExamTotal) : 0;
                            if ($markNeededToPassOverAll > $markNeededToPassExternal) {
                                $markNeededToPass = $markNeededToPassOverAll;
                                $passMark = $overallPassMark;
                            }
                        }
                        if ( $request->fetchMarkHistory ) {
                            $studentSupplyExams = $this->getSupplyMarkHistory ($exam->subject->academicPaperSubjectId, $studentId, $supplyExamDetails);
                            foreach ( $studentSupplyExams as $studentSupplyExam ) {
                                $checkPassPercentCriteria->externalMark = $studentSupplyExam->mark;
                                if ( $request->considerRevaluation) {
                                    $revalRequest = new \stdClass();
                                    $revalRequest->studentId = $studentId;
                                    $revalRequest->assessmentId = $studentSupplyExam->assessmentId;
                                    $revalRequest->orderByHighestMark = 1;
                                    $studentSupplyExam->markObtainedInExam =  round($studentSupplyExam->mark, 2) ;
                                    $studentRevaluationDetails = StudentsOverAllMarkReportService::getInstance()->getStudentFinalizedRevaluationMark($revalRequest);
                                    if($studentRevaluationDetails){
                                        $studentRevaluationDetail = current(current($studentRevaluationDetails)->students);
                                        if($studentRevaluationDetail->revaluationMark){
                                            $studentSupplyExam->mark = $studentRevaluationDetail->revaluationMark;
                                            $studentSupplyExam->markType['REVALUATION']->mark = $studentRevaluationDetail->revaluationMark;
                                        }
                                    }
                                }
                                if ( $request->considerModerationMark ) {
                                    $studentModerationMark = $this->getStudentExamDetails($studentSupplyExam->assessmentId, $studentId, $moderationMarkDetails);
                                    if($studentModerationMark){
                                        $studentSupplyExam->mark += $studentModerationMark->externalMark;
                                        $studentSupplyExam->markType['MODERATION']->mark =  $studentModerationMark->externalMark;
                                        // $markHistory["REGULAR"]->mark = $studentMark->externalMark;
                                    }
                                }
                                if ( $request->considerGraceMark ) {
                                    $studentGraceMark = $this->getStudentExamDetails($studentSupplyExam->assessmentId, $studentId,  $graceMarkDetails);
                                    if($studentGraceMark){
                                        $studentSupplyExam->mark += $studentGraceMark->externalMark;
                                        $studentSupplyExam->markType['GRACEMARK']->mark =  $studentGraceMark->externalMark;
                                    }   
                                }
                                $studentSupplyExam->mark =  round($studentSupplyExam->mark, 2) ;
                                $isSupplyFailed = $this->checkIsFailedByPassPercentCriteria ( 
                                    $checkPassPercentCriteria );
                                $studentSupplyExam->isFailed = $isSupplyFailed;
                                $studentSupplyExam->studentExamRegType = $supplyStudentDetails->studentExamRegType; 
                                $markHistory["SUPPLY"]->supplyMarks[] = $studentSupplyExam;
                            }
                            $markHistory["REGULAR"]->maxMark = $examTotal;
                        }
                        // if ($exam->subject->isInternal &&  $studentMark->internalMark === null) {
                        //     $isFailed = true;
                        // }
                        
                        /**
                         * $maxGradePercent is used so that, we get the percentage in 'out of' the values in the db 
                         * ie, 6, 10 or 100, different values for different colleges for different colleges...
                         */
                        if ( $isFailed ) {
                            $percentageObtained = 0;
                            $semesterGradePercentObtained = 0;
                        }
                        else {
                            $percentageObtained = $maxGradePercent * $studentExamTotal / $examTotal;
                            $percentageObtained = round($percentageObtained, 2);
                           
                            $semesterGradePercentObtained = $maxSemesterGradePercent * $studentExamTotal / $examTotal;
                            $semesterGradePercentObtained = round($semesterGradePercentObtained, 2);
                        }
                        $grade = $this->getGradeByPercentage($percentageObtained, $gradeDetails);
                        if ($courseType->courseTypeMethod == "PG") {
                            $exam->externalMaxMark = $exam->externalMaxMark? $exam->externalMaxMark : 0;
                            $internalMarkPer = $externalMarkPer = 0;
                            $x = 1;
                            // $isFailed = 0;
                            $studentExternalMark = round($studentExternalMark);
                            if ($exam->subject->isInternal) {
                                $internalMarkPer = round($maxGradePercent * $studentMark->internalMark / $exam->internalMaxMark, 2); 
                            }
                            if ($exam->subject->isExternal) {
                                $externalMarkPer = round($maxGradePercent * $studentExternalMark / $exam->externalMaxMark, 2); 
                            }
                            if ($exam->subject->isInternal && $exam->subject->isExternal) {
                                $gradePoint = round((($x * $internalMarkPer) + ( ($maxGradePercent-$x) * $externalMarkPer ) ) / $maxGradePercent, 2);
                            }
                            else {
                                $gradePoint = $internalMarkPer + $externalMarkPer;
                            }
            
                            $overallPercentPG = 100 * $gradePoint / $maxGradePercent ?? 0;
                            if (!empty ($overallPassCriteria)) {
                                $isFailed = $overallPassCriteria <= $overallPercentPG ? $isFailed : 1;
    
                            }
                            if ($isFailed) {
                                $gradePoint = 0;
                            }
                            $grade = $this->getGradeByPercentage($gradePoint, $gradeDetails);
                            $grade->gradePoint = $gradePoint ?? 0;
                            $isFailed = $grade->failStatus ? 1 : $isFailed;
                        }
                        if (!empty ($grade)) {
                            $creditGradePoint = ($exam->subject->credit * $grade->gradePoint);
                            if ($grade->failStatus == 1) {
                                $isFailed = 1;
                            }
                        }
                    } // Exempted ends
                    if($studentMark->internalAttendanceStatus == "ABSENT"){
                        $isFailed = 1;
                        $isInternalFailed = 1;
                    }
                    $student[$studentId]->semMarks[$academicTermId]->regularExamRegId = $exam->examRegistrations->examRegistrationId;
                    $student[$studentId]->semMarks[$academicTermId]->examRegName = $exam->examRegistrations->examRegistartionName;
                    $student[$studentId]->semMarks[$academicTermId]->examAttendedGroupId= $exam->batch->groupId;
                    $student[$studentId]->name = $studentMark->student->studentName;
                    $student[$studentId]->regNo = $studentMark->student->regNo;
                    $student[$studentId]->admissionNo = $studentMark->student->admissionNo;
                    $student[$studentId]->studentId = $studentId;
                    $student[$studentId]->myImage = $studentMark->student->myImage;
                    $student[$studentId]->groupId = $studentMark->student->groupId;
                    $student[$studentId]->batchName = $exam->batch->name;
                    $student[$studentId]->gender = $studentMark->student->studentGender;
                    if( !$exam->subject->excludeSubjectFromTotal ){
                        $student[$studentId]->totalArrears += $isFailed;
                        $student[$studentId]->semMarks[$academicTermId]->arrears += $isFailed;
                    }
                    $student[$studentId]->batchStartYear = $exam->batch->startYear;
                    $student[$studentId]->batchEndYear = $exam->batch->endYear ;
                    $student[$studentId]->yearOfStudy = $exam->batch->startYear . " - " . $exam->batch->endYear ;
                    $subject = new \stdClass();
                    $subject->id = $academicPaperSubjectId;
                    $subject->subjectName = $exam->subject->subjectName;
                    $subject->syllabusCode = $exam->subject->syllabusCode;
                    $subject->subjectDesc =  filter_var(html_entity_decode($exam->subject->subjectDesc), FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
                    $subject->subjectCatId = $exam->subject->subjectCatId;
                    $subject->subjectCatName = $exam->subject->subjectCatName;
                    $subject->subjectCatCode = $exam->subject->subjectCatCode;
                    $subject->categoryCode = $exam->subject->categoryCode;
                    
                    $subject->isInternal = $exam->subject->isInternal;
                    $subject->internalMark = $courseType->courseTypeMethod == "PG"? round($studentMark->internalMark, 2) : round($studentMark->internalMark) ;
                    $subject->internalMaxMark = $exam->internalMaxMark;
                    $subject->isInternalFailed = $isInternalFailed;
                    $subject->isInternalAbsent = $studentMark->internalAbsentStatus;
                    $subject->internalMarkDecimal = $studentMark->internalMark;
                    
                    $subject->isExternal = $exam->subject->isExternal;
                    $subject->externalMark = round($studentExternalMark);
                    $subject->externalMark2Decimal = round($studentExternalMark, 2);
                    $subject->externalMaxMark = $exam->externalMaxMark;
                    $subject->isExternalFailed = $isExternalFailed;
                    
                    $subject->internalGradePoint = $internalMarkPer;
                    $subject->externalGradePoint = $externalMarkPer;
                    $subject->credit = $exam->subject->credit;
                    $subject->grade = $grade->letterGrade;
                    $subject->maxGradePercent = $maxGradePercent;
                    $subject->maxGradePoint = $maxGradePoint;
                    
                    $subject->examMonth = $examMonth;
                    $subject->examYear = $examYear;
                    $subject->monthYearOfPassing = $monthYearOfPassing;
                    $subject->examRegTypeOfPassing = $examRegTypeOfPassing;
                    $subject->examAttendedGroupId = $exam->batch->groupId;
                    
                    $subject->subjectOrder = (int) $exam->subject->subjectOrder;
                    $subject->subjectPriority = (int) $exam->subject->subjectPriority;
                    $subject->isTheory = (int) $exam->subject->isTheory;
                    $subject->regularExamId = $exam->id;
                    $subject->supplyAttemptCount  = StudentsOverAllMarkReportService::getInstance()->getSupplyAttemptCount($studentId, $academicPaperSubjectId);
                    $subject->internalPassCriteria = $internalPassCriteria;
                    $subject->externalPassCriteria = $externalPassCriteria;
                    $subject->overallPassCriteria = $overallPassCriteria;
                    
                    $subject->externalPassMark = $externalPassMark;
                    $subject->overallPassMark = $overallPassMark;
                    $subject->markNeededToPassExternal = abs($markNeededToPassExternal);
                    $subject->markNeededToPassOverAll = abs($markNeededToPassOverAll);
                    $subject->markNeededToPass = abs($markNeededToPass);
                    $subject->passMark = $passMark;
                    
                    // isAbsent is only to know whether the student was present/absent for regular exam only
                    $subject->isAbsent = $studentMark->externalAttendanceStatus;
                    $subject->isFailed = $isFailed;
                    $subject->isExempted = $isExempted;
                    $subject->excludeSubjectFromTotal = $exam->subject->excludeSubjectFromTotal;
                    $subject->subjectType = $exam->subject->subjectType;
                    $subject->markHistory = $markHistory;
                    
                    /**
                     * Here 'Class' is fetched from 'semesterGrades' which is for temporary purposes
                     * The class has to be fetched from 'subjectGrades'
                     * A feature has to be added to examController to add ClassName in subjectGrades
                     */
                    $subject->className = $grade->className;
                    // $subject->className = $this->getGradeByPercentage($semesterGradePercentObtained, $semesterGradeDetails)->className;
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId] = $subject;
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->academicPaperSubjectId = $academicPaperSubjectId;
                    // max count of supply attempted in the semester
                    if($student[$studentId]->semMarks[$academicTermId]->supplyAttemptCount < $subject->supplyAttemptCount){
                        $student[$studentId]->semMarks[$academicTermId]->supplyAttemptCount = $subject->supplyAttemptCount;
                    }
                    // max count of supply attempted in all semesters
                    if($student[$studentId]->supplyAttemptCount < $subject->supplyAttemptCount){
                        $student[$studentId]->supplyAttemptCount = $subject->supplyAttemptCount;
                    }
                    if ( $isExempted == 1 ) {
                        continue;
                    }
                    $student[$studentId]->allCredit += $exam->subject->credit;
                    if ($courseType->isPG == 1 &&
                        $exam->batch->startYear >= 2017 &&
                        $exam->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE) {
                        // Exclude open electives from totalMarks and CGPA for pg 2017 onwards
                        continue;
                    } else if ($courseType->isPG == 0 &&
                        $exam->batch->startYear <= 2015 &&
                        $exam->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE) {
                        // Exclude open elective from Total mark & CGPA Calculation for UG passout students
                        continue;
                    } else if ($courseType->isPG == 0 &&
                        $exam->batch->startYear >= 2016 && (
                            $exam->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                            $exam->subject->subjectType == ExamSubjectTypeConstants::FOUNDATION_COURSE ||
                            $exam->subject->subjectType == ExamSubjectTypeConstants::TERM_PAPER)) {
                        // Exclude open elective, term paper, foundation course from Total mark & CGPA Calculation for UG 2016 onwards
                        continue;
                    }
                    $student[$studentId]->credit += $exam->subject->credit;
                    $student[$studentId]->creditGradePoint += $creditGradePoint;
                    if( !$exam->subject->excludeSubjectFromTotal ){
                        $student[$studentId]->semMarks[$academicTermId]->credit += $exam->subject->credit;
                        $student[$studentId]->semMarks[$academicTermId]->creditGradePoint += $creditGradePoint;
                    }
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->gradePoint = $grade->gradePoint;
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->creditGradePoint = $creditGradePoint;
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->totalMarkObtained = round($studentExamTotal, 2);
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->creditxMark = $exam->subject->credit * $studentExamTotal;
                    $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->totalMaxMark = $examTotal;
                    if ( $exam->subject->excludeSubjectFromTotal != 1 ) {
                        $totalMark = round($studentExamTotal, 2);
                        $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->totalMark = $totalMark;
                        $student[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]->percentage = round(100 * 
                            $totalMark / $examTotal, 2);
                        unset ( $totalMark );
                    }
                    if ($courseType->isPG == 0 && (
                            $exam->subject->subjectType == ExamSubjectTypeConstants::FOUNDATION_COURSE ||
                            $exam->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                            $exam->subject->subjectType == ExamSubjectTypeConstants::TERM_PAPER)) {
                        continue;
                    } else if ($courseType->isPG == 0 && $exam->subject->excludeSubjectFromTotal == 1) {
                        continue;
                    } else if ($courseType->isPG == 1 && (
                        $exam->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                        $exam->subject->subjectType == ExamSubjectTypeConstants::IGNITORS )) {
                        continue;
                    }
                    $student[$studentId]->totalMarkObtained += $studentExamTotal;
                    $student[$studentId]->totalMark += $examTotal;
                    $student[$studentId]->semMarks[$academicTermId]->totalMarks += $studentExamTotal;
                    $student[$studentId]->semMarks[$academicTermId]->examTotalMarks += $examTotal;
                    $student[$studentId]->creditForConvocation += $exam->subject->credit;
                    $student[$studentId]->creditGradePointForConvocation += $creditGradePoint;
                }
            }
        }
        if ($request->fetchOnlyMark) {
            return $subjectMark;
        }
        foreach ($student as $studentId => $studentObj) {
            $totalMark = $studentObj->totalMark;
            $maxPercent = $semesterGradeDetails[0]->rangeTo; 
            $studentObj->isFailed = false;
            $studentObj->isPG = $courseType->isPG;
            foreach ($studentObj->semMarks as $actTermId => $semMark) {
                $semMarkGrade = null;
                $semIsFailed = false;
                $searchRequest = new \stdClass();
                $searchRequest->groupId = $semMark->examAttendedGroupId;
                $searchRequest->academicTermId = $actTermId;
                $searchRequest->requestType = "SEMESTER";
                $semesterGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
                $semesterGradeDetails = current($semesterGradeSchemeArray)->grades;
                $maxPercent = $semesterGradeDetails[0]->rangeTo; 
                if ( $semMark->arrears ) {
                    $semMark->sgpa = "0"; // Please don't update "-"
                    $semMarkGrade = $this->getGradeByPercentage(0, $semesterGradeDetails);
                    $semIsFailed = true;
                } else {
                    /**
                     * Semester wise aggregate percentage criteria check
                     */
                    $semesterPercentage = round ( ( $semMark->examTotalMarks ? 100 * $semMark->totalMarks / $semMark->examTotalMarks : 0) , 2);
                    if ( $courseType->isPG == 1 && $semesterPercentage < $aggregatePassCriteria ) {
                        $studentObj->isFailed = true;
                        $semIsFailed = true;
                    }
                    /** codeEnds **/
                    if ( !$studentObj->isFailed ) {
                        $semMark->sgpa = $semMark->credit ? round($semMark->creditGradePoint / $semMark->credit, 2) : 0;
                        $semMarkGrade = $this->getGradeByPercentage($semMark->sgpa, $semesterGradeDetails);
                    }
                }
                $semMark->grade = $semMarkGrade->letterGrade;
                $semMark->class = $semMarkGrade->className;
                $semMark->isFailed = $semIsFailed;
                $semCreditxMark = array_sum(array_column($semMark->subject, "creditxMark"));
                $semMark->WAS = $semMark->credit ? ($semCreditxMark / $semMark->credit) : 0;
                $semMark->rawSgpa = $semMark->credit ? ($semMark->creditGradePoint / $semMark->credit) : 0;
            }
            
            if ($studentObj->totalArrears > 0) {
                $studentObj->isFailed = true;
            }
            /**
             * In 'semesterGradeDetails' the percentage cannot be always in 100.
             * So inorder to handle that '$maxPercent' is used.
             */
            $studentObj->percentage = $totalMark ? ( $maxPercent * $studentObj->totalMarkObtained / $totalMark) : 0;
            $studentObj->percentage = round($studentObj->percentage, 2);
            $schemeType = current($semesterGradeDetails)->schemeType;
            $studentObj->totalSgpaCreditGradePoint = 0;
            $studentObj->totalSgpaCredits = 0;
            if ($studentObj->credit) {
                foreach ($studentObj->semMarks as $actTermId => $semMark) {
                    $semMark->roundedSgpaxCredit = round($semMark->rawSgpa,2) * $semMark->credit;
                    $studentObj->totalSgpaCreditGradePoint += $semMark->roundedSgpaxCredit;
                    $studentObj->totalSgpaCredits +=  $semMark->credit;
                }
                $studentObj->cgpa = $studentObj->totalSgpaCreditGradePoint / $studentObj->totalSgpaCredits;
                // $studentObj->cgpa = $totalCreditGradePoint / $totalCredit;
                if($request->considerRoundingOffCgpa){
                    $studentObj->cgpa = $studentObj->cgpa ? round($studentObj->cgpa,$request->roundingOffCgpaUpto) : $studentObj->cgpa;
                }
                // if ($studentObj->totalArrears > 0 || $studentObj->isFailed ) {
                //     $percentageGrade = $this->getGradeByPercentage(0, $semesterGradeDetails);
                // } else {
                //     if ( $schemeType == "CREDIT") {
                        $percentageGrade = $this->getGradeByPercentage($studentObj->cgpa, $cgpaGradeDetails);
                    // }
                    // else {
                    //     $percentageGrade = $this->getGradeByPercentage($studentObj->percentage, $semesterGradeDetails);
                    // }
                // }
                if (!empty ($percentageGrade)) {
                    $studentObj->grade = $percentageGrade->letterGrade;
                    $studentObj->class = $percentageGrade->className;
                }
            }
        }
        if ($request->getFailedStudentDetailsOnly){
            return $failedSemMarks;
        }
        return $student;
    }
    protected function markListProcessing($request, $studentDetails, $studentRegularExamDetails)
    {
        $searchRequest = new \stdClass();
        $searchRequest->groupId =  $request->groupId;
        $searchRequest->academicTermId = $request->academicTermId;
        $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
        // $reqWithoutGracemark = clone $request;
        // $reqWithoutGracemark->considerGraceMark = false;
        // $studentDetailsWithoutGracemark = reset($this->getStudentsOverallMarkReport($reqWithoutGracemark, $studentRegularExamDetails)); 
        $searchRequest->requestType = "CURRICULAM";
        $cgpaGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
        $cgpaGradeDetails = reset($cgpaGradeSchemeArray)->grades;
        foreach ($studentDetails as $studentId => $student) {
            $student->consolidated->groupId = $student->groupId;
            $student->consolidated->studentId = $studentId;
            $examRegHistoryDetails = null;
            $studentSemHistoryDetails = null;
            $semHistoryArray = [];
            $supplyRegDetails = [];
            $historyRequest = new ConsolidatedOverAllMarkReportRequest();
            $historyRequest = clone $request;
            $historyRequest->considerSupplementary = false;
            $historyRequest->considerImprovement = false;
            $historyRequest->studentId = $request->studentId;
            $historyRequest->groupId = $request->groupId;
            $historyRequest->examRegistrationType = ExamType::REGULAR;
            $historyRequest->requestType = ""; 
            $examRegHistoryDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($historyRequest);
            if ( !empty ( $examRegHistoryDetails ) ) {
                $studentSemHistoryDetails = $this->getStudentsOverallMarkReport($historyRequest, $examRegHistoryDetails);
                $historyRequest->considerGraceMark = false;
                $studentSemHistoryDetailsWithoutGrace = $this->getStudentsOverallMarkReport($historyRequest, $examRegHistoryDetails);
                foreach (reset($studentSemHistoryDetails)->semMarks as $semMarkHisId => $semMarkHis) {
                    $semHistory = new \stdClass();
                    $semHistory->wgp = $semMarkHis->wgp; 
                    $semHistory->creditGradePoint = $semMarkHis->creditGradePoint; 
                    $semHistory->groupId = $semMarkHis->examAttendedGroupId;
                    $semHistory->academicTermId = $semMarkHisId;
                    $semHistory->examRegistrationId = $semMarkHis->regularExamRegId;
                    $semHistory->sgpa = $semMarkHis->rawSgpa; 
                    $semHistory->wgpa = $semMarkHis->wgpa ?? 0; 
                    $semHistory->class = $semMarkHis->class; 
                    $semHistory->grade = $semMarkHis->grade; 
                    $semHistory->examYear = $semMarkHis->lastExamYear;
                    $semHistory->examMonth = $semMarkHis->lastExamMonth;
                    $semHistory->totalMark = $semMarkHis->examTotalMarks;
                    $semHistory->gradePoint = $semMarkHis->gradePoint ?? 0;
                    $semHistory->markObtained = $semMarkHis->totalMarks; 
                    $semHistory->totalMarks = $semMarkHis->examTotalMarks; 
                    $semHistory->percentage = ($semHistory->markObtained / $semHistory->totalMarks) * 100; 
                    $semHistory->creditxMark = $semMarkHis->creditxMark; 
                    $semHistory->failedStatus = $semMarkHis->isFailed ? "FAILED" : "PASSED"; 
                    $semHistory->historyType = ExamType::REGULAR;
                    $student->semMarks[$semMarkHisId]->consolidated->markHistory[] = $semHistory;
                    $student->semMarks[$semMarkHisId]->consolidated->regularExamMarkDetails = $semHistory;
                }
            }
            foreach ($request->supplyRegIdArray as $supplyReg) {
                $supplyHistoryRequest = new ConsolidatedOverAllMarkReportRequest();
                $supplyHistoryRequest = clone $request;
                $supplyHistoryRequest->examRegistrationId = $supplyReg->id;
                $supplyHistoryRequest->examRegistrationType = "";
                $supplyHistoryRequest->requestType = "";
                $supplyHistoryRequest->academicTermId = $supplyReg->academicTermId;
                $supplyRegDetails[$supplyReg->id] = $this->getStudentsSupplyMarkReport($supplyHistoryRequest);
                if (empty($supplyRegDetails[$supplyReg->id])) continue;
                
                $semMarkHis = reset($supplyRegDetails[$supplyReg->id])->overAllMarkDetails->semMarks[$supplyReg->academicTermId];
                $supplySemMarkHis = reset($supplyRegDetails[$supplyReg->id])->semMarks[$supplyReg->academicTermId];
                $semHistory = new \stdClass();
                $semHistory->wgp = $semMarkHis->wgp; 
                $semHistory->creditGradePoint = $supplySemMarkHis->creditGradePoint; 
                $semHistory->groupId = $semMarkHis->examAttendedBatchId;
                $semHistory->academicTermId = $supplyReg->academicTermId;
                $semHistory->sgpa = $semMarkHis->rawSgpa; 
                $semHistory->wgpa = $semMarkHis->wgpa ?? 0; 
                $semHistory->class = $semMarkHis->class; 
                $semHistory->grade = $semMarkHis->grade; 
                $semHistory->examYear = $semMarkHis->lastExamYear;
                $semHistory->examMonth = $semMarkHis->lastExamMonth;
                $semHistory->totalMarks = $supplySemMarkHis->examTotalMarks;
                $semHistory->gradePoint = $supplySemMarkHis->supplyGradePoint ?? 0;
                $semHistory->markObtained = $supplySemMarkHis->totalMarks;  
                $semHistory->supplyMarkObtained = $supplySemMarkHis->supplyRegularTotalMarks; 
                $semHistory->supplyGradePoint = $supplySemMarkHis->supplyRegularGradePoint; 
                $semHistory->percentage = ($semHistory->markObtained / $semHistory->totalMarks) * 100; 
                $semHistory->creditxMark = $supplySemMarkHis->supplyCreditxMarks; 
                $semHistory->failedStatus = $semMarkHis->isFailed ? "FAILED" : "PASSED"; 
                $semHistory->historyType = reset($supplyRegDetails[$supplyReg->id])->examRegType;
                $semHistory->examRegistrationId = $supplyReg->id;
                $student->semMarks[$supplyReg->academicTermId]->consolidated->markHistory[] = $semHistory;
            }
            
            foreach ($student->semMarks as $semId => $semMarks) {
                $semMarks->consolidated->groupId = $semMarks->examAttendedGroupId;
                $semMarks->consolidated->semId = $semId;
                $semMarks->consolidated->academicTermId =  $semId;
                $semMarks->consolidated->studentId = $studentId;
                $semMarks->consolidated->wgpa = 0;
                if(!$student->isPG){
                    $semGradeObject = new \stdClass();
                    $semGradeObject->groupId = $request->groupId;
                    $semGradeObject->academicTermId = $semId;
                    $semesterGradeDetials = $this->getSemesterGradeDetials($semGradeObject, ($semMarks->arrears > 0 ? 0 : round($semMarks->sgpa, 3) * 10));
                }
                foreach ($semMarks->subject as $subjectId => $subject) {
                    $subject->consolidated->examAttendedGroupId = $subject->examAttendedGroupId;
                    $subject->consolidated->groupId = $subject->examAttendedGroupId;
                    $subject->consolidated->academicTermId = $semId;
                    $subject->consolidated->academicPaperSubjectId = $subject->id;
                    $subject->consolidated->id = $subject->id;
                    $subject->consolidated->studentId = $studentId;
                    $searchRequest = new \stdClass();
                    $searchRequest->groupId = $request->groupId;
                    $searchRequest->academicTermId = $semId;
                    $searchRequest->academicPaperSubjectId = $subject->id;
                    $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
                    $gradeDetails[$subject->id] = current($subjectGradeSchemeArray)->grades;
                    $maxGradePercent = current($gradeDetails[$subject->id])->rangeTo;
                    $subject->lastMonthYear = strtotime("01 $subject->monthYearOfPassing");
                    $subject->consolidated->totalMarks = $subject->totalMarkObtained ? $subject->totalMarkObtained : 0;
                    $subject->consolidated->internalMark = $subject->internalMark;
                    $subject->consolidated->isInternalNull = $subject->isInternalNull;
                    $subject->consolidated->internalAttendanceStatus = $subject->isInternalAbsent?"ABSENT":"PRESENT";
                    $subject->consolidated->percentage = $subject->percentage ? $subject->percentage : 0;
                    $subject->consolidated->credit = $subject->credit ? $subject->credit : 0;
                    $subject->consolidated->grade = $subject->grade ? $subject->grade : "";
                    $subject->consolidated->class = $subject->className ? $subject->className : "";
                    $subject->consolidated->gradePoint = $subject->gradePoint ? $subject->gradePoint : 0;
                    $subject->consolidated->creditGradePoint = $subject->creditGradePoint ? $subject->creditGradePoint : 0;
                    $subject->consolidated->noOfChancesTaken = $subject->supplyAttemptCount + 1;
                   
                    $internalGrade = $this->getGradeByPercentage(($subject->internalMark/$subject->internalMaxMark)*$maxGradePercent, $gradeDetails[$subjectId]);
                    $internalGrade->gradePoint = $student->isPG ?$subject->internalGradePoint : $internalGrade->gradePoint;
                    $subject->internalGrade = $internalGrade->letterGrade;
                    $subject->internalGradePoint = $internalGrade->gradePoint;
                    $subjectmarkHistory = [];
                    foreach ($subject->markHistory as $markHistoryType => $markHistory) {
                        if($markHistoryType == ExamType::SUPPLY || $markHistoryType == ExamType::IMPROVEMENT || $markHistoryType == ExamType::REGULAR_SPECIAL_EXAM) {
                            foreach ($markHistory->supplyMarks as $supplyMarksHistory){
                                $subjectmarkHistoryObj = new \stdClass();
                                $subjectmarkHistoryObj->examMarkType = $markHistoryType;
                                if($supplyMarksHistory->studentExamRegType == 'IMPROVEMENT'){  
                                    $subjectmarkHistoryObj->examMarkType = $supplyMarksHistory->studentExamRegType;
                                }
                                $subjectmarkHistoryObj->examRegId = $supplyMarksHistory->id;
                                $subjectmarkHistoryObj->examRegistrationId = $supplyMarksHistory->id;
                                $subjectmarkHistoryObj->assessmentId = $supplyMarksHistory->assessmentId;
                                $subjectmarkHistoryObj->oeExamId = $supplyMarksHistory->oeExamId;
                                if (empty($supplyRegDetails[$subjectmarkHistoryObj->examRegistrationId])) continue;
                                $supplyRegDetail = reset($supplyRegDetails[$subjectmarkHistoryObj->examRegId])->semMarks[$semId]->subject[$subjectId];
                                $subjectmarkHistoryObj->examId = $supplyRegDetail->supplyExamId;
                                $subjectmarkHistoryObj->externalMark = $supplyRegDetail->externalMark;
                                $subjectmarkHistoryObj->externalMarkObtainedInExam = $supplyMarksHistory->markObtainedInExam;
                                $subjectmarkHistoryObj->externalMaxMark = $supplyRegDetail->externalMaxMark;
                                $externalGradePointForGradeCalc = $student->isPG ? $supplyRegDetail->externalGradePoint : (($subjectmarkHistoryObj->externalMark+$subject->graceMark)/$subjectmarkHistoryObj->externalMaxMark)*$maxGradePercent;
                                $externalGrade = $this->getGradeByPercentage($externalGradePointForGradeCalc, $gradeDetails[$subjectId]);
                                $externalGrade->gradePoint = $student->isPG ? $supplyRegDetail->externalGradePoint : $externalGrade->gradePoint;
                                $subjectmarkHistoryObj->externalGrade = $externalGrade->letterGrade;
                                $subjectmarkHistoryObj->externalGradePoint = $externalGrade->gradePoint ?? 0;
                                $subjectmarkHistoryObj->markObtained = $supplyRegDetail->totalMark ?? 0;
                                $subjectmarkHistoryObj->totalMark = $supplyRegDetail->totalMaxMark ?? ($subject->internalMaxMark + $subject->externalMaxMark);
                                $subjectmarkHistoryObj->percentage = ($subjectmarkHistoryObj->markObtained/$subjectmarkHistoryObj->totalMark) * 100;
                                $subjectmarkHistoryObj->internalMark = $subject->internalMark;
                                $subjectmarkHistoryObj->isInternalNull = $subject->isInternalNull;
                                $subjectmarkHistoryObj->internalAttendanceStatus = $subject->isInternalAbsent?"ABSENT":"PRESENT";
                                $subjectmarkHistoryObj->internalGrade = $subject->internalGrade;
                                $subjectmarkHistoryObj->internalGradePoint = $subject->internalGradePoint;
    
                                $percentageObtainedInternal = round(($maxGradePercent * $subject->internalMark / $subject->internalMaxMark), 2);
                                $percentageObtainedExternal = round(($maxGradePercent * $subjectmarkHistoryObj->externalMark / $subjectmarkHistoryObj->externalMaxMark), 2);
                                if($student->batchStartYear > 2018 && $subject->isInternal && $subject->isExternal){
                                    $subjectmarkHistoryObj->wgpa = ($percentageObtainedInternal + (4 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                                    $subjectmarkHistoryObj->wgpa = round($subjectmarkHistoryObj->wgpa, 2) ?? 0;
                                }else if ($subject->isInternal && $subject->isExternal) {
                                    $subjectmarkHistoryObj->wgpa = ($percentageObtainedInternal + (3 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                                    $subjectmarkHistoryObj->wgpa = round($subjectmarkHistoryObj->wgpa, 2) ?? 0;
                                }
                                else if ($subject->isInternal){
                                    $subjectmarkHistoryObj->wgpa = round($percentageObtainedInternal, 2) ?? 0;
                                }
                                else if ($subject->isExternal){
                                    $subjectmarkHistoryObj->wgpa = round($percentageObtainedExternal, 2) ?? 0;
                                }
                                
                                $subjectmarkHistoryObj->creditxMark = $supplyRegDetail->creditxMark;
                                $subjectmarkHistoryObj->grade = $supplyRegDetail->grade;
                                $subjectmarkHistoryObj->class = $supplyRegDetail->class;
                                $subjectmarkHistoryObj->gradePoint = $supplyRegDetail->gradePoint ?? 0;
                                $subjectmarkHistoryObj->creditGradePoint = $subject->credit * $subjectmarkHistoryObj->gradePoint;
                                $subjectmarkHistoryObj->percentageObtainedExternal = $percentageObtainedExternal;
                                $subjectmarkHistoryObj->percentageObtainedInternal = $percentageObtainedInternal;
                                $subjectmarkHistoryObj->isInternal = $subject->isInternal;
                                $subjectmarkHistoryObj->excludeSubjectFromTotal = $subject->excludeSubjectFromTotal;
                                $subjectmarkHistoryObj->isExternal = $subject->isExternal;        
                              
                                $subjectmarkHistoryObj->examMonth = $supplyMarksHistory->examMonth;
                                $subjectmarkHistoryObj->examYear = $supplyMarksHistory->examYear;
                                $subjectmarkHistoryObj->attendanceStatus = $supplyMarksHistory->externalAttendanceStatus;
                                $subjectmarkHistoryObj->resultStatus = $supplyRegDetail->isFailed ? "FAILED" : "PASSED";
                                $passMarkForMarkHistory = $subject->externalPassMark ?? ($subject->overallPassMark ?? 0);
                                $subjectmarkHistoryObj->markNeededToPass = $supplyRegDetail->isFailed ? $passMarkForMarkHistory -  $subjectmarkHistoryObj->externalMark : 0;
                                $subjectmarkHistoryObj->markNeededToPass = abs($subjectmarkHistoryObj->markNeededToPass);
                                $subjectmarkHistoryObj->examName = trim($supplyMarksHistory->supplyName);
                                //for exam written mark details
                                $regularHistory = new \stdClass();
                                $regularHistory->mark =  $subjectmarkHistoryObj->externalMarkObtainedInExam;
                                $markHistoryStatus = $this->getStudentSubjectGradeDetailsForMarkHistory($request, $subject, $semId, $regularHistory);
                                $typeVariable = "externalMarkObtainedInExam";
                                if ( $markHistoryStatus ){
                                    $gradeVar = $typeVariable."Grade";
                                    $subjectmarkHistoryObj->$gradeVar = $markHistoryStatus->letterGrade;
                                    $gradePointVar = $typeVariable."GradePoint";
                                    $subjectmarkHistoryObj->$gradePointVar = $markHistoryStatus->gradePoint;
                                    $creditGradePointVar = $typeVariable."CreditGradePoint";
                                    $subjectmarkHistoryObj->$creditGradePointVar = $markHistoryStatus->creditGradePoint;
                                    $isFailedVar = $typeVariable."IsFailed";
                                    $subjectmarkHistoryObj->$isFailedVar = $markHistoryStatus->isFailed;
                                }
                                //for getting gracemark, revaluation, moderation - gradepoints and marks
                                foreach ($supplyMarksHistory->markType as $typeKey => $subjectMarkType){
                                    $typeVariable = "";
                                    if($typeKey == "REVALUATION"){
                                        $typeVariable = "revaluation";
                                    }
                                    else if($typeKey == "GRACEMARK"){
                                        $typeVariable = "graceMark";
                                    }
                                    else if($typeKey == "MODERATION"){
                                        $typeVariable = "moderation";
                                    }
                                    if( $typeVariable ){
                                        $markVar = $typeVariable."Mark";
                                        if($typeKey == "GRACEMARK"){
                                            $markVar = "graceMark";
                                        }
                                        $subjectmarkHistoryObj->$markVar = $subjectMarkType->mark;
                                        if($typeKey == "GRACEMARK" || $typeKey == "MODERATION"){
                                            $subjectMarkType->mark += $subjectmarkHistoryObj->externalMarkObtainedInExam;
                                        }
                                        $markHistoryStatus = $this->getStudentSubjectGradeDetailsForMarkHistory($request, $subject, $semId, $subjectMarkType);
                                        
                                        if ( $markHistoryStatus ){
                                            $gradeVar = $typeVariable."Grade";
                                            $subjectmarkHistoryObj->$gradeVar = $markHistoryStatus->letterGrade;
                                            $gradePointVar = $typeVariable."GradePoint";
                                            $subjectmarkHistoryObj->$gradePointVar = $markHistoryStatus->gradePoint;
                                            $creditGradePointVar = $typeVariable."CreditGradePoint";
                                            $subjectmarkHistoryObj->$creditGradePointVar = $markHistoryStatus->creditGradePoint;
                                            $isFailedVar = $typeVariable."IsFailed";
                                            $subjectmarkHistoryObj->$isFailedVar = $markHistoryStatus->isFailed;
                                        }
                                    }                                   
                                }
                                $subjectmarkHistory[] = $subjectmarkHistoryObj;
                            }
                        }
                        else if($markHistoryType == ExamType::REGULAR ) {
                            $regularExamSubjectData = reset($studentSemHistoryDetails)->semMarks[$semId]->subject[$subject->id];
                            $regularExamSubjectDataWithoutGraceMark = reset($studentSemHistoryDetailsWithoutGrace)->semMarks[$semId]->subject[$subject->id];
                            $subjectmarkHistoryObj = new \stdClass();
                            $subjectmarkHistoryObj->examMarkType = $markHistoryType;
                            $subjectmarkHistoryObj->examRegistrationId = $markHistory->examRegistrationId;
                            $subjectmarkHistoryObj->assessmentId = $markHistory->assessmentId;
                            $subjectmarkHistoryObj->oeExamId = $markHistory->oeExamId;
                            $subjectmarkHistoryObj->externalMark = $regularExamSubjectData->externalMark;
                            $subjectmarkHistoryObj->externalMarkObtainedInExam = $markHistory->markObtainedInExam;
                            $subjectmarkHistoryObj->externalMaxMark = $subject->externalMaxMark;
                            $externalGradePointForGradeCalc = $student->isPG ? $regularExamSubjectData->externalGradePoint : (($subjectmarkHistoryObj->externalMark+$subject->graceMark)/$subjectmarkHistoryObj->externalMaxMark)*$maxGradePercent;
                            $externalGrade = $this->getGradeByPercentage($externalGradePointForGradeCalc, $gradeDetails[$subjectId]);
                            $externalGrade->gradePoint = $student->isPG ? $regularExamSubjectData->externalGradePoint : $externalGrade->gradePoint;
                            $subjectmarkHistoryObj->externalGrade = $externalGrade->letterGrade;
                            $subjectmarkHistoryObj->externalGradePoint = $externalGrade->gradePoint ?? 0;
                            $subjectmarkHistoryObj->markObtained = $regularExamSubjectData->totalMarkObtained;
                            $subjectmarkHistoryObj->totalMark = $subject->internalMaxMark + $subject->externalMaxMark;
                            $subjectmarkHistoryObj->percentage = ($subjectmarkHistoryObj->markObtained/$subjectmarkHistoryObj->totalMark) * 100;
                            $subjectmarkHistoryObj->internalMark = $subject->internalMark;
                            $subjectmarkHistoryObj->isInternalNull = $subject->isInternalNull;
                            $subjectmarkHistoryObj->internalAttendanceStatus = $subject->isInternalAbsent?"ABSENT":"PRESENT";
                            $subjectmarkHistoryObj->internalGrade = $subject->internalGrade;
                            $subjectmarkHistoryObj->internalGradePoint = $subject->internalGradePoint;
                            $percentageObtainedInternal = round(($maxGradePercent * $subject->internalMark / $subject->internalMaxMark), 2);
                            $percentageObtainedExternal = round(($maxGradePercent * $subjectmarkHistoryObj->externalMark / $subjectmarkHistoryObj->externalMaxMark), 2);
                            if($student->batchStartYear > 2018 && $subject->isInternal && $subject->isExternal){
                                $subjectmarkHistoryObj->wgpa = ($percentageObtainedInternal + (4 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                                $subjectmarkHistoryObj->wgpa = round($subjectmarkHistoryObj->wgpa, 2) ?? 0;
                            }else if ($subject->isInternal && $subject->isExternal) {
                                $subjectmarkHistoryObj->wgpa = ($percentageObtainedInternal + (3 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                                $subjectmarkHistoryObj->wgpa = round($subjectmarkHistoryObj->wgpa, 2) ?? 0;
                            }
                            else if ($subject->isInternal){
                                $subjectmarkHistoryObj->wgpa = round($percentageObtainedInternal, 2) ?? 0;
                            }
                            else if ($subject->isExternal){
                                $subjectmarkHistoryObj->wgpa = round($percentageObtainedExternal, 2) ?? 0;
                            }
                            
                            $grade = $this->getGradeByPercentage($subjectmarkHistoryObj->percentage * $maxGradePercent/100, $gradeDetails[$subjectId]);
                            $grade->gradePoint = $regularExamSubjectData->gradePoint;
                            $subjectmarkHistoryObj->creditxMark = $subject->credit * $subjectmarkHistoryObj->markObtained;
                            $subjectmarkHistoryObj->grade = $regularExamSubjectData->grade;
                            $subjectmarkHistoryObj->class = $regularExamSubjectData->className;
                            $subjectmarkHistoryObj->percentageObtainedExternal = $percentageObtainedExternal;
                            $subjectmarkHistoryObj->percentageObtainedInternal = $percentageObtainedInternal;
                            $subjectmarkHistoryObj->gradePoint = $grade->gradePoint ?? 0;
                            $subjectmarkHistoryObj->creditGradePoint = $subject->credit * $subjectmarkHistoryObj->gradePoint ;
                            $subjectmarkHistoryObj->examMonth = $markHistory->month;
                            $subjectmarkHistoryObj->examYear = $markHistory->year;
                            $subjectmarkHistoryObj->attendanceStatus = $markHistory->externalAttendanceStatus;
                            $subjectmarkHistoryObj->resultStatus = $regularExamSubjectData->isFailed ? "FAILED" : "PASSED";
                            $subjectmarkHistoryObj->resultStatusWithoutGraceMark = $regularExamSubjectDataWithoutGraceMark->isFailed ? "FAILED" : "PASSED";
                            $subjectmarkHistoryObj->markNeededToPass = $regularExamSubjectData->isFailed ? $regularExamSubjectData->markNeededToPass : 0;
                            $subjectmarkHistoryObj->markNeededToPassWithoutGraceMark = $regularExamSubjectDataWithoutGraceMark->isFailed ? $regularExamSubjectDataWithoutGraceMark->markNeededToPass : 0;
                            $subjectmarkHistoryObj->markNeededToPassExternal = $regularExamSubjectData->isExternalFailed ? $regularExamSubjectData->markNeededToPassExternal : 0;
                            $subjectmarkHistoryObj->markNeededToPassOverAll = $regularExamSubjectData->isFailed ? $regularExamSubjectData->markNeededToPassOverAll : 0;
                            $subjectmarkHistoryObj->isInternal = $subject->isInternal;
                            $subjectmarkHistoryObj->excludeSubjectFromTotal = $subject->excludeSubjectFromTotal;
                            $subjectmarkHistoryObj->isExternal = $subject->isExternal;        
                          
                            $subjectmarkHistoryObj->examName = trim($markHistory->name);
                            //for exam written mark details
                            $regularHistory = new \stdClass();
                            $regularHistory->mark =  $subjectmarkHistoryObj->externalMarkObtainedInExam;
                            $markHistoryStatus = $this->getStudentSubjectGradeDetailsForMarkHistory($request, $subject, $semId, $regularHistory);
                            $typeVariable = "externalMarkObtainedInExam";
                            if ( $markHistoryStatus ){
                                $gradeVar = $typeVariable."Grade";
                                $subjectmarkHistoryObj->$gradeVar = $markHistoryStatus->letterGrade;
                                $gradePointVar = $typeVariable."GradePoint";
                                $subjectmarkHistoryObj->$gradePointVar = $markHistoryStatus->gradePoint;
                                $creditGradePointVar = $typeVariable."CreditGradePoint";
                                $subjectmarkHistoryObj->$creditGradePointVar = $markHistoryStatus->creditGradePoint;
                                $isFailedVar = $typeVariable."IsFailed";
                                $subjectmarkHistoryObj->$isFailedVar = $markHistoryStatus->isFailed;
                            }
                            //for getting gracemark, revaluation, moderation - gradepoints and marks
                            foreach ($markHistory->markType as $typeKey => $subjectMarkType){
                                $typeVariable = "";
                                if($typeKey == "REVALUATION"){
                                    $typeVariable = "revaluation";
                                }
                                else if($typeKey == "GRACEMARK"){
                                    $typeVariable = "graceMark";
                                }
                                else if($typeKey == "MODERATION"){
                                    $typeVariable = "moderation";
                                }
                                if( $typeVariable ){
                                    $markVar = $typeVariable."Mark";
                                    if($typeKey == "GRACEMARK"){
                                        $markVar = "graceMark";
                                    }
                                    $subjectmarkHistoryObj->$markVar = $subjectMarkType->mark;
                                    if($typeKey == "GRACEMARK" || $typeKey == "MODERATION"){
                                        $subjectMarkType->mark += $subjectmarkHistoryObj->externalMarkObtainedInExam;
                                    }
                                    $markHistoryStatus = $this->getStudentSubjectGradeDetailsForMarkHistory($request, $subject, $semId, $subjectMarkType);
                                    
                                    if ( $markHistoryStatus ){
                                        $gradeVar = $typeVariable."Grade";
                                        $subjectmarkHistoryObj->$gradeVar = $markHistoryStatus->letterGrade;
                                        $gradePointVar = $typeVariable."GradePoint";
                                        $subjectmarkHistoryObj->$gradePointVar = $markHistoryStatus->gradePoint;
                                        $creditGradePointVar = $typeVariable."CreditGradePoint";
                                        $subjectmarkHistoryObj->$creditGradePointVar = $markHistoryStatus->creditGradePoint;
                                        $isFailedVar = $typeVariable."IsFailed";
                                        $subjectmarkHistoryObj->$isFailedVar = $markHistoryStatus->isFailed;
                                    }
                                }                                   
                            }
                            
                            $subjectmarkHistory[] = $subjectmarkHistoryObj;
                        }
                        else {
                            $subjectmarkHistoryObj = new \stdClass();
                            $subjectmarkHistoryObj->examMarkType = $markHistoryType;
                            $subjectmarkHistoryObj->examRegId = $markHistory->examRegId;
                            $subjectmarkHistoryObj->examId = $markHistory->examId;
                            $subjectmarkHistoryObj->externalMark = $markHistory->mark;
                            $subjectmarkHistoryObj->externalMaxMark = $subject->externalMaxMark;
                            $subjectmarkHistoryObj->internalMark = $subject->internalMark;
                            $subjectmarkHistoryObj->isInternalNull = $subject->isInternalNull;
                            $subjectmarkHistoryObj->internalAttendanceStatus = $subject->isInternalAbsent?"ABSENT":"PRESENT";
                            $subjectmarkHistoryObj->internalGrade = $subject->internalGrade;
                            $subjectmarkHistoryObj->internalGradePoint = $subject->internalGradePoint;
                            
                            $externalGrade = $this->getGradeByPercentage((($subjectmarkHistoryObj->externalMark+$subject->graceMark)/$subjectmarkHistoryObj->externalMaxMark)*$maxGradePercent, $gradeDetails[$subjectId]);
                            $externalGrade->gradePoint = $student->isPG ? $markHistory->externalGradePoint : $externalGrade->gradePoint;
                            $subjectmarkHistoryObj->externalGrade = $externalGrade->letterGrade;
                            $subjectmarkHistoryObj->externalGradePoint = $externalGrade->gradePoint ?? 0;
                            $subjectmarkHistoryObj->markObtained = $subjectmarkHistoryObj->externalMark+$subject->graceMark;
                            $subjectmarkHistoryObj->totalMark = $subject->internalMaxMark + $subject->externalMaxMark;
                            $subjectmarkHistoryObj->percentage = ($subjectmarkHistoryObj->markObtained/$subjectmarkHistoryObj->totalMark) * 100;
                            $percentageObtainedInternal = round(($maxGradePercent * $subject->internalMark / $subject->internalMaxMark), 2);
                            $percentageObtainedExternal = round(($maxGradePercent * $subjectmarkHistoryObj->externalMark / $subjectmarkHistoryObj->externalMaxMark), 2);
                            if($student->batchStartYear > 2018 && $subject->isInternal && $subject->isExternal){
                                $subjectmarkHistoryObj->wgpa = ($percentageObtainedInternal + (4 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                                $subjectmarkHistoryObj->wgpa = round($subjectmarkHistoryObj->wgpa, 2) ?? 0;
                            }else if ($subject->isInternal && $subject->isExternal) {
                                $subjectmarkHistoryObj->wgpa = ($percentageObtainedInternal + (3 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                                $subjectmarkHistoryObj->wgpa = round($subjectmarkHistoryObj->wgpa, 2) ?? 0;
                            }
                            else if ($subject->isInternal){
                                $subjectmarkHistoryObj->wgpa = round($percentageObtainedInternal, 2) ?? 0;
                            }
                            else if ($subject->isExternal){
                                $subjectmarkHistoryObj->wgpa = round($percentageObtainedExternal, 2) ?? 0;
                            }
                            
                            $grade = $this->getGradeByPercentage($subjectmarkHistoryObj->percentage * $maxGradePercent/100, $gradeDetails[$subjectId]);
                            $subjectmarkHistoryObj->creditxMark = $subject->credit * $subjectmarkHistoryObj->markObtained;
                            $subjectmarkHistoryObj->grade = $grade->letterGrade;
                            $subjectmarkHistoryObj->class = $grade->className;
                            $subjectmarkHistoryObj->percentageObtainedExternal = $percentageObtainedExternal;
                            $subjectmarkHistoryObj->percentageObtainedInternal = $percentageObtainedInternal;
                            $subjectmarkHistoryObj->gradePoint = $grade->gradePoint ?? 0;
                            $subjectmarkHistoryObj->creditGradePoint = $subject->credit * $subjectmarkHistoryObj->gradePoint ;
                            $subjectmarkHistoryObj->examMonth = $markHistory->month;
                            $subjectmarkHistoryObj->examYear = $markHistory->year;
                            $subjectmarkHistoryObj->attendanceStatus = $markHistory->externalAttendanceStatus;
                            $subjectmarkHistoryObj->resultStatus = $markHistory->isFailed ? "FAILED" : "PASSED";
                            $subjectmarkHistoryObj->markNeededToPass = $markHistory->isFailed ? $subject->externalPassMark -  $subjectmarkHistoryObj->externalMark : 0;
                            $subjectmarkHistoryObj->markNeededToPass = abs($subjectmarkHistoryObj->markNeededToPass);
                            $subjectmarkHistoryObj->examName = trim($markHistory->name);
                            $subjectmarkHistoryObj->isInternal = $subject->isInternal;
                            $subjectmarkHistoryObj->excludeSubjectFromTotal = $subject->excludeSubjectFromTotal;
                            $subjectmarkHistoryObj->isExternal = $subject->isExternal;        
                            $subjectmarkHistory[] = $subjectmarkHistoryObj;
                        }
                    }
                    $subject->consolidated->markHistory = $subjectmarkHistory;
                    $subject->consolidated->status = $subject->isFailed ? "FAILED" : "PASSED";
                    $subjectMarkDetails = new \stdClass();
                    $subjectMarkDetails->code = $subject->subjectName;
                    $subjectMarkDetails->syllabusCode = $subject->syllabusCode;
                    $subjectMarkDetails->priority = $subject->subjectPriority;
                    $subjectMarkDetails->categoryId = $subject->subjectCatId;
                    $subjectMarkDetails->categoryName = $subject->subjectCatName;
                    $subjectMarkDetails->categoryCode = $subject->subjectCatCode;
                    $subjectMarkDetails->isInternal = $subject->isInternal;
                    $subjectMarkDetails->excludeSubjectFromTotal = $subject->excludeSubjectFromTotal;
                    $subjectMarkDetails->internalMark = $subject->internalMark;
                    $subjectMarkDetails->isInternalNull = $subject->isInternalNull;
                    $subjectMarkDetails->internalAttendanceStatus = $subject->isInternalAbsent?"ABSENT":"PRESENT";
                    $subjectMarkDetails->internalMaxMark = $subject->internalMaxMark;
                    $subjectMarkDetails->graceMark = $subject->graceMark;
                    $subjectMarkDetails->internalGrade = $subject->letterGrade;
                    $subjectMarkDetails->internalGradePoint = $subject->gradePoint;
                    $subjectMarkDetails->isInternalFailed = $subject->isInternalFailed;
                    $subjectMarkDetails->internalAttendance = $subject->isInternalAbsent?"ABSENT":"PRESENT";
                    $subjectMarkDetails->isExternal = $subject->isExternal;
                    $subjectMarkDetails->externalMark = $subject->externalMark;
                    $subjectMarkDetails->externalMaxMark = $subject->externalMaxMark;
                    $externalGrade = $this->getGradeByPercentage(($subjectMarkDetails->externalMark/$subjectMarkDetails->externalMaxMark)*$maxGradePercent, $gradeDetails[$subjectId]);
                    $externalGrade->gradePoint = $student->isPG ? $subject->externalGradePoint : $externalGrade->gradePoint;
                    $subjectMarkDetails->externalGrade = $externalGrade->letterGrade;
                    $subjectMarkDetails->externalGradePoint = $externalGrade->gradePoint;
                    $subjectMarkDetails->isExternalFailed = $subject->isExternalFailed;
                    $subjectMarkDetails->maxGradePercent = $subject->maxGradePercent;
                    $subjectMarkDetails->maxGradePoint = $subject->maxGradePoint;
                    $subjectMarkDetails->examMonth = $subject->examMonth;
                    $subjectMarkDetails->examYear = $subject->examYear;
                    $subjectMarkDetails->monthYearOfPassing = $subject->monthYearOfPassing;
                    $subjectMarkDetails->isTheory = $subject->isTheory;
                    $subjectMarkDetails->supplyAttemptCount = $subject->supplyAttemptCount;
                    $subjectMarkDetails->credit = $subject->credit;
                    $subjectMarkDetails->creditGradePoint = $subject->creditGradePoint;
                    $subjectMarkDetails->markNeededToPass = abs($subject->markNeededToPass);
                    $subjectMarkDetails->gradePoint = $subject->gradePoint;
                    $percentageObtainedInternal = round(($maxGradePercent * $subject->internalMark / $subject->internalMaxMark), 2);
                    $percentageObtainedExternal = round(($maxGradePercent * ($subjectMarkDetails->externalMark + $subject->graceMark) / $subjectMarkDetails->externalMaxMark), 2);
                    if($student->batchStartYear > 2018 && $subject->isInternal && $subject->isExternal){
                        $subjectMarkDetails->wgpa = ($percentageObtainedInternal + (4 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                        $subjectMarkDetails->wgpa = round($subjectMarkDetails->wgpa, 2) ?? 0;
                    }else if ($subject->isInternal && $subject->isExternal) {
                        $subjectMarkDetails->wgpa = ($percentageObtainedInternal + (3 * $percentageObtainedExternal)) / $subject->maxGradePoint;
                        $subjectMarkDetails->wgpa = round($subjectMarkDetails->wgpa, 2) ?? 0;
                    }
                    else if ($subject->isInternal){
                        $subjectMarkDetails->wgpa = round($percentageObtainedInternal, 2) ?? 0;
                    }
                    else if ($subject->isExternal){
                        $subjectMarkDetails->wgpa = round($percentageObtainedExternal, 2) ?? 0;
                    }
                    $subjectMarkDetails->grade = $subject->grade;
                    $subjectMarkDetails->class = $subject->className ? $subject->className : "";
                    $subjectMarkDetails->creditxMark = $subject->creditxMark;
                    $subjectMarkDetails->markObtained = $subject->totalMark;
                    $subjectMarkDetails->totalMarks = $subject->totalMaxMark;
                    $subjectMarkDetails->isFailed = $subject->isFailed;
                    $subjectMarkDetails->percentageObtainedExternal = $percentageObtainedExternal;
                    $subjectMarkDetails->percentageObtainedInternal = $percentageObtainedInternal;
                    $subjectMarkDetails->internalPassPercentage = $subject->internalPassCriteria;
                    $subjectMarkDetails->externalPassPercentage = $subject->externalPassCriteria;
                    $subjectMarkDetails->aggregatePassPercentage = $subject->overallPassCriteria;
                    $subjectMarkDetails->attendance = $subject->externalAttendanceStatus;
                    $subjectMarkDetails->latestExamYear = date("Y",strtotime("01 $subject->monthYearOfPassing"));
                    $subjectMarkDetails->latestExamMonth = date("m",strtotime("01 $subject->monthYearOfPassing"));
                    $subjectMarkDetails->latestExamType = $subject->examRegTypeOfPassing;
                    $subjectMarkDetails->attendanceStatus = $subject->isAbsent ; 
                    $subjectMarkDetails->internalMark = $subject->internalMark;
                    $subjectMarkDetails->internalMaxMark = $subject->internalMaxMark;
                    $subjectMarkDetails->internalResultStatus = $subject->isInternalFailed ? "FAILED" : "PASSED";
                    $subjectMarkDetails->externalMark = $subject->externalMark;
                    $subjectMarkDetails->externalMaxMark = $subject->externalMaxMark;
                    $subjectMarkDetails->externalResultStatus = $subject->isExternalFailed ? "FAILED" : "PASSED";
                    $subjectMarkDetails->maxGradePoint = $subject->maxGradePoint;
                    $subjectMarkDetails->maxGradePercentage = $subject->maxGradePercent;
                    $subject->consolidated->markDetails = $subjectMarkDetails;
                    $semMarks->consolidated->wgpa += $subjectMarkDetails->wgpa;
                }
                $totalCreditxGradePoint = array_sum(array_column($semMarks->subject,'creditGradePoint'));
                $semMarks->sgpa = $totalCreditxGradePoint / $semMarks->credit;
                $semMarks->creditGradePoint = $totalCreditxGradePoint;
                $semGradeObject = new \stdClass();
                $semGradeObject->groupId = $request->groupId;
                $semGradeObject->academicTermId = $semId;
                $semesterGradeDetials = $this->getSemesterGradeDetials($semGradeObject, round(($semMarks->isFailed ? 0 : $semMarks->sgpa), 2));
                $semMarks->grade = $semesterGradeDetials->letterGrade;
                $semMarks->class = $semesterGradeDetials->className;
                
                $semMarks->consolidated->noOfArrears = $semMarks->arrears ? $semMarks->arrears : 0;
                $semMarks->consolidated->supplyAttemptCount = $semMarks->supplyAttemptCount ? $semMarks->supplyAttemptCount : 0;
                $semMarks->consolidated->totalMarks = $semMarks->totalMarks ? $semMarks->totalMarks : 0;
                $semMarks->consolidated->percentage = ($semMarks->totalMarks / $semMarks->examTotalMarks) * 100;
                $semMarks->consolidated->grade = $semMarks->grade ? $semMarks->grade : "";
                $semMarks->consolidated->class = $semMarks->class ? $semMarks->class : "";
                $semMarks->consolidated->sgpa = $student->batchStartYear > 2018 ? round($semMarks->sgpa, 3) : round($semMarks->sgpa, 2);
                // without Gracemark
                $semMarks->consolidated->sgpaWithoutGracemark = $studentDetailsWithoutGracemark->batchStartYear > 2018 ? round($studentDetailsWithoutGracemark->semMarks[$semId]->sgpa, 3) : round($studentDetailsWithoutGracemark->semMarks[$semId]->sgpa, 2);
                $semMarks->consolidated->rawSgpaWithoutGracemark = $studentDetailsWithoutGracemark->semMarks[$semId]->rawSgpa;
                $semMarks->consolidated->rawSgpa = $semMarks->rawSgpa;
                $semMarks->consolidated->status = $semMarks->isFailed ? "FAILED" : "PASSED";
                
                $semMarkDetails = new \stdClass();
                $semMarkDetails->noOfChancesTaken = max(array_column(array_column($semMarks->subject,"consolidated"),"noOfChancesTaken"));
                $semMarkDetails->id = $semMarks->consolidated->academicTermId;
                $semMarkDetails->name = $semMarks->semName;
                $semMarkDetails->credit = $semMarks->credit;
                $semMarkDetails->creditGradePoint = $semMarks->creditGradePoint;
                $semMarkDetails->latestExamMonth = $semMarks->lastExamMonth;
                $semMarkDetails->latestExamYear = $semMarks->lastExamYear;
                $semMarkDetails->latestExamType = $semMarks->lastExamReg;
                $semMarkDetails->arrearCount = $semMarks->consolidated->noOfArrears;
                $semMarkDetails->supplyAttemptCount = $semMarks->consolidated->supplyAttemptCount;
                $semMarkDetails->sgpa = $semMarks->consolidated->sgpa;
                $semMarkDetails->rawSgpa = $semMarks->consolidated->rawSgpa;
                $semMarkDetails->wgpa = $semMarks->consolidated->wgpa ?? 0;
                $semMarkDetails->gradePoint = $semMarks->gradePoint;
                $semMarkDetails->grade = $semMarks->consolidated->grade;
                $semMarkDetails->class = $semMarks->consolidated->class;
                $semMarkDetails->percentage = $semMarks->consolidated->percentage;
                $semMarkDetails->creditxMark = $semMarks->creditxMark;
                $semMarkDetails->markObtained = $semMarks->totalMarks;
                $semMarkDetails->totalMarks = $semMarks->examTotalMarks;
                $semMarkDetails->passPercentage = $student->aggregatePassCriteria;
                $semMarkDetails->isFailed = $semMarks->isFailed;
                $semMarks->consolidated->markDetails = $semMarkDetails;
                if ($student->isPG == 1) {
                        $semMarks->creditGradePoint = $semMarks->consolidated->sgpa * $semMarks->credit;
                }
            }
            
            $student->creditGradePoint = array_sum(array_column($student->semMarks,"creditGradePoint"));
            $student->credit = array_sum(array_column($student->semMarks,"credit"));
            // $student->cgpa = $student->creditGradePoint / $student->credit;
            $studentObj->cgpa = $student->totalSgpaCreditGradePoint / $student->totalSgpaCredits;
            $student->rawCgpa = $student->cgpa;
            $student->cgpa = round($student->cgpa, 2);
            
            $percentageGrade = $this->getGradeByPercentage($student->cgpa, $cgpaGradeDetails);
            if (!empty ($percentageGrade)) {
                $student->grade = $percentageGrade->letterGrade;
                $student->class = $percentageGrade->className;
            }
            $student->consolidated->noOfArrears = $student->totalArrears ? $student->totalArrears : 0;
            $student->consolidated->supplyAttemptCount = $student->supplyAttemptCount ? $student->supplyAttemptCount : 0;
            $student->consolidated->totalMark = $student->totalMarkObtained ? $student->totalMarkObtained : 0;
            $student->consolidated->percentage = ($student->totalMarkObtained / $student->totalMark) * 100;
            $student->consolidated->grade = $student->grade ? $student->grade : "";
            $student->consolidated->cgpa = $student->cgpa ? $student->cgpa : 0;
            $student->consolidated->rawCgpa = $student->rawCgpa ?? 0;
            
            // without gracemark
            $student->consolidated->cgpaWithoutGracemark = $studentDetailsWithoutGracemark->cgpa;
            $student->consolidated->rawCgpaWithoutGracemark = $studentDetailsWithoutGracemark->rawCgpa;
            
            $student->consolidated->class = $student->class ? $student->class : "";
            $student->consolidated->status = $student->isFailed ? "FAILED" : "PASSED";
            $studentMarkDetails = new \stdClass();
            $studentMarkDetails->noOfChancesTaken = max(array_column(array_column(array_column($student->semMarks,"consolidated"),"markDetails"),"noOfChancesTaken"));
            $studentMarkDetails->credit = $student->credit;
            $studentMarkDetails->creditGradePoint = $student->creditGradePoint;
            $studentMarkDetails->latestExamYear = $student->lastExamYear;
            $studentMarkDetails->latestExamMonth = $student->lastExamMonth;
            $studentMarkDetails->latestExamType = $student->lastExamReg;
            $studentMarkDetails->totalMaxMark = $student->totalMark;
            $studentMarkDetails->arrearCount = $student->totalArrears;
            $studentMarkDetails->supplyAttemptCount = $student->supplyAttemptCount;
            $studentMarkDetails->credit = $student->credit;
            $studentMarkDetails->creditGradePoint = $student->creditGradePoint;
            $studentMarkDetails->markObtained = $student->totalMarkObtained;
            $studentMarkDetails->totalMarks = $student->totalMark;
            $studentMarkDetails->isFailed = $student->isFailed;
            $studentMarkDetails->cgpa = $student->cgpa;
            $studentMarkDetails->rawCgpa = $student->rawCgpa;
            $studentMarkDetails->cgpaWithoutGracemark = $studentDetailsWithoutGracemark->cgpa;
            $studentMarkDetails->rawCgpaWithoutGracemark = $studentDetailsWithoutGracemark->rawCgpa;
            // $studentMarkDetails->wgp = $student->wgp;
            $studentMarkDetails->wgpa = $student->wgpa ?? 0;
            $studentMarkDetails->gradePoint = $student->gradePoint;
            $studentMarkDetails->creditxMark = $student->creditxMark;
            $studentMarkDetails->grade = $student->grade;
            $studentMarkDetails->class = $student->class;
            $studentMarkDetails->creditxMark = $student->creditxMark;
            $student->consolidated->markDetails = $studentMarkDetails;
        }
        return $studentDetails;
    }
    protected function getStudentSubjectGradeDetailsForMarkHistory($request, $subject, $semId, $markHistory)
    {
        $schemeType = "PERCENTAGE";
        $passCriteriaArrayOfSubject = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($subject->id, $schemeType);
        $searchRequest = new \stdClass();
        $searchRequest->groupId = $request->groupId;
        $searchRequest->academicTermId = $semId;
        $searchRequest->academicPaperSubjectId = $subject->academicPaperSubjectId;
        $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
        $gradeDetails = current($subjectGradeSchemeArray)->grades;
        $maxGradePercent = $gradeDetails[0]->rangeTo;
        $checkPassPercentCriteria = new \stdClass(); 
        $checkPassPercentCriteria->isInternal = $subject->isInternal;
        $checkPassPercentCriteria->internalMaxMark = $subject->internalMaxMark;
        
        $checkPassPercentCriteria->isExternal = $subject->isExternal;
        $checkPassPercentCriteria->externalMaxMark = $subject->externalMaxMark;
        $checkPassPercentCriteria->internalMark = round($subject->internalMark);
        // $checkPassPercentCriteria->considerOverallPassCriteriaOnly = $considerOverallPassCriteriaOnly;
        $checkPassPercentCriteria->passPercentConfig = $passCriteriaArrayOfSubject;
        $checkPassPercentCriteria->externalMark = $markHistory->mark;
        $isFailedForTheSubject = $this->checkIsFailedByPassPercentCriteria ( $checkPassPercentCriteria );
        if ( $isFailedForTheSubject ) {
            $percentageObtained = 0;
            // $semesterGradePercentObtained = 0;
        }
        else {
            $percentageObtained = $maxGradePercent * (round($subject->internalMark) + $markHistory->mark) / ($subject->externalMaxMark + $subject->internalMaxMark);
            $percentageObtained = round($percentageObtained, 2);
           
            // $semesterGradePercentObtained = $maxSemesterGradePercent * $studentExamTotal / $examTotal;
            // $semesterGradePercentObtained = round($semesterGradePercentObtained, 2);
        }
        $grade = $this->getGradeByPercentage($percentageObtained, $gradeDetails);
        if (!empty ($grade)) {
            $creditGradePoint = ($subject->credit * $grade->gradePoint);
            if ($grade->failStatus == 1) {
                $isFailedForTheSubject = 1;
            }
        }
        $grade->isFailed = $isFailedForTheSubject;
        $grade->creditGradePoint = $creditGradePoint;
        return $grade;
    }
    protected function getGradeByPercentage($percentage, $gradeDetails)
    {
        foreach ($gradeDetails as $grade) {
            if ($grade->rangeFrom <= $percentage && $grade->rangeTo >= $percentage) {
                return $grade;
            }
        }
        return null;
    }
    protected function getStudentImprovementExamDetailsForThisExam($academicPaperSubjectId, $studentId, $improveExamDetails)
    {
        $examMark = null;
        foreach ($improveExamDetails as $improveExam) {
            if ($improveExam->subject->academicPaperSubjectId == $academicPaperSubjectId) {
                foreach ($improveExam->studentMarks as $studentMarks) {
                    if ($studentMarks->student->studentId == $studentId) {
                        $examMark = $studentMarks;
                        $examMark->assessmentId = $improveExam->assessmentId;
                        $examMark->oeExamId = $improveExam->oeExamId;
                        $examMark->examRegistrations = $improveExam->examRegistrations;
                    }
                }
            }
        }
        return $examMark;
    }
    protected function getStudentExamDetails($assessmentId, $studentId, $examDetails)
    {
        $examMark = null;
        foreach ($examDetails as $exam) {
            if ($exam->assessmentId == $assessmentId) {
                foreach ($exam->studentMarks as $studentMarks) {
                    if ($studentMarks->student->studentId == $studentId) {
                        $examMark = $studentMarks;
                        $examMark->assessmentId = $exam->assessmentId;
                        $examMark->examRegistrations = $exam->examRegistrations;
                    }
                }
            }
        }
        return $examMark;
    }
    public function getSupplyMarkHistory ($academicPaperSubjectId, $studentId, $supplyExamDetails) {
        $supplyExamMarks = [];
        foreach ($supplyExamDetails as $supplyExam) {
            if ($supplyExam->subject->academicPaperSubjectId == $academicPaperSubjectId) {
                foreach ($supplyExam->studentMarks as $studentMarks) {
                    if ($studentMarks->student->studentId == $studentId) {
                        $supplyExamMark = new \stdClass();
                        $supplyExamMark->id = $supplyExam->examRegistrations->examRegistrationId;
                        $supplyExamMark->assessmentId = $supplyExam->assessmentId;
                        $supplyExamMark->oeExamId = $supplyExam->oeExamId;
                        $supplyExamMark->mark = $studentMarks->externalMark;
                        $supplyExamMark->externalAttendanceStatus = $studentMarks->externalAttendanceStatus;
                        $supplyExamMark->examMonth = $supplyExam->examRegistrations->month;
                        $supplyExamMark->examYear = $supplyExam->examRegistrations->year;
                        $supplyExamMark->supplyName = $supplyExam->examRegistrations->name;
                        $supplyExamMarks[] = $supplyExamMark;
                        break;
                    }
                }
            }
        }
        return $supplyExamMarks;
    }
    public function checkIsFailedByPassPercentCriteria ( $checkPassPercentCriteria ) {
        $studentExamTotal = 0;
        $examTotal = 0;
        $isFailed = 0;
        $internalPassCriteria = $externalPassCriteria = $overallPassCriteria  = null;
        if ($checkPassPercentCriteria->passPercentConfig->internalPassCriteria) {
            $internalPassCriteria = (float) $checkPassPercentCriteria->passPercentConfig->internalPassCriteria;
        }
        if ($checkPassPercentCriteria->passPercentConfig->externalPassCriteria) {
            $externalPassCriteria = (float) $checkPassPercentCriteria->passPercentConfig->externalPassCriteria;
        }
        if ($checkPassPercentCriteria->passPercentConfig->overallPassCriteria) {
            $overallPassCriteria = (float) $checkPassPercentCriteria->passPercentConfig->overallPassCriteria;
        }
        
        if ($checkPassPercentCriteria->isInternal) {
            $studentExamTotal = round($checkPassPercentCriteria->internalMark);
            $examTotal = $checkPassPercentCriteria->internalMaxMark;
            if (!empty ($internalPassCriteria)) {
                $internalPercent = $checkPassPercentCriteria->internalMaxMark ? (100 * $checkPassPercentCriteria->internalMark / $checkPassPercentCriteria->internalMaxMark) : 0;
                if ( $checkPassPercentCriteria->considerOverallPassCriteriaOnly == 0 ) {
                    $isFailed = $internalPassCriteria <= $internalPercent ? $isFailed : 1;
                }
            }
        }
        if ($checkPassPercentCriteria->isExternal) {
            $studentExamTotal += round($checkPassPercentCriteria->externalMark);
            $examTotal += $checkPassPercentCriteria->externalMaxMark;
            if (!empty ($externalPassCriteria)) {
                $externalPercent = $checkPassPercentCriteria->externalMaxMark ? (100 * 
                    $checkPassPercentCriteria->externalMark / $checkPassPercentCriteria->externalMaxMark) : 0;
                if ( $checkPassPercentCriteria->considerOverallPassCriteriaOnly == 0 ) {
                    $isFailed = $externalPassCriteria <= $externalPercent ? $isFailed : 1;
                }
            }
        }
        if (!empty ($overallPassCriteria)) {
            if (empty($checkPassPercentCriteria->studentExamTotal))
                $overallPercent = $examTotal ? 100 * $studentExamTotal / $examTotal : 0;
            else
                $overallPercent = $checkPassPercentCriteria->totalMaxMark ? 100 * $checkPassPercentCriteria->studentExamTotal / $checkPassPercentCriteria->totalMaxMark : 0;
            $isFailed = $overallPassCriteria <= $overallPercent ? $isFailed : 1;
        }
        
        return $isFailed;
    }
    public function getSemesterGradeDetials($searchReq, $sgpa)
    {
        $searchRequest = new \stdClass();
        $searchRequest->groupId = $searchReq->groupId;
        $searchRequest->academicTermId = $searchReq->academicTermId;
        $searchRequest->requestType = "SEMESTER";
        $semesterGradeDetails = reset(GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest))->grades;
        $semMarkGrade =  $this->getGradeByPercentage($sgpa, $semesterGradeDetails);
        return $semMarkGrade;
    }
    /**
     * Get Students supplementary mark report
     */
    public function getStudentsSupplyMarkReport ( $request, $supplyExamDetails = null ) {
        $students = [];
        $subjects = [];
        $passCriteriaArray = [];
        $includeImprovement = false;
        $includeImprovement = $request->includeImprovement ?? false;
        
        if( empty ( $supplyExamDetails ) ){
            ;
            $request->examRegistrationType = ExamRegistrationTypeConstants::SUPPLEMENTARY;
            $supplyExamDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
        }
        if ( !empty ( $supplyExamDetails ) ) {
            $examMonth = current($supplyExamDetails)->examRegistrations->month;
            $examYear = current($supplyExamDetails)->examRegistrations->year;
            
            $request->examYear = $examYear; 
            $request->examMonth = $examMonth; 
            $studentObj = null;
            /** Getting the mark details of that batch **/
            if ( empty ( $studentObj ) ) {
                $request->examRegistrationType = ExamType::REGULAR;
                $request->examRegistrationId = "";
                $examDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
                $request->supplementaryYearUpperLimit = $examYear; 
                $request->supplementaryMonthUpperLimit = $examMonth; 
                $studentObj = $this->getStudentsOverallMarkReport($request, $examDetails);
                $request->supplementaryYearUpperLimit = ''; 
                $request->supplementaryMonthUpperLimit = ''; 
            }
            if ( $request->considerModerationMark ) {
                $request->examRegistrationType = "";
                $request->requestType = "MODERATION";
                $moderationMarkDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
            }
            if ( $request->considerGraceMark ) {
                $request->examRegistrationType = "";
                $request->requestType = "GRACEMARK";
                $graceMarkDetails = StudentsOverAllMarkReportService::getInstance()->getStudentExamMarkDetails($request);
            }
            foreach ($supplyExamDetails as $examDetail) {
                $totalMaxMark = 0;
                $academicPaperSubjectId = $examDetail->subject->academicPaperSubjectId;
                $batchId = $examDetail->batch->id;
                $academicTermId = $examDetail->semester->academicTermId;
                $courseTypeId = $examDetail->batch->courseTypeId;
                $regularSubjectDetails = $studentObj[$request->studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId];
                $schemeType = "PERCENTAGE";
                $passCriteriaArray[$academicPaperSubjectId] = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($academicPaperSubjectId, $schemeType);
    
    
                $searchRequest = new \stdClass();
                $searchRequest->groupId = $request->groupId;
                $searchRequest->academicTermId = $academicTermId;
                $searchRequest->academicPaperSubjectId = $examDetail->subject->academicPaperSubjectId;
                $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequest);
                $gradeDetails = current($subjectGradeSchemeArray)->grades;
                $maxGradePercent = $gradeDetails[0]->rangeTo;
                $considerOverallPassCriteriaOnly = 0;
                if ( $examDetail->subject->subjectType == ExamSubjectTypeConstants::OPEN_ELECTIVE ||
                    $examDetail->subject->subjectType == ExamSubjectTypeConstants::FOUNDATION_COURSE ||
                    $examDetail->subject->subjectType == ExamSubjectTypeConstants::TERM_PAPER ) {
                    $considerOverallPassCriteriaOnly = 1;
                }
                /** Object checking whether a student is passed for a subject by the pass percent criteria **/
                $checkPassPercentCriteria = new \stdClass();
                $checkPassPercentCriteria->isInternal = $examDetail->subject->isInternal;
                $checkPassPercentCriteria->internalMaxMark = $examDetail->internalMaxMark;
                $checkPassPercentCriteria->isExternal = $examDetail->subject->isExternal;
                $checkPassPercentCriteria->externalMaxMark = $examDetail->externalMaxMark;
                $checkPassPercentCriteria->considerOverallPassCriteriaOnly = $considerOverallPassCriteriaOnly;
                /** For getting the supplementary subject details **/
                $subjects[$academicPaperSubjectId]->id = $academicPaperSubjectId;
                $subjects[$academicPaperSubjectId]->subjectOrder = $examDetail->subject->subjectOrder;
                
                $subjects[$academicPaperSubjectId]->subjectName = $examDetail->subject->subjectName;
                $subjects[$academicPaperSubjectId]->subjectDesc =  filter_var(html_entity_decode($examDetail->subject->subjectDesc), FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
                $subjects[$academicPaperSubjectId]->syllabusCode = $examDetail->subject->syllabusCode;
                $subjects[$academicPaperSubjectId]->subjectCatId = $examDetail->subject->subjectCatId;
                $subjects[$academicPaperSubjectId]->internalMaxMark = $examDetail->internalMaxMark;
                $subjects[$academicPaperSubjectId]->externalMaxMark = $examDetail->externalMaxMark;
                $subjects[$academicPaperSubjectId]->supplyAssessmentId= $examDetail->assessmentId;
                if ($examDetail->subject->isInternal == 1) {
                    $totalMaxMark += $examDetail->internalMaxMark;
                }
                if ($examDetail->subject->isExternal == 1) {
                    $totalMaxMark += $examDetail->externalMaxMark;
                }
                $subjects[$academicPaperSubjectId]->totalMaxMark = $totalMaxMark;
                $subjects[$academicPaperSubjectId]->excludeSubjectFromTotal = $examDetail->subject->excludeSubjectFromTotal;
                /** Subject details ends **/
                
                foreach ($examDetail->studentMarks as $studentMark) {
                    $isFailed = null;
                    $examTotal = 0;
                    $studentExamTotal = 0;
                    $studentId = $studentMark->student->studentId;
                    if ( $request->considerRevaluation) {
                        $revalRequest = new \stdClass();
                        $revalRequest->studentId = $studentId;
                        $revalRequest->assessmentId = $examDetail->assessmentId;
                        $revalRequest->orderByHighestMark = 1;
                        $studentRevaluationDetails = StudentsOverAllMarkReportService::getInstance()->getStudentFinalizedRevaluationMark($revalRequest);
                        if($studentRevaluationDetails){
                            $studentRevaluationDetail = current(current($studentRevaluationDetails)->students);
                            if($studentRevaluationDetail->revaluationMark){
                                $studentMark->externalMark = $studentRevaluationDetail->revaluationMark;
                            }
                        }
                    }
                    if ( $request->considerModerationMark ) {
                        $studentModerationMark = $this->getStudentExamDetails($examDetail->assessmentId, $studentId, $moderationMarkDetails);
                        if($studentModerationMark){
                            $studentMark->externalMark += $studentModerationMark->externalMark;
                        }
                    }
                    if ( $request->considerGraceMark ) {
                        $studentGraceMark = $this->getStudentExamDetails($examDetail->assessmentId, $studentId, $graceMarkDetails);
                        if($studentGraceMark){
                            $studentMark->externalMark += $studentGraceMark->externalMark;
                        }
                    }
                    $checkPassPercentCriteria->internalMark = round($studentMark->internalMark, 2 );
                    $checkPassPercentCriteria->passPercentConfig = $passCriteriaArray[$academicPaperSubjectId];
                    $checkPassPercentCriteria->externalMark = round ( $studentMark->externalMark, 2 );
                    $isFailed = $this->checkIsFailedByPassPercentCriteria ( $checkPassPercentCriteria );
                    /** code ends **/
                    
                    $student = $students[$studentId];
                    $studentSemMark = $student->semMarks[$academicTermId];
                    $studentSubject = $studentSemMark->subject[$academicPaperSubjectId];
                    
                    if (empty($studentSubject)){
                        $studentSubject = json_decode(json_encode($studentObj[$studentId]->semMarks[$academicTermId]->subject[$academicPaperSubjectId]));
                        unset($studentSubject->markHistory);
                    }
                    if (empty($studentSemMark)){
                        $studentSemMark = json_decode(json_encode($studentObj[$studentId]->semMarks[$academicTermId]));
                        unset($studentSemMark->subject);
                    }
                    if (empty($student)){
                        $student = json_decode(json_encode($studentObj[$studentId]));
                        unset($student->semMarks);
                    }
                    $studentSemMark->supplyCredit = empty($studentSemMark->supplyCredit) ? 0 : $studentSemMark->supplyCredit;
                    
                    $student->id = $studentId;
                    $student->name = $studentMark->student->studentName;
                    $student->regNo = $studentMark->student->regNo;
                    $student->examRegType = $studentMark->studentExamRegType;
                    
                    /** Subject's common details **/
                    $studentSubject->code = $examDetail->subject->subjectCode;
                    $studentSubject->name = $examDetail->subject->subjectName;
                    $studentSubject->desc =  filter_var(html_entity_decode($examDetail->subject->subjectDesc), FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
                    $studentSubject->syllabusCode = $examDetail->subject->syllabusCode;
                    $studentSubject->subjectCatId = $examDetail->subject->subjectCatId;
                    $studentSubject->excludeSubjectFromTotal = $examDetail->subject->excludeSubjectFromTotal;
                    $studentSubject->credit = round ( $examDetail->subject->credit, 2 );
                    $studentSubject->subjectOrder = $examDetail->subject->subjectOrder;
                    /** Subject's common details ends here */
                    
                    $studentSubject->id = $academicPaperSubjectId;
                    $studentSubject->isExempted = $studentMark->isExempted;
                    $studentSubject->isAbsent = $studentMark->externalAttendanceStatus;
                    $studentSubject->isInternal = $examDetail->subject->isInternal;
                    $studentSubject->isInternalAbsent = $studentMark->internalAttendanceStatus;
                    $studentSubject->isExternal = $examDetail->subject->isExternal;
                    $studentSubject->supplyExamId = $examDetail->id;
                    
                    if ( $examDetail->subject->isInternal == 1 ) {
                        $internalMark = round ( $studentMark->internalMark, 2 );
                        $internalMaxMark = round ( $examDetail->internalMaxMark, 2 );
                        
                        $studentSubject->internalMark = $internalMark;
                        $studentSubject->internalMaxMark = $internalMaxMark;
                        
                        $studentExamTotal += $internalMark;
                        $examTotal += $internalMaxMark;
                    }
                    if ( $examDetail->subject->isExternal == 1 ) {
                        $externalMark = round ( $studentMark->externalMark, 2 );
                        $externalMaxMark = round ( $examDetail->externalMaxMark, 2 );
                        
                        $studentExamTotal += $externalMark;
                        $examTotal += $externalMaxMark;
                        
                        $studentSubject->externalMark = $externalMark;
                        $studentSubject->graceMark = $regularSubjectDetails->graceMark;
                        $studentSubject->externalMaxMark = $externalMaxMark;
                    }
                    $studentSubject->totalMark = $studentExamTotal;
                    
                    if ( $isFailed ) {
                        $percentageObtained = 0;
                    } else {
                        $percentageObtained = $maxGradePercent * $studentExamTotal / $examTotal;
                        $percentageObtained = round($percentageObtained, 2);
                    }
                    $grade = $this->getGradeByPercentage($percentageObtained, $gradeDetails);
       
                    $internalMarkPer = $externalMarkPer = 0;
                    if ($student->isPG == 1) {
                        $x = 1;
                        if ($examDetail->subject->isInternal) {
                            $internalMarkPer = round($maxGradePercent * $studentSubject->internalMark / $examDetail->internalMaxMark, 2);
                        }
                        if ($examDetail->subject->isExternal) {
                            $externalMarkPer = round($maxGradePercent * $studentSubject->externalMark / $examDetail->externalMaxMark, 2); 
                        }
        
                        if ($examDetail->subject->isInternal && $examDetail->subject->isExternal) {
                            $gradePoint = round((($x * $internalMarkPer) + ( ($maxGradePercent-$x) * $externalMarkPer ) ) / $maxGradePercent, 2);
                        }
                        else {
                            $gradePoint = $internalMarkPer + $externalMarkPer;
                        }
                        if ($isFailed) {
                            $gradePoint = 0;
                        }
                        $grade = $this->getGradeByPercentage($gradePoint, $gradeDetails);
                        $grade->gradePoint = $gradePoint ?? 0;
                    }
                    if (!empty ($grade)) {
                        $creditGradePoint = ($examDetail->subject->credit * $grade->gradePoint);
                        if ($grade->failStatus == 1) {
                            $isFailed = 1;
                        }
                        $studentSubject->grade = $grade->letterGrade;
                        $studentSubject->class = $grade->className;
                        $studentSubject->gradePoint = round ( $grade->gradePoint, 2 );
                        $studentSubject->creditGradePoint = round ( $creditGradePoint, 2 );
                        $studentSubject->creditxMark = round ( $examDetail->subject->credit * $studentExamTotal, 2 );
                    }
                    else {
                        $studentSubject->grade = "";
                        $studentSubject->class = "";
                        $studentSubject->gradePoint = 0;
                        $studentSubject->creditGradePoint = 0;
                    }
                    $studentSubject->totalMaxMark = $examTotal;
                    
                    $studentSubject->isFailed = $isFailed;
                    $studentSubject->internalGradePoint = $internalMarkPer;
                    $studentSubject->externalGradePoint = $externalMarkPer;
                    $studentSemMark->isFailed = $isFailed ? 1 : (empty($studentSemMark->isFailed) ? 0 : $studentSemMark->isFailed);
                    $studentSemMark->regularExamRegId = $examDetail->regularExamRegId;
                    $studentSemMark->supplyCredit += $studentSubject->credit;
                    $student->isFailed = $isFailed ? 1 : (empty($student->isFailed) ? 0 : $student->isFailed);
                    $studentSemMark->subject[$academicPaperSubjectId] = $studentSubject;
                    $student->semMarks[$academicTermId] = $studentSemMark;
                    $students[$studentId] = $student;
                }
            }
            $completedStatus = "COMPLETED";
            $incompleteStatus = "INCOMPLETE";
            $failStatus = "FAIL";
            foreach ( $students as $student ) {
                $sgpa = null;
                $studentId = $student->id;
                $semId = $request->semId;
                $student->sgpa = '';
                $studentOverallMarkReport = $studentObj[$studentId];
                
                /** Case when the student passed in all the written supply **/
                if ( !$student->isFailed ) {
                    
                    /**
                     * Here we are considering the mark details of 1 semester
                     * So, total arrears will be the no. of arrears in that sem
                     */
                    if ( $studentObj[$studentId]->totalArrears > 0 || $studentObj[$studentId]->isFailed ) {
                        $student->status = $incompleteStatus;
                    }
                    else {
                        $student->status = $completedStatus;
                        
                        if ($examYear < $studentObj[$studentId]->lastExamYear) {
                            $student->status = $incompleteStatus;
                        } 
                        else if ($examYear == $studentObj[$studentId]->lastExamYear && $examMonth <
                            $studentObj[$studentId]->lastExamMonth) {
                            $student->status = $incompleteStatus;
                        }
                        else {
                            $sgpa = round($studentObj[$studentId]->semMarks[$academicTermId]->sgpa, 2);
                            $student->semMarks[$academicTermId]->sgpa = $sgpa;
                            $student->sgpa = $sgpa;
                        }
                    }
                }
                else {
                    $student->status = $failStatus;
                }
                $student->semMarks[$academicTermId]->grade = $studentOverallMarkReport->semMarks[$academicTermId]->grade;
                $student->semMarks[$academicTermId]->class = $studentOverallMarkReport->semMarks[$academicTermId]->class;
                $student->semMarks[$academicTermId]->credit = $studentOverallMarkReport->semMarks[$academicTermId]->credit;
                $student->semMarks[$academicTermId]->creditGradePoint = $studentOverallMarkReport->semMarks[$academicTermId]->creditGradePoint;
                $student->semMarks[$academicTermId]->gradePoint = $studentOverallMarkReport->semMarks[$academicTermId]->gradePoint;
                $student->semMarks[$academicTermId]->supplyCreditGradePoint = array_sum(array_column($student->semMarks[$academicTermId]->subject, "creditGradePoint"));
                $student->semMarks[$academicTermId]->supplyGradePoint = array_sum(array_column($student->semMarks[$academicTermId]->subject, "gradePoint"));
                $student->semMarks[$academicTermId]->supplyTotalMarks = array_sum(array_column($student->semMarks[$academicTermId]->subject, "totalMark"));
                $student->semMarks[$academicTermId]->supplyTotalMaxMarks = array_sum(array_column($student->semMarks[$academicTermId]->subject, "totalMaxMark"));
                $student->semMarks[$academicTermId]->supplyCreditxMarks = array_sum(array_column($student->semMarks[$academicTermId]->subject, "creditxMark"));
                $student->overAllMarkDetails = $studentOverallMarkReport;
                $student->semMarks[$academicTermId]->supplyRegularTotalMarks = array_sum(array_column($studentOverallMarkReport->semMarks[$academicTermId]->subject, "totalMark"));
                $student->semMarks[$academicTermId]->supplyRegularGradePoint = array_sum(array_column($studentOverallMarkReport->semMarks[$academicTermId]->subject, "gradePoint"));
            }
            usort($students, function ($a, $b) {
                return $a->regNo > $b->regNo;
            });
        }
        
        $details = new \stdClass();
        $details->students = $students;
        
        return $details->students;
    }
    
   
}