Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 28
CRAP
0.00% covered (danger)
0.00%
0 / 2553
RegularExamReportService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 28
194040.00
0.00% covered (danger)
0.00%
0 / 2553
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getCurrentRegularExamReportUITypes
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 64
 getBatchWiseSuccessRateDetails
0.00% covered (danger)
0.00%
0 / 1
1332.00
0.00% covered (danger)
0.00%
0 / 260
 moderateBatchWiseSuccessRateDetails
0.00% covered (danger)
0.00%
0 / 1
702.00
0.00% covered (danger)
0.00%
0 / 74
 getSubjectWiseSuccessRateDetails
0.00% covered (danger)
0.00%
0 / 1
552.00
0.00% covered (danger)
0.00%
0 / 179
 moderateSubjectWiseSuccessRateDetails
0.00% covered (danger)
0.00%
0 / 1
380.00
0.00% covered (danger)
0.00%
0 / 61
 getAllResultAnalysisTabMenus
0.00% covered (danger)
0.00%
0 / 1
342.00
0.00% covered (danger)
0.00%
0 / 110
 getRegularResultAnalysissearchFilterInputs
0.00% covered (danger)
0.00%
0 / 1
30.00
0.00% covered (danger)
0.00%
0 / 57
 getRegularExamStatisticalResultAnalysisInputs
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 43
 getRegularExamSubjectWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 109
 getSubjectWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
992.00
0.00% covered (danger)
0.00%
0 / 92
 getRegularExamCourseWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
56.00
0.00% covered (danger)
0.00%
0 / 109
 getCourseWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
812.00
0.00% covered (danger)
0.00%
0 / 86
 getRegularExamStudentWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 45
 getStudentWiseResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 44
 getRegularExamGradeReportResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 55
 getGradeReportResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 41
 getRegularExamStatisticalAnalysis
0.00% covered (danger)
0.00%
0 / 1
600.00
0.00% covered (danger)
0.00%
0 / 156
 getRegularExamSemesterWiseAnalysis
0.00% covered (danger)
0.00%
0 / 1
272.00
0.00% covered (danger)
0.00%
0 / 107
 getAllStudentDetailsListForSemesterWise
0.00% covered (danger)
0.00%
0 / 1
1722.00
0.00% covered (danger)
0.00%
0 / 116
 getAllGradeSchemesDetailsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 41
 getAllSubjectGradeSchemesDetailsByExamRegistration
0.00% covered (danger)
0.00%
0 / 1
132.00
0.00% covered (danger)
0.00%
0 / 41
 getAllRegistredStudentOverAllDetails
0.00% covered (danger)
0.00%
0 / 1
600.00
0.00% covered (danger)
0.00%
0 / 214
 getExamValuationReport
0.00% covered (danger)
0.00%
0 / 1
306.00
0.00% covered (danger)
0.00%
0 / 102
 getFailedStudentListReport
0.00% covered (danger)
0.00%
0 / 1
420.00
0.00% covered (danger)
0.00%
0 / 96
 getRegularExamSubjectProgramCombainedResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
156.00
0.00% covered (danger)
0.00%
0 / 82
 getSubjectProgramCombainedResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
240.00
0.00% covered (danger)
0.00%
0 / 50
 getRegularExamCasteCategoryResultAnalysis
0.00% covered (danger)
0.00%
0 / 1
110.00
0.00% covered (danger)
0.00%
0 / 117
<?php
namespace com\linways\ec\core\service;
use com\linways\ec\core\request\SearchRuleRequest;
use com\linways\ec\core\service\RuleService;
use com\linways\base\util\MakeSingletonTrait;
use com\linways\ec\core\exception\ExamControllerException;
use com\linways\core\ams\professional\service\ReligionService;
use com\linways\core\ams\professional\service\AdmissionService;
use com\linways\core\ams\professional\service\ReservationStudentsService;
use com\linways\core\ams\professional\service\CampusTypeService;
use com\linways\base\util\TwigRenderer;
use com\linways\core\ams\professional\util\PdfUtil;
use com\linways\core\ams\professional\service\CommonService;
use com\linways\ec\core\service\ExamRegistrationService;
use com\linways\ec\core\request\SearchExamRegistrationRequest;
use com\linways\ec\core\service\ExamRegistrationSubjectService;
use com\linways\core\ams\professional\service\CourseTypeService;
use com\linways\core\ams\professional\util\CommonUtil;
use com\linways\core\ams\professional\constant\ExamType; 
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\base\util\SecurityUtils;
use com\linways\ec\core\request\SearchExamRegistrationBatchRequest;
use com\linways\ec\core\service\GradeSchemeService;
use com\linways\ec\core\mapper\RegularExamReportServiceMapper;
use com\linways\ec\core\dto\StudentMarkDetails;
use com\linways\ec\core\dto\exam\StudentDetails;
use com\linways\ec\core\dto\exam\AcademicTermMark;
use com\linways\ec\core\dto\exam\RegularExam;
use com\linways\ec\core\dto\exam\ExamSubject;
use com\linways\ec\core\service\MarkReportService;
use com\linways\ec\core\service\CommonExamService;
use com\linways\core\ams\professional\request\examcontroller\ConsolidatedMarkReportRequest;
use com\linways\ec\core\service\ExamValuationService;
class RegularExamReportService extends BaseService
{
    use MakeSingletonTrait;
    private function __construct() {
        $this->mapper = RegularExamReportServiceMapper::getInstance()->getMapper();
    }
     /**
     * get Current Regular Exam UI Type
     * @param $searchRequest 
     * @return $response 
     */
    public function getCurrentRegularExamReportUITypes($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try
        {
            $response = new \stdClass;
            $batchWiseSuccessRateMarkAwardedInputArray=[];
            $subjectWiseSuccessRateMarkAwardedInputArray=[];
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "BATCH_WISE_SUCCESS_RATE_RULE";
            $batchWiseSuccessRateRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            if(!empty($batchWiseSuccessRateRuleArray))
            {
                $batchWiseSuccessRateMarkAwardedInputCount = (int)$batchWiseSuccessRateRuleArray[0]->rule->MarkAwardedInputCount;
                if($batchWiseSuccessRateMarkAwardedInputCount)
                {
                    for($i=1;$i<=$batchWiseSuccessRateMarkAwardedInputCount;$i++)
                    {
                        $markAwardedInputCount = new \stdClass;
                        $markAwardedInputCount->id = $i;
                        $markAwardedInputCount->text = $i;
                        $batchWiseSuccessRateMarkAwardedInputArray[] = $markAwardedInputCount;
                    }
                }
            }
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "SUBJECT_WISE_SUCCESS_RATE_RULE";
            $subjecthWiseSuccessRateRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            if(!empty($subjecthWiseSuccessRateRuleArray))
            {
                $subjectWiseSuccessRateMarkAwardedInputCount = (int)$subjecthWiseSuccessRateRuleArray[0]->rule->MarkAwardedInputCount;
                if($subjectWiseSuccessRateMarkAwardedInputCount)
                {
                    for($i=1;$i<=$subjectWiseSuccessRateMarkAwardedInputCount;$i++)
                    {
                        $markAwardedInputCount = new \stdClass;
                        $markAwardedInputCount->id = $i;
                        $markAwardedInputCount->text = $i;
                        $subjectWiseSuccessRateMarkAwardedInputArray[] = $markAwardedInputCount;
                    }
                }
            }
            $response = new \stdClass;
            $regularExamReportJson = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_REPORT, SettingsConstents::REGULAR_EXAM_REPORTS_UI_TYPES);
            $regularExamReportObj = json_decode($regularExamReportJson);
            if($regularExamReportObj->BatchWiseSuccessRateUIType == "TEMPLATE_WITH_BATCH"){
                $response->batchWiseSuccessRate = $regularExamReportObj->BatchWiseSuccessRateUIType;
            }
            else{
                $response->batchWiseSuccessRate = "TEMPLATE_WITH_OUT_BATCH";
            }
            if($regularExamReportObj->SubjectWiseSuccessRateUIType == "TEMPLATE_WITH_SUBJECTS"){
                $response->subjectWiseSuccessRate = $regularExamReportObj->SubjectWiseSuccessRateUIType;
            }
            else{
                $response->subjectWiseSuccessRate = "TEMPLATE_WITH_OUT_SUBJECTS";
            }
            $response->subjectWiseSuccessRateMarkAwardedInputArray = $subjectWiseSuccessRateMarkAwardedInputArray;
            $response->batchWiseSuccessRateMarkAwardedInputArray = $batchWiseSuccessRateMarkAwardedInputArray;
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
    /**
     * get Batch Wise Success Rate Details
     * @param $searchRequest 
     * @return $response 
     */
    public function getBatchWiseSuccessRateDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            global $COLLEGE_NAME, $COLLEGE_LOGO_PATH;
            $examRegistrationDetailsArray = ExamRegistrationService::getInstance()->searchDetailedExamRegistrationDetails($searchRequest);
            $response = new \stdClass;
            $examRegistrationBatches = [];
            $additionalData = new \stdClass;
            $additionalData->exmRegistrationName = $examRegistrationDetailsArray[0]->name;
            $additionalData->collegeName = $GLOBALS['COLLEGE_NAME'];
            foreach($examRegistrationDetailsArray[0]->groups as $group){
                $examRegistrationBatches[] = $group->groupName;
            }
            $additionalData->batchNames = implode(" , ",$examRegistrationBatches);
            $additionalData->courseType = $examRegistrationDetailsArray[0]->groups[0]->courseTypeName;
            $additionalData->departmentName = $examRegistrationDetailsArray[0]->groups[0]->deptName;
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "SUBJECT_WISE_SUCCESS_RATE_RULE";
            $successRatRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            if(!empty($successRatRuleArray)){
                $IsConsiderFailedWhenOnlyExtrenalFailed = $successRatRuleArray[0]->rule->IsConsiderFailedWhenOnlyExtrenalFailed;
            }
            $regularExamReportJson = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_REPORT, SettingsConstents::REGULAR_EXAM_REPORTS_UI_TYPES);
            $regularExamReportObj = json_decode($regularExamReportJson);
            if($regularExamReportObj->BatchWiseSuccessRateUIType == "TEMPLATE_WITH_BATCH")
            {
                $request = new ConsolidatedMarkReportRequest();
                if ( $searchRequest->examType == "SUPPLEMENTARY" ){
                    $examMonth =  $examRegistrationDetailsArray[0]->properties->examMonth;
                    $examYear =  $examRegistrationDetailsArray[0]->properties->examYear;
                    $request->academicTermId = $examRegistrationDetailsArray[0]->groups[0]->academicTermId;
                    $request->excludeMinorHonor = 1;
                }
                else{
                    $request->examRegistrationId = $searchRequest->examRegistrationId;
                }
                $request->groupId = $searchRequest->groupId;
                $request->isFetchWithFeSubject = true;
                $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
                // $studentMarkDetails = $this->getMarkReportDummyData();
                $failedStudents=[];
                $noOfStudents=count($studentMarkDetails);
                if($studentMarkDetails){
                    // if($IsConsiderFailedWhenOnlyExtrenalFailed){
                    //     foreach($studentMarkDetails as $student){
                    //         $subjectArray = [];
                    //         $isFailedStudent=false;
                    //         foreach ( $student->academicTerms as $academicTerm ) {
                    //             foreach ( $academicTerm->subjects as $subject ){
                    //                 if($subject->isExternalFailed){
                    //                     $isFailedStudent=true;
                    //                     $subjectObj = new \stdClass;
                    //                     $subjectObj->id = $subject->id;
                    //                     $subjectObj->internalMark = $subject->internalMark;
                    //                     $subjectObj->externalMark = $subject->externalMark;
                    //                     $subjectObj->internalMaxMark = $subject->internalMaxMark;
                    //                     $subjectObj->externalMaxMark = $subject->externalMaxMark;
                    //                     $subjectObj->isInternalAbsent = $subject->isInternalAbsent;
                    //                     $subjectObj->isExternal = $subject->isExternal;
                    //                     $subjectObj->isInternal = $subject->isInternal;
                    //                     $subjectObj->isInternalFailed = $subject->isInternalFailed;
                    //                     $subjectObj->isExternalFailed = $subject->isExternalFailed;
                    //                     $subjectObj->maxGradePoint = $subject->maxGradePoint;
                    //                     $subjectObj->isFailed = $subject->isFailed;
                    //                     $subjectObj->markNeededToPass = $subject->markNeededToPass;
                    //                     $subjectArray[$subject->id] = $subjectObj;
                    //                 }
                    //             }
                    //         }
                    //         if($isFailedStudent){
                    //             $studentObj = new \stdClass;
                    //             $studentObj->studentId = $student->studentDetails->id;
                    //             $studentObj->regNo = $student->studentDetails->registerNo;
                    //             $studentObj->name = $student->studentDetails->name;
                    //             $studentObj->batchName = $student->studentDetails->batchName;
                    //             $studentObj->isFailed = $isFailedStudent;
                    //             $studentObj->subjects = $subjectArray;
                    //             $failedStudents[] = $studentObj;
                    //         } 
                    //     }
                    // }
                    // else{
                    $distinctBatchIds = [];
                    $distinctTermIds = [];
                    foreach($studentMarkDetails as $student){
                        if(!$distinctBatchIds[$student->studentDetails->batchId]){
                            $distinctBatchIds[$student->studentDetails->batchId] = $student->studentDetails->batchId;
                        }
                        foreach ( $student->academicTerms as $academicTerm ) {
                            if(!$distinctTermIds[$academicTerm->id]){
                                $distinctTermIds[$academicTerm->id] = $academicTerm->id;
                            }
                        }
                    }
                    $searchRequestForGradeScheme = new \stdClass();
                    $searchRequestForGradeScheme->groupId = array_values($distinctBatchIds);
                    $searchRequestForGradeScheme->academicTermId = array_values($distinctTermIds);
                    $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequestForGradeScheme);
                    foreach($studentMarkDetails as $studentKey => $student){
                        $studentObj = new \stdClass;
                        $studentObj->studentId = $student->studentDetails->id;
                        $studentObj->regNo = $student->studentDetails->registerNo;
                        $studentObj->name = $student->studentDetails->name;
                        $studentObj->batchName = $student->studentDetails->batchName;
                        $studentObj->isFailed = $student->isFailed;
                        $studentObj->markNeededToPassInSemester = 0;
                        $subjectArray = [];
                        foreach ( $student->academicTerms as $academicTerm ) {
                            $currentAcademicTerm = reset(array_filter($academicTerm->markHistory,function($value)use($searchRequest){
                                return $value->examRegistrationId == $searchRequest->examRegistrationId;
                            }));
                            if ( $searchRequest->examType == "SUPPLEMENTARY" ){
                                if ( empty($currentAcademicTerm) ){
                                    unset($studentMarkDetails[$studentKey]);
                                    continue;
                                }
                                foreach ( $academicTerm->subjects as $subject ){
                                    $currentSupplyChance = reset(array_filter($subject->subjectMarkHistory,function($value)use($searchRequest){
                                        return $value->examRegistrationId == $searchRequest->examRegistrationId;
                                    }));
                                    if( $currentSupplyChance ){
                                        $subject->isSupplyChance = 1;
                                        $latestMarkHistory = $currentSupplyChance;
                                    }
                                    else{
                                        $subject->markHistory = array_filter($subject->subjectMarkHistory,function($value)use($examMonth, $examYear){
                                            return $value->examYear."-".date("m", mktime(0, 0, 0, (int)$value->examMonth, 10))  <= $examYear."-".date("m", mktime(0, 0, 0, (int)$examMonth, 10)); 
                                        });
                                        usort($subject->markHistory, function($a, $b) {
                                            return ($a->examYear."-".date("m", mktime(0, 0, 0, (int)$a->examMonth, 10))) < ($b->examYear."-".date("m", mktime(0, 0, 0, (int)$b->examMonth, 10)));
                                        });
                                        usort($subject->markHistory, function($a, $b) {
                                            return ($a->externalMark < $b->externalMark); 
                                        });
                                        $latestMarkHistory = reset($subject->markHistory);
                                    }
                                    $subject->isFailed = $latestMarkHistory->resultStatus;
                                    $subject->internalMark = $latestMarkHistory->internalMark;
                                    $subject->externalMark = $latestMarkHistory->externalMark;
                                    $subject->isInternalAbsent = $latestMarkHistory->internalAttendanceStatus;
                                    $subject->isExternalFailed = $latestMarkHistory->isExternalFailed;
                                    if(  $currentSupplyChance ){
                                    }
                                    // $subject->isInternalFailed = $latestMarkHistory->isInternalFailed;
                                }
                            }
                            if($searchRequest->considerSupplementaryOnly == 'true'){
                                $failedSubjects = array_filter($academicTerm->subjects,function($value){
                                    return $value->isFailed == 'FAILED';
                                });
                                $academicTerm->subjects = $failedSubjects;
                            }
                            if($currentAcademicTerm->failedStatus == 'FAILED'){
                                foreach ( $academicTerm->subjects as $subject ){
                                    if($subject->isFailed == 'FAILED'){ 
                                        // $schemeType = "PERCENTAGE";
                                        // $passCriteriaArray[$subject->id] = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($subject->id, $schemeType);
                                        // $checkPassPercentCriteria = new \stdClass();
                                        // $checkPassPercentCriteria->isInternal = $subject->isInternal;
                                        // $checkPassPercentCriteria->internalMaxMark = $subject->internalMaxMark;
                                        // $checkPassPercentCriteria->isExternal = $subject->isExternal;
                                        // $checkPassPercentCriteria->externalMaxMark = $subject->externalMaxMark;
                                        // $checkPassPercentCriteria->internalMark = round($subject->internalMark, 2 );
                                        // $checkPassPercentCriteria->passPercentConfig = $passCriteriaArray[$subject->id];
                                        // $checkPassPercentCriteria->externalMark = round ( $subject->externalMark, 2 );
                                        // $subjectPassCriteria = CommonExamService::getInstance()->checkIsFailedByPassPercentCriteria ( $checkPassPercentCriteria );
                                        // $searchRequestForGradeScheme = new \stdClass();
                                        // $searchRequestForGradeScheme->groupId = $student->studentDetails->batchId;
                                        // $searchRequestForGradeScheme->academicTermId = $academicTerm->id;
                                        // $searchRequestForGradeScheme->academicPaperSubjectId = $subject->id;
                                        // $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequestForGradeScheme);
                                        $subjectGradeKey = array_search($subject->id, array_column( $subjectGradeSchemeArray, "id"));
                                        $gradeDetails = [];
                                        if($subjectGradeKey || $subjectGradeKey === 0){
                                            $gradeDetails = $subjectGradeSchemeArray[$subjectGradeKey]->grades;
                                        }
                                        $maxGradePercent =  max(array_column($gradeDetails,"rangeTo"));
                                        $schemeType = "PERCENTAGE";
                                        if(!$passCriteriaArray[$subject->id]){
                                            $passCriteriaArray[$subject->id] = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($subject->id, $schemeType);
                                        }
                                        $checkPassPercentCriteria = new \stdClass();
                                        $checkPassPercentCriteria->courseTypeMethod = $student->studentDetails->courseTypeMethod;
                                        $checkPassPercentCriteria->schemeType = $subjectGradeSchemeArray[$subjectGradeKey]->schemeType ? $subjectGradeSchemeArray[$subjectGradeKey]->schemeType : "PERCENTAGE";
                                        $checkPassPercentCriteria->isInternal = $subject->isInternal;
                                        $checkPassPercentCriteria->internalMaxMark = $subject->internalMaxMark;
                                        $checkPassPercentCriteria->isExternal = $subject->isExternal;
                                        $checkPassPercentCriteria->externalMaxMark = $subject->externalMaxMark;
                                        $checkPassPercentCriteria->internalMark = round($subject->internalMark, 2 );
                                        $checkPassPercentCriteria->passPercentConfig = $passCriteriaArray[$subject->id];
                                        $checkPassPercentCriteria->externalMark = round ( $subject->externalMark, 2 );
                                        $checkPassPercentCriteria->maxGradePercent = $maxGradePercent;
                                        $checkPassPercentCriteria->gradeDetails = $gradeDetails;
                                        $subjectPassCriteria = CommonExamService::getInstance()->checkIsFailedByPassPercentCreditCriteria ( $checkPassPercentCriteria );
                                        $subjectObj = new \stdClass;
                                        $subjectObj->id = $subject->id;
                                        $subjectObj->internalMark = $subject->internalMark;
                                        $subjectObj->studentAttendanceStatus = $subject->studentAttendanceStatus;
                                        $subjectObj->externalMark = $subject->externalMark;
                                        $subjectObj->internalMaxMark = $subject->internalMaxMark;
                                        $subjectObj->externalMaxMark = $subject->externalMaxMark;
                                        $subjectObj->isInternalAbsent = $subject->isInternalAbsent;
                                        $subjectObj->isExternal = $subject->isExternal;
                                        $subjectObj->isInternal = $subject->isInternal;
                                        $subjectObj->isInternalFailed = $subjectPassCriteria->internalFailedStatus ?? 'PASSED';
                                        $subjectObj->isExternalFailed = $subject->isExternalFailed;
                                        $subjectObj->maxGradePoint = $subject->maxGradePoint;
                                        $subjectObj->isFailed = $subject->isFailed;
                                        $subjectObj->isSupplyChance = $subject->isSupplyChance;
                                        $subjectObj->markNeededToPass = $subjectPassCriteria->overAllMarkNeededToPass >  $subjectPassCriteria->externalMarkNeededToPass ? (int)ceil($subjectPassCriteria->overAllMarkNeededToPass) : (int)ceil($subjectPassCriteria->externalMarkNeededToPass);
                                        $studentObj->markNeededToPassInSemester += $subjectObj->markNeededToPass;
                                        $subjectArray[$subject->id] = $subjectObj;
                                    }
                                }
                                $studentObj->subjects = $subjectArray;
                                $failedStudents[] = $studentObj;
                            }
                        }
                    }
                    // }
                    $noOfFailedStudents=count($failedStudents);
                    $noOfStudents=count($studentMarkDetails);
                    $noOfPassedStudents = $noOfStudents - $noOfFailedStudents;
                    $successRate = ($noOfPassedStudents / $noOfStudents) * 100;
                    $subjectPassDetails = new \stdClass;
                    $subjectPassDetails->noOfStudents = $noOfStudents;
                    $subjectPassDetails->successRate = round($successRate, 2);
                    $subjectPassDetails->noOfPassedStudents = $noOfPassedStudents;
                    $subjectPassDetails->noOfFailedStudents = $noOfFailedStudents;
                    $subjectPassDetails->noOfStudentsPassedByModeration = '0';
                    $subjectPassDetails->moderationMark='0';
                    $subjectPassDetails->existingModerationMark='0';
                    $additionalData->noOfStudents = $noOfStudents;
                    $additionalData->noOfPassedStudents = $noOfPassedStudents;
                    $response->subjectPassDetails= $subjectPassDetails;
                    $response->failedStudents = base64_encode(json_encode($failedStudents));
                    $response->additionalData = $additionalData;
                    $response->currentType = $regularExamReportObj->BatchWiseSuccessRateUIType;
                }
            }
            else
            {
                $additionalBatchDetails = new \stdClass;
                $additionalBatchDetails->collegeName = $GLOBALS['COLLEGE_NAME'];
                $additionalBatchDetails->collegeCode = $GLOBALS['COLLEGE_CODE'];
                $additionalBatchDetails->collegeUrl = $GLOBALS['_SERVER']['REQUEST_SCHEME']."://".$GLOBALS['_SERVER']['HTTP_HOST'];
                $batchRequest = new SearchExamRegistrationBatchRequest();
                $batchRequest->examRegistrationId = $searchRequest->examRegistrationId;
                $examRegistraionBatchDetails = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatch($batchRequest);
                $batchDetails = [];
                if($examRegistraionBatchDetails){
                    $additionalBatchDetails->exmRegistrationName = $examRegistraionBatchDetails[0]->examRegistrationName;
                    foreach($examRegistraionBatchDetails as $examRegBatch){
                        $request = new ConsolidatedMarkReportRequest;
                        $request->examRegistrationId = $searchRequest->examRegistrationId;
                        $request->groupId = $examRegBatch->groupId;
                        $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
                        // $studentMarkDetails = $this->getMarkReportDummyData();
                        if($studentMarkDetails){
                            foreach($studentMarkDetails as $student){
                                $batchName = $examRegBatch->groupName;
                                $batchDetails[$batchName]->batchId = $examRegBatch->id;
                                $batchDetails[$batchName]->batchName = $examRegBatch->groupName;
                                $batchDetails[$batchName]->departmentName = $examRegBatch->deptName;
                                $batchDetails[$batchName]->deptDescription = $examRegBatch->deptDescription;
                                $batchDetails[$batchName]->semster = $examRegBatch->academicTermName;
                                $batchDetails[$batchName]->courseType = $examRegBatch->courseTypeName;
                                $batchDetails[$batchName]->degreeName = $examRegBatch->degreeName;
                                $student->isFailedAnySubjectInExamRegistration = false;
                                // $regularExamTermMarkDetails = reset(array_filter(reset($student->academicTerms)->markHistory, function($history){
                                //     return $history->historyType == "REGULAR";
                                // }));
                                $currentAcademicTerm = reset(array_filter(reset($student->academicTerms)->markHistory,function($value)use($searchRequest){
                                    return $value->examRegistrationId == $searchRequest->examRegistrationId;
                                }));
                                // foreach ( $student->academicTerms as $academicTerm ) {
                                    // foreach ( $academicTerm->subjects as $subject ){
                                    //     if($subject->isFailed == "FAILED"){
                                    //         $student->isFailedAnySubjectInExamRegistration = true;
                                    //     }
                                    // }
                                // }
                                if($currentAcademicTerm->failedStatus == "FAILED"){
                                    $student->isFailedAnySubjectInExamRegistration = true;
                                }
                                $batchDetails[$batchName]->noOfPassedStudents += $student->isFailedAnySubjectInExamRegistration ? 0 : 1;
                                $batchDetails[$batchName]->noOfFailedStudents += $student->isFailedAnySubjectInExamRegistration ? 1 : 0;
                                $batchDetails[$batchName]->noOfStudents++;
                            }
                            foreach($batchDetails as $singleBatch){
                                $successRate = ($singleBatch->noOfPassedStudents / $singleBatch->noOfStudents) * 100;                
                                $singleBatch->successRate = round($successRate, 2);
                            }
                        }
                    }
                }
                if(empty($examRegistraionBatchDetails)){
                    throw new ExamControllerException(ExamControllerException::NO_BATCH_DETAILS_FOUND,"No Entry In This Exam Registration");
                    }
                    else{
                        $templateName = "BatchWiseSuccessRateTemplate";
                        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/successRateTemplateTwigs/$templateName.twig"), [ 'examRegistraionBatchDetails'=>$batchDetails ,'additionalBatchDetails'=>$additionalBatchDetails]);
    
                        $prtContent = NULL;
                            $prtContent .= '<html><head>';
                            $prtContent .= "<style>
                                h6 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                                table, th, td {border: 1px solid black;border-collapse: collapse;}
                                </style>";
                            $prtContent .= '</head><title>Batch Wise Success Rate Report</title><body>';
                            $prtContent .= $responseHtml;
                            $prtContent .= '</body></html>';
    
                            $totalWidth = 210;
                            $totalHeight = 297;
                            $options = array(
                                'page-width'     => $totalHeight."mm",
                                'page-height'    => $totalWidth."mm",
                                'dpi'            => 96,
                                'margin-top' => "9mm",
                                'margin-left' => "1mm",
                                'margin-right' => "1mm",
                                'margin-bottom' => "9mm",
                                // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                                'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                            );
                        $programResult = new \stdClass;
                        $programResult->dispalyHtmlData = $responseHtml;
                        $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
                    }
                $response->programResult = $programResult;
                $response->currentType = $regularExamReportObj->BatchWiseSuccessRateUIType;
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
       /**
     * Moderate Subject Wise Success Rate Details
     * @param $searchRequest 
     * @return $response 
     */
    public function moderateBatchWiseSuccessRateDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $response = new \stdClass;
            $failedStudents  = json_decode(base64_decode($searchRequest->failedStudents));
            $subjectPassDetails  = $searchRequest->subjectPassDetails;
            $moderationMark  = $searchRequest->moderationMark;
            $subjectMarkLimit  = (int)$searchRequest->subjectMarkLimit;
            $failCount = 0;
            $passedByModerationStudentList=[];
            $noOfStudentsPassedByModeration = 0;
            $noOfStudents = $subjectPassDetails['noOfStudents'];
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "SUBJECT_WISE_SUCCESS_RATE_RULE";
            $subjectWiseSuccessRatRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            if(!empty($subjectWiseSuccessRatRuleArray)){
                $IsConsiderFailedWhenOnlyExtrenalFailed = $subjectWiseSuccessRatRuleArray[0]->rule->IsConsiderFailedWhenOnlyExtrenalFailed;
            }
            foreach ($failedStudents as $student) {
                $student =(object)$student;
                $student->totalModerationMark = (int)$moderationMark;
                $student->arrears = 0;
                if($student->markNeededToPassInSemester <= $student->totalModerationMark){
                    $student->subjects = (array) $student->subjects;
                    foreach($student->subjects as $subject){
                        if( $searchRequest->examType == "SUPPLEMENTARY" &&  !$subject->isSupplyChance && $subject->isFailed == "FAILED" ){
                            $student->arrears += 1; 
                        }
                        else if($subject->isInternalFailed != 'PASSED'){
                            $student->arrears += 1; 
                        }
                        // this case to handle FE case if FE students then avoid pass conditions
                        else if($subject->studentAttendanceStatus == 'FE'){
                            $student->arrears += 1; 
                        }
                        else if($subject->isFailed != 'PASSED' && $subject->markNeededToPass != 0 ){
                            $subject->allowModeration = ($subject->markNeededToPass <= $subjectMarkLimit) ? true : false;
                            $subject->allowModeration = $subjectMarkLimit ? $subject->allowModeration : true;
                            $subject->allowModeration = $subjectMarkLimit == 0 ? false : $subject->allowModeration;
                            if($subject->allowModeration && $student->totalModerationMark && ($subject->markNeededToPass <= $student->totalModerationMark)){
                                $subject->isFailed = 'PASSED';
                                $student->totalModerationMark = $student->totalModerationMark - $subject->markNeededToPass;
                            }else{
                                $student->arrears += 1; 
                            }
                        }
                    }
                }
                if($student->arrears || $student->markNeededToPassInSemester > $moderationMark){
                    //is failed
                    $failCount++;
                } 
                else {
                    $student->isFailed = 'FAILED';
                    $noOfStudentsPassedByModeration++;
                    $passedByModerationStudentList [] = $student;
                }
            }
            $noOfFailedStudents = $failCount;
            $noOfPassedStudents = $noOfStudents - $noOfFailedStudents;
            $successRate = ($noOfPassedStudents / $noOfStudents) * 100;
            $subjectPassDetails = new \stdClass;
            $subjectPassDetails->successRate = round($successRate, 2);
            $subjectPassDetails->noOfPassedStudents = $noOfPassedStudents ? $noOfPassedStudents : 0 ;
            $subjectPassDetails->noOfFailedStudents = $noOfFailedStudents ? $noOfFailedStudents : 0;
            $subjectPassDetails->noOfStudentsPassedByModeration = $noOfStudentsPassedByModeration ? $noOfStudentsPassedByModeration : 0;
            $subjectPassDetails->moderationMark = $moderationMark ? $moderationMark : 0;
            $subjectPassDetails->existingModerationMark = $moderationMark ? $moderationMark : 0;
            $subjectPassDetails->passedByModerationStudentList = $passedByModerationStudentList;
            $response->subjectPassDetails = $subjectPassDetails;
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
      /**
     * get Batch Wise Success Rate Details
     * @param $searchRequest 
     * @return $response 
     */
    public function getSubjectWiseSuccessRateDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $academicPaperSubjectIds = explode(',',$searchRequest->academicPaperSubjectId);
            $examRegRequest = json_decode(json_encode($searchRequest));
            $examRegRequest->academicPaperSubjectId = $academicPaperSubjectIds;
            $examRegistrationDetailsArray = ExamRegistrationService::getInstance()->searchDetailedExamRegistrationDetails($examRegRequest);
            $response = new \stdClass;
            $additionalData = new \stdClass;
            $additionalData->exmRegistrationName = $examRegistrationDetailsArray[0]->name;
            $additionalData->collegeName = $GLOBALS['COLLEGE_NAME'];
            $additionalData->subjectCode = $examRegistrationDetailsArray[0]->groups[0]->subjects[0]->code;
            $additionalData->subjectName = $examRegistrationDetailsArray[0]->groups[0]->subjects[0]->name;
            $regularExamReportJson = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_REPORT, SettingsConstents::REGULAR_EXAM_REPORTS_UI_TYPES);
            $regularExamReportObj = json_decode($regularExamReportJson);
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "SUBJECT_WISE_SUCCESS_RATE_RULE";
            $successRatRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            if(!empty($successRatRuleArray)){
                $IsConsiderFailedWhenOnlyExtrenalFailed = $successRatRuleArray[0]->rule->IsConsiderFailedWhenOnlyExtrenalFailed;
            }
            if($regularExamReportObj->SubjectWiseSuccessRateUIType == "TEMPLATE_WITH_SUBJECTS"){
                $request = new ConsolidatedMarkReportRequest;
                $request->examRegistrationId = $searchRequest->examRegistrationId;
                $request->groupId = $searchRequest->groupId;
                $academicPaperSubjectIds = explode(',',$searchRequest->academicPaperSubjectId);
                $request->academicPaperSubjectId = $academicPaperSubjectIds;
                $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
                // $studentMarkDetails = $this->getMarkReportDummyData();
                $failedStudents=[];
                $noOfStudents=count($studentMarkDetails);
                if($studentMarkDetails){
                    // if($IsConsiderFailedWhenOnlyExtrenalFailed){
                    //     foreach($studentMarkDetails as $student){
                    //         $subjectArray = [];
                    //         $isFailedStudent = false;
                    //         foreach ( $student->academicTerms as $academicTerm ) {
                    //             foreach ( $academicTerm->subjects as $subject ){
                    //                 if($subject->isExternalFailed == "FAILED"){
                    //                     $isFailedStudent=true;
                    //                     $subjectObj = new \stdClass;
                    //                     $subjectObj->id = $subject->id;
                    //                     $subjectObj->internalMark = $subject->internalMark;
                    //                     $subjectObj->externalMark = $subject->externalMark;
                    //                     $subjectObj->internalMaxMark = $subject->internalMaxMark;
                    //                     $subjectObj->externalMaxMark = $subject->externalMaxMark;
                    //                     $subjectObj->isInternalAbsent = $subject->isInternalAbsent;
                    //                     $subjectObj->isExternal = $subject->isExternal;
                    //                     $subjectObj->isInternal = $subject->isInternal;
                    //                     $subjectObj->isInternalFailed = $subject->isInternalFailed;
                    //                     $subjectObj->isExternalFailed = $subject->isExternalFailed;
                    //                     $subjectObj->maxGradePoint = $subject->maxGradePoint;
                    //                     $subjectObj->isFailed = $subject->isFailed;
                    //                     $subjectObj->markNeededToPass = $subject->markNeededToPass;
                    //                     $subjectArray[$subject->id] = $subjectObj;
                    //                 }
                    //             }
                    //         }
                    //         if($isFailedStudent){
                    //             $studentObj = new \stdClass;
                    //             $studentObj->studentId = $student->studentDetails->id;
                    //             $studentObj->regNo = $student->studentDetails->registerNo;
                    //             $studentObj->name = $student->studentDetails->name;
                    //             $studentObj->batchName = $student->studentDetails->batchName;
                    //             $studentObj->isFailed = "FAILED";
                    //             $studentObj->subjects = $subjectArray;
                    //             $failedStudents[] = $studentObj;
                    //         } 
                    //     }
                    // }
                    // else{
                        foreach($studentMarkDetails as $student){
                            foreach ( $student->academicTerms as $academicTerm ) {
                                foreach ( $academicTerm->subjects as $subject ){
                                    $searchRequestForGradeScheme = new \stdClass();
                                    $searchRequestForGradeScheme->groupId = $student->studentDetails->batchId;
                                    $searchRequestForGradeScheme->academicTermId = $academicTerm->id;
                                    $searchRequestForGradeScheme->academicPaperSubjectId = $subject->id;
                                    $subjectGradeSchemeArray = GradeSchemeService::getInstance()->getAllSubjectGradeSchemesByRequest($searchRequestForGradeScheme);
                                    $subjectGradeKey = array_search($subject->id, array_column( $subjectGradeSchemeArray, "id"));
                                    $gradeDetails = [];
                                    if($subjectGradeKey || $subjectGradeKey === 0){
                                        $gradeDetails = $subjectGradeSchemeArray[$subjectGradeKey]->grades;
                                    }
                                    $maxGradePercent =  max(array_column($gradeDetails,"rangeTo"));
                                    $schemeType = "PERCENTAGE";
                                    $passCriteriaArray[$subject->id] = GradeSchemeService::getInstance()->getSubjectPassCriteriaByAcademicPaperSubject($subject->id, $schemeType);
                                    $checkPassPercentCriteria = new \stdClass();
                                    $checkPassPercentCriteria->courseTypeMethod = $student->studentDetails->courseTypeMethod;
                                    $checkPassPercentCriteria->schemeType = $subjectGradeSchemeArray[$subjectGradeKey]->schemeType ? $subjectGradeSchemeArray[$subjectGradeKey]->schemeType : "PERCENTAGE";
                                    $checkPassPercentCriteria->isInternal = $subject->isInternal;
                                    $checkPassPercentCriteria->internalMaxMark = $subject->internalMaxMark;
                                    $checkPassPercentCriteria->isExternal = $subject->isExternal;
                                    $checkPassPercentCriteria->externalMaxMark = $subject->externalMaxMark;
                                    $checkPassPercentCriteria->internalMark = round($subject->internalMark, 2 );
                                    $checkPassPercentCriteria->passPercentConfig = $passCriteriaArray[$subject->id];
                                    $checkPassPercentCriteria->externalMark = round ( $subject->externalMark, 2 );
                                    $checkPassPercentCriteria->maxGradePercent = $maxGradePercent;
                                    $checkPassPercentCriteria->gradeDetails = $gradeDetails;
                                    $subjectPassCriteria = CommonExamService::getInstance()->checkIsFailedByPassPercentCreditCriteria ( $checkPassPercentCriteria );
                                    if($subjectPassCriteria->failedStatus =='FAILED'){
                                        $studentObj = new \stdClass;
                                        $studentObj->studentId = $student->studentDetails->id;
                                        $studentObj->regNo = $student->studentDetails->registerNo;
                                        $studentObj->name = $student->studentDetails->name;
                                        $studentObj->batchName = $student->studentDetails->batchName;
                                        $studentObj->isFailed = $student->isFailed;
                                        $subjectArray = $academicTermArray = [];
                                        $subjectObj = new \stdClass;
                                        $subjectObj->id = $subject->id;
                                        $subjectObj->internalMark = $subject->internalMark;
                                        $subjectObj->externalMark = $subject->externalMark;
                                        $subjectObj->internalMaxMark = $subject->internalMaxMark;
                                        $subjectObj->externalMaxMark = $subject->externalMaxMark;
                                        $subjectObj->isInternalAbsent = $subject->isInternalAbsent;
                                        $subjectObj->isExternal = $subject->isExternal;
                                        $subjectObj->isInternal = $subject->isInternal;
                                        $subjectObj->isInternalFailed = $subjectPassCriteria->internalFailedStatus ?? 'PASSED';
                                        $subjectObj->isExternalFailed = $subject->isExternalFailed;
                                        $subjectObj->maxGradePoint = $subject->maxGradePoint;
                                        $subjectObj->isFailed = $subject->isFailed;
                                        $subjectObj->markNeededToPass = $subjectPassCriteria->overAllMarkNeededToPass >  $subjectPassCriteria->externalMarkNeededToPass ? (int)ceil($subjectPassCriteria->overAllMarkNeededToPass) : (int)ceil($subjectPassCriteria->externalMarkNeededToPass);
                                        $subjectArray[$subject->id] = $subjectObj;
                                        $academicTermArray[$academicTerm->id]->subjects = $subjectArray;
                                        $studentObj->academicTerms = $academicTermArray;
                                        $failedStudents[] = $studentObj;
                                    }
                                }
                            }
                        }
                    // }
                    $noOfFailedStudents = count($failedStudents);
                    $noOfStudents = count($studentMarkDetails);
                    $noOfPassedStudents = $noOfStudents - $noOfFailedStudents;
                    $successRate = ($noOfPassedStudents / $noOfStudents) * 100;
                    $subjectPassDetails = new \stdClass;
                    $subjectPassDetails->noOfStudents = $noOfStudents;
                    $subjectPassDetails->successRate = round($successRate, 2);
                    $subjectPassDetails->noOfPassedStudents = $noOfPassedStudents;
                    $subjectPassDetails->noOfFailedStudents = $noOfFailedStudents;
                    $subjectPassDetails->noOfStudentsPassedByModeration = '0';
                    $subjectPassDetails->moderationMark='0';
                    $subjectPassDetails->existingModerationMark='0';
                    $subjectPassDetails->subjectId =  $request->academicPaperSubjectId;
                    $additionalData->noOfStudents = $noOfStudents;
                    $additionalData->noOfPassedStudents = $noOfPassedStudents;
                    $response->subjectPassDetails= $subjectPassDetails;
                    $response->failedStudents = base64_encode(json_encode($failedStudents));
                    $response->additionalData = $additionalData;
                    $response->currentType = $regularExamReportObj->SubjectWiseSuccessRateUIType;
                }
            }
            else{
                $subjectPassDetails = [];
                $additionalDataBatchDetails = new \stdClass;
                $batchRequest = new SearchExamRegistrationBatchRequest();
                $batchRequest->examRegistrationId = $searchRequest->examRegistrationId;
                $batchRequest->academicTermId = $searchRequest->academicTermIds;
                if(!empty($searchRequest->groupId)){
                    $batchRequest->groupId = $searchRequest->groupId;
                }
                $examRegistraionBatchDetails = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatch($batchRequest);
                if($examRegistraionBatchDetails){
                    $additionalDataBatchDetails->examRegistrationName = reset($examRegistraionBatchDetails)->examRegistrationName;
                    foreach($examRegistraionBatchDetails as $batch){
                        $additionalDataBatchDetails->batchNames[] = $batch->groupName;
                    }
                    $additionalDataBatchDetails->batchName = implode ( ",", $additionalDataBatchDetails->batchNames );
                    $additionalDataBatchDetails->collegeName = $GLOBALS['COLLEGE_NAME'];
                }
                $examRegistrationSubjects = [];
                $request = new ConsolidatedMarkReportRequest;
                $request->examRegistrationId = $searchRequest->examRegistrationId;
                $request->groupId = $searchRequest->groupId;
                $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
                if(empty($studentMarkDetails)){
                    throw new ExamControllerException(ExamControllerException::NO_DETAILS_FOUND,"No Students Found");
                }
                // $studentMarkDetails = $this->getMarkReportDummyData();
                if($studentMarkDetails){
                    foreach($studentMarkDetails as $student){
                        foreach ( $student->academicTerms as $academicTerm ) {
                            foreach ( $academicTerm->subjects as $subject ) {
                                $syllabusCode = $subject->syllabusCode ?? $subject->code;
                                $examRegistrationSubjects[$syllabusCode]->subjectId = $subject->id;
                                $examRegistrationSubjects[$syllabusCode]->subjectCode = $subject->code;
                                $examRegistrationSubjects[$syllabusCode]->syllabusCode = $syllabusCode;
                                $examRegistrationSubjects[$syllabusCode]->subjectName = $subject->name;
                                $examRegistrationSubjects[$syllabusCode]->noOfStudents++;
                                $examRegistrationSubjects[$syllabusCode]->batchId = $student->studentDetails->batchId;
                                if($subject->isFailed == "FAILED"){
                                    $examRegistrationSubjects[$syllabusCode]->noOfFailedStudents = $examRegistrationSubjects[$syllabusCode]->noOfFailedStudents + 1;
                                    $examRegistrationSubjects[$syllabusCode]->noOfPassedStudents = $examRegistrationSubjects[$syllabusCode]->noOfPassedStudents + 0;
                                    $examRegistrationSubjects[$syllabusCode]->failedStudent[] = $student;
                                }
                                else{
                                    $examRegistrationSubjects[$syllabusCode]->noOfFailedStudents = $examRegistrationSubjects[$syllabusCode]->noOfFailedStudents + 0;
                                    $examRegistrationSubjects[$syllabusCode]->noOfPassedStudents = $examRegistrationSubjects[$syllabusCode]->noOfPassedStudents + 1;
                                }
                            }
                        }
                    }
                    foreach($examRegistrationSubjects as $singleSubject){
                        $singleSubject->successRate = round(($singleSubject->noOfPassedStudents / $singleSubject->noOfStudents) * 100,2);
                        $singleSubject->modurationMark = "";
                        $singleSubject->failedStudentsAfterModeration = 0;
                        $singleSubject->successRateAfterModeration = 0;
                        $singleSubject->failedStudent = base64_encode(json_encode($singleSubject->failedStudent));
                        $subjectPassDetails[]= $singleSubject;
                    }
                }
                $response->subjectPassDetails = $subjectPassDetails;
                $response->additionalData = $additionalDataBatchDetails;
                $response->currentType = $regularExamReportObj->SubjectWiseSuccessRateUIType;
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
       /**
     * Moderate Subject Wise Success Rate Details
     * @param $searchRequest 
     * @return $response 
     */
    public function moderateSubjectWiseSuccessRateDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try
        {
            $response = new \stdClass;
            $failedStudents  = json_decode(base64_decode($searchRequest->failedStudents));
            $subjectPassDetails  = $searchRequest->subjectPassDetails;
            $moderationMark  = $searchRequest->moderationMark;
            $failCount = 0;
            $passedByModerationStudentList=[];
            $noOfStudentsPassedByModeration = 0;
            $noOfStudents = $subjectPassDetails['noOfStudents'];
            foreach ($failedStudents as $student) {
                $student->academicTerms = (array)$student->academicTerms;
                $student =(object)$student;
                $student->totalModerationMark = (int)$moderationMark;
                $student->arrears = 0;
                foreach($student->academicTerms as $academicTerm){
                    $academicTerm->subjects = (array) $academicTerm->subjects;
                    foreach($academicTerm->subjects as $subject){
                        if(is_array($subjectPassDetails["subjectId"])){
                            if(!in_array($subject->id, $subjectPassDetails["subjectId"])) continue;
                        }
                        else{
                            if($subject->id != $subjectPassDetails["subjectId"]) continue;
                        }
                        $subject->markNeededToPass = abs($subject->markNeededToPass);
                        if(($student->totalModerationMark) && ($subject->markNeededToPass) && ($subject->markNeededToPass <= $student->totalModerationMark) && ($subject->isInternalFailed == 'PASSED')){
                            $subject->isFailed = "PASSED";
                            $student->totalModerationMark = $student->totalModerationMark - $subject->markNeededToPass;
                        }else if ($subject->isFailed == "FAILED") {
                            $student->arrears += 1;
                        }
                    }
                }
                if($student->arrears){
                    //is failed
                    $failCount++;
                } else {
                    $student->isFailed = "PASSED";
                    $noOfStudentsPassedByModeration++;
                    $passedByModerationStudentList [] = $student;
                }
            }
            $noOfFailedStudents = $failCount;
            $noOfPassedStudents = $noOfStudents - $noOfFailedStudents;
            $successRate = ($noOfPassedStudents / $noOfStudents) * 100;
            $subjectPassDetails = new \stdClass;
            $subjectPassDetails->successRate = round($successRate, 2);
            $subjectPassDetails->noOfPassedStudents = $noOfPassedStudents ? $noOfPassedStudents : 0 ;
            $subjectPassDetails->noOfFailedStudents = $noOfFailedStudents ? $noOfFailedStudents : 0;
            $subjectPassDetails->noOfStudentsPassedByModeration = $noOfStudentsPassedByModeration ? $noOfStudentsPassedByModeration : 0;
            $subjectPassDetails->moderationMark = $moderationMark ? $moderationMark : 0;
            $subjectPassDetails->existingModerationMark = $moderationMark ? $moderationMark : 0;
            $subjectPassDetails->passedByModerationStudentList = $passedByModerationStudentList;
            $response->subjectPassDetails = $subjectPassDetails;
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
    /**
     * get Current result Analysis Exam UI Type
     * @param $searchRequest 
     * @return $response 
     */
    public function getAllResultAnalysisTabMenus($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $response = new \stdClass;
            $tabMenusDisplay = new \stdClass;
            $tabMenusDisplay->isSubjectWise = false;
            $tabMenusDisplay->isCourseWise = false;
            $tabMenusDisplay->isStudentWise = false;
            $tabMenusDisplay->isGradeReport = false;
            $tabMenusDisplay->isYearWise = false;
            $tabMenusDisplay->isResultAnalysis = false;
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = $searchRequest->examType == 'SUPPLEMENTARY' ? "SUPPLEMENTARY_EXAM_REPORTS_UI_TYPES" : "REGULAR_EXAM_REPORTS_UI_TYPES";
            $regularExamReportObj = reset(RuleService::getInstance()->searchRule($searchRuleRequest))->rule;
            // $regularExamReportJson = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_REPORT, SettingsConstents::REGULAR_EXAM_REPORTS_UI_TYPES);
            // $regularExamReportObj = json_decode($regularExamReportJson);
            if($regularExamReportObj->IsVisibleGradeHeadInResultAnalysisSubjectWise){
                $response->IsVisibleGradeHeadInResultAnalysisSubjectWise = true; 
                $gradeHeads = '[
                    {
                        "id":"grade",
                        "text":"Grade"
                    },
                    {
                        "id":"class",
                        "text":"Class"
                    },
                    {
                        "id":"classGrade",
                        "text":"Class (Grade)"
                    }
                ]';
                $gradeHeads = json_decode($gradeHeads);
                $response->gradeHeadsArraySubjectWise =  $gradeHeads; 
            }
            else{
                $response->IsVisibleGradeHeadInResultAnalysisSubjectWise = false;
                $response->gradeHeadsArraySubjectWise = []; 
            }
            if($regularExamReportObj->IsVisibleGradeHeadInResultAnalysisCourseWise){
                $response->IsVisibleGradeHeadInResultAnalysisCourseWise = true; 
                $gradeHeads = '[
                    {
                        "id":"grade",
                        "text":"Grade"
                    },
                    {
                        "id":"class",
                        "text":"Class"
                    },
                    {
                        "id":"classGrade",
                        "text":"Class (Grade)"
                    }
                ]';
                $gradeHeads = json_decode($gradeHeads);
                $response->gradeHeadsArrayCourseWise =  $gradeHeads; 
            }
            else
            {
                $response->IsVisibleGradeHeadInResultAnalysisCourseWise = false;
                $response->gradeHeadsArrayCourseWise = []; 
            }
            if($regularExamReportObj->IsVisibleFiltersInResultAnalysis)
            {
                $response->IsVisibleFiltersInResultAnalysis = true;
            }
            else
            {
                $response->IsVisibleFiltersInResultAnalysis = false;
            }
            if(!empty ($regularExamReportObj->ResultAnalysisTabDispalyArray)){
                foreach($regularExamReportObj->ResultAnalysisTabDispalyArray as $tabMenu){
                    if($tabMenu == "SUBJECT_WISE"){
                        $tabMenusDisplay->isSubjectWise = true;
                    }
                    if($tabMenu == "COURSE_WISE"){
                        $tabMenusDisplay->isCourseWise = true;
                    }
                    if($tabMenu == "STUDENT_WISE"){
                        $tabMenusDisplay->isStudentWise = true;
                    }
                    if($tabMenu == "GRADE_REPORT"){
                        $tabMenusDisplay->isGradeReport = true;
                    }
                    if($tabMenu == "YEAR_WISE"){
                        $tabMenusDisplay->isYearWise = true;
                    }
                    if($tabMenu == "RESULT_ANALYSIS"){
                        $tabMenusDisplay->isResultAnalysis = true;
                    }
                    if($tabMenu == "PROGRAM_WISE"){
                        $tabMenusDisplay->isProgramWise = true;
                    }
                    if($tabMenu == "COMBINED_WISE"){
                        $tabMenusDisplay->isCombinedWise = true;
                    }
                    if($tabMenu == "SUBJECT_WISE_MULTIPLE_EXAM"){
                        $tabMenusDisplay->isSubjectWiseMultipleExam = true;
                    }
                    if($tabMenu == "CASTE_CATEGORY_WISE"){
                        $tabMenusDisplay->isCasteCategoryWise = true;
                    }
                    
                }
            }
            $response->tabMenus = $tabMenusDisplay;
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
    /**
     * get Current Regular Exam Search Filter Inputs
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularResultAnalysissearchFilterInputs($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try
        {
            $response = new \stdClass;
            $reservations = ReservationStudentsService::getInstance()->getAllReservations();
            $religions = ReligionService::getInstance()->getAllReligion();
            $campusTypes = CampusTypeService::getInstance()->getAllCampusTypes();
            $allObj = new \stdClass();
            $allObj->id = "ALL";
            $allObj->text = "All";
            foreach($reservations as $reservation)
            {
                $reservation->id = $reservation->reservationID;
                $reservation->text = $reservation->reservationName;
            }
            foreach($religions as $religion)
            {
                $religion->id = $religion->religionId;
                $religion->text = $religion->religionName;
            }
            foreach($campusTypes as $campusType)
            {
                $campusType->text = $campusType->name;
            }
            $gendersJson = '[
                {
                    "id":"ALL",
                    "text":"All"
                },
                {
                    "id":"male",
                    "text":"Male"
                },
                {
                    "id":"female",
                    "text":"Female"
                },
                {
                    "id":"ThirdGender",
                    "text":"Third Gender"
                }
            ]';
            $genders = json_decode($gendersJson);
            array_unshift($reservations,$allObj);
            array_unshift($religions,$allObj);
            array_unshift($campusTypes,$allObj);
            $response->reservations = $reservations;
            $response->religions = $religions;
            $response->genders = $genders;
            $response->campusTypes = $campusTypes;
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
      /**
     * get Regular Exam Statistical Result Analysis Inputs
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamStatisticalResultAnalysisInputs($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try
        {
            $response = new \stdClass;
            $gradeHeads = '[
                {
                    "id":"grade",
                    "text":"Grade"
                },
                {
                    "id":"class",
                    "text":"Class"
                },
                {
                    "id":"classGrade",
                    "text":"Class (Grade)"
                }
            ]';
            $reportTypes = '[
                {
                    "id":"RELIGION_WISE",
                    "text":"Religion Wise"
                },
                {
                    "id":"CATEGORY_WISE",
                    "text":"Category Wise"
                },
                {
                    "id":"COURSE_WISE",
                    "text":"Course Wise"
                }
            ]';
            $reportTypes = json_decode($reportTypes);
            $response->reportTypes =  $reportTypes;
            $gradeHeads = json_decode($gradeHeads);
            $response->gradeHeads =  $gradeHeads; 
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
      /**
     * get Regular Exam Subject Wise Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamSubjectWiseResultAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $additionalDetails = new \stdClass;
            $additionalDetails->collegeName = $GLOBALS['COLLEGE_NAME'];
            $additionalDetails->collegeCode = $GLOBALS['COLLEGE_CODE'];
            $additionalDetails->collegeUrl = $GLOBALS['_SERVER']['REQUEST_SCHEME']."://".$GLOBALS['_SERVER']['HTTP_HOST'];
            $absenteesAsFailedStatus = $searchRequest->absenteesAsFailedStatus == 'true' ? true : false;
            
            // $academicTermId = $searchRequest->academicTermId;
            $subjectWiseResultAnalysisRequest = new \stdClass;
            $subjectWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $subjectWiseResultAnalysisRequest->degreeId = $searchRequest->degreeId;
            $subjectWiseResultAnalysisRequest->groupId = $searchRequest->examRegBatchIds;
            $subjectWiseResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId;          
            $subjectWiseResultAnalysisRequest->absenteesAsFailedStatus = $absenteesAsFailedStatus;
            $subjectWiseResultAnalysisRequest->isStaffSideView = $searchRequest->isStaffSideView; 
            // $regularExamReportJson = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_REPORT, SettingsConstents::REGULAR_EXAM_REPORTS_UI_TYPES);
            // $regularExamReportObj = json_decode($regularExamReportJson);
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name =  "REGULAR_EXAM_REPORTS_UI_TYPES";
            $regularExamReportObj = reset(RuleService::getInstance()->searchRule($searchRuleRequest))->rule;
            // current exam Registration Details 
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->id = $searchRequest->examRegistrationId;
            $examRegistration = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
            if(!empty($examRegistration)){
                $additionalDetails->examRegistrationName = reset($examRegistration)->name;
                $additionalDetails->examRegistrationType = reset($examRegistration)->type; 
            }
            //Template 1 For Grade Head
            if($regularExamReportObj->IsVisibleGradeHeadInResultAnalysisSubjectWise){
                $gradeSchemeRequest = new \stdClass;
                $gradeSchemeRequest->examRegistrationId = $searchRequest->examRegistrationId;
                $gradeSchemeRequest->academicTermId = $searchRequest->academicTermId;
                $gradeSchemeRequest->gradeHead = $searchRequest->subjectWiseGradeHead;
                $gradeSchemeRequest->courseTypeId = $searchRequest->courseType;
                $gradeSchemeRequest->excludeFailedGrade = true;
                $gradeSchemeDetals = $this->getAllSubjectGradeSchemesDetailsByExamRegistration($gradeSchemeRequest);
                $uniqueClassNames = array_unique($gradeSchemeDetals->classNames);
                $subjectWiseResultAnalysisRequest->IsVisibleGradeHeadInResultAnalysisSubjectWise = $regularExamReportObj->IsVisibleGradeHeadInResultAnalysisSubjectWise; 
                $subjectWiseResultAnalysisRequest->gradeHead = $searchRequest->subjectWiseGradeHead; 
                $resultAnalysis = $this->getSubjectWiseResultAnalysis($subjectWiseResultAnalysisRequest);
                if(empty($resultAnalysis)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"Result analysis not available");
                }
                else{
                    $templateName = "SubjectWiseResultAnalysisTemplateWithGradeHead";
                    $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ,'uniqueClassNames'=>$uniqueClassNames ,'additionalDetails'=>$additionalDetails ,'headerNames'=>$gradeSchemeDetals->classHeaderNames]);
                    $prtContent = NULL;
                        $prtContent .= '<html><head>';
                        $prtContent .= "<style>
                            .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                            table, th, td {border: 1px solid black;border-collapse: collapse;}
                            </style>";
                        $prtContent .= '</head><title>Subject Wise Result Anaysis</title><body>';
                        $prtContent .= $responseHtml;
                        $prtContent .= '</body></html>';
                        $totalWidth = 210;
                        $totalHeight = 297;
                        $options = array(
                            'page-width'     => $totalHeight."mm",
                            'page-height'    => $totalWidth."mm",
                            'dpi'            => 96,
                            'margin-top' => "9mm",
                            'margin-left' => "1mm",
                            'margin-right' => "1mm",
                            'margin-bottom' => "9mm",
                            // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                            'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                        );
                    $programResult = new \stdClass;
                    $programResult->dispalyHtmlData = $responseHtml;
                    $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
                }
            }
            //Template 2 For With Out Grade Head
            else{
                $resultAnalysis = $this->getSubjectWiseResultAnalysis($subjectWiseResultAnalysisRequest);
                if(empty($resultAnalysis)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"Result analysis not available");
                }
                else{
                    $templateName = "SubjectWiseResultAnalysisTemplateWithOutGradeHead";
                    $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis,'absenteesAsFailedStatus'=>$absenteesAsFailedStatus ,'additionalDetails'=>$additionalDetails]);
                    $prtContent = NULL;
                        $prtContent .= '<html><head>';
                        $prtContent .= "<style>
                            h5 {font-size: 26px;}  h6 {font-size: 22px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                            table, th, td {border: 1px solid black;border-collapse: collapse;}
                            </style>";
                        $prtContent .= '</head><title>Subject Wise Result Anaysis</title><body>';
                        $prtContent .= $responseHtml;
                        $prtContent .= '</body></html>';
                        $totalWidth = 210;
                        $totalHeight = 297;
                        $options = array(
                            'page-width'     => $totalHeight."mm",
                            'page-height'    => $totalWidth."mm",
                            'dpi'            => 96,
                            'margin-top' => "9mm",
                            'margin-left' => "1mm",
                            'margin-right' => "1mm",
                            'margin-bottom' => "9mm",
                            // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                            'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                        );
                    $programResult = new \stdClass;
                    $programResult->dispalyHtmlData = $responseHtml;
                    $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
                }
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
    public function getSubjectWiseResultAnalysis($request){
        $request = $this->realEscapeObject($request);
        try{
            $resultAnalysis = [];
            $searchRequest = new ConsolidatedMarkReportRequest;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->academicTermId = $request->academicTermId;
            $searchRequest->degreeId = $request->degreeId;
            $searchRequest->groupId = $request->groupId;
            if( $request->isStaffSideView == 'true'){
                $requestForExamRegistration = new SearchExamRegistrationRequest;
                $requestForExamRegistration->groupId = $request->groupId;
                $revaluationRegistrations = ExamRegistrationService::getInstance()->getAllExamRevaluation($requestForExamRegistration);    
            }
            $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
            // $studentMarkDetails = $this->getMarkReportDummyData();
            if($studentMarkDetails){
                foreach($studentMarkDetails as $key => $student){
                    if( $request->isStaffSideView == 'true'){
                        $examBatchProperties = $student->examBatchProperties;
                        if($student->isResultWithHeld == '1' ||  (!($examBatchProperties->isResultPublished ) ||  (($examBatchProperties->isResultPublished) && (strtotime($examBatchProperties->publishingStartDate) > strtotime(date("Y-m-d H:i")))))) {
                            unset($studentMarkDetails[$key]);
                            $student = null;                        
                        }
                    }
                    foreach ( $student->academicTerms as $academicTerm ) {
                        foreach ( $academicTerm->subjects as $subject ) {
                            if( $request->isStaffSideView == 'true'){
                                if ( $subject->subjectHasRevaluationMark ){
                                    $currentRegistration = reset(array_filter($revaluationRegistrations,function($value)use($subject){
                                        return $value->id == $subject->subjectRevaluationId;
                                    }));
                                    $revaluationBatch = reset(array_filter($currentRegistration->groups,function($value)use($academicTerm){
                                        return $value->id == $academicTerm->groupId;
                                    }));
                                    if ( $revaluationBatch->properties->isResultPublished != 1 || strtotime($revaluationBatch->properties->publishingStartDate) > strtotime(date("Y-m-d H:i"))){
                                        $subject->failedStatus = $subject->subjectWithoutRevaluationIsFailed == 1 ? "FAILED" : "PASSED";
                                        $subject->isFailed = $subject->failedStatus;
                                    }
                                }
                            }
                            $syllabusCode = $subject->syllabusCode ?? $subject->code;
                            $resultAnalysis[$syllabusCode]->subjectCode = $subject->code;
                            $resultAnalysis[$syllabusCode]->syllabusCode = $syllabusCode;
                            $resultAnalysis[$syllabusCode]->subjectDesc = $subject->name;
                            $resultAnalysis[$syllabusCode]->enrolled++;
                            $resultAnalysis[$syllabusCode]->passed += $subject->isFailed == "FAILED" ? 0 : 1;
                            if ($subject->examAttendanceStatus == 'ABSENT') {
                                $resultAnalysis[$syllabusCode]->absent ++;
                            }
                            if($request->absenteesAsFailedStatus){
                                $resultAnalysis[$syllabusCode]->failed += $subject->isFailed == "FAILED" ? 1 : 0;
                                if ($subject->examAttendanceStatus != 'ABSENT') {
                                    $resultAnalysis[$syllabusCode]->appeared++;
                                }
                            }
                            else{
                                if ($subject->examAttendanceStatus != 'ABSENT') { 
                                    $resultAnalysis[$syllabusCode]->failed += $subject->isFailed == "FAILED" ? 1 : 0;
                                    $resultAnalysis[$syllabusCode]->appeared++;
                                } 
                            }
                            if ($subject->isFailed == "PASSED") {
                                // If the student is absent then his/her 'isFailed' will be 1
                                if($request->IsVisibleGradeHeadInResultAnalysisSubjectWise){
                                    if($request->gradeHead == 'class'){
                                        $resultAnalysis[$syllabusCode]->analysisHead[strtoupper($subject->class)]++;
                                    }
                                    elseif($request->gradeHead == 'grade'){
                                        $resultAnalysis[$syllabusCode]->analysisHead[strtoupper($subject->grade)]++;
                                    }
                                    elseif($request->gradeHead == 'classGrade'){
                                        $resultAnalysis[$syllabusCode]->analysisHead[strtoupper($subject->class.$subject->grade)]++;
                                    }
                                }
                                $resultAnalysis[$syllabusCode]->batchId = $student->studentDetails->batchId;
                            }
                        }
                    }
                }
                foreach($resultAnalysis as $singleResultAnalysis){
                    $singleResultAnalysis->passPercentage = round ( ( 100 * $singleResultAnalysis->passed / $singleResultAnalysis->enrolled ), 2);
                    $attendedStudentCount = $singleResultAnalysis->enrolled - $singleResultAnalysis->absent;
                    if ( $attendedStudentCount > 0 ) {
                        $singleResultAnalysis->passPercentageExcludingAbsent = round ( ( 100 * $singleResultAnalysis->passed / $attendedStudentCount ), 2);
                    }
                    else {
                        $singleResultAnalysis->passPercentageExcludingAbsent = 0;
                    }
                }
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $resultAnalysis;
    }
     /**
     * get Regular Exam Couse Wise Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamCourseWiseResultAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try
        {
            $additionalDetails = new \stdClass;
            $additionalDetails->collegeName = $GLOBALS['COLLEGE_NAME'];
            $additionalDetails->collegeCode = $GLOBALS['COLLEGE_CODE'];
            $additionalDetails->collegeUrl = $GLOBALS['_SERVER']['REQUEST_SCHEME']."://".$GLOBALS['_SERVER']['HTTP_HOST'];
            // $searchRuleRequest = new SearchRuleRequest;
            // $searchRuleRequest->name = "REGULAR_EXAM_REPORT_RULE";
            // $regularExamReportRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            // if(!empty($regularExamReportRuleArray))
            // {
            //     $IsConsiderNotAppearedWhenStudentAbsentInExam = $regularExamReportRuleArray[0]->rule->IsConsiderNotAppearedWhenStudentAbsentInExam;
            // }
            $absenteesAsFailedStatus = $searchRequest->absenteesAsFailedStatus == 'true' ? true : false;
            // $academicTermId = $searchRequest->academicTermId;
            $courseWiseResultAnalysisRequest = new \stdClass;
            $courseWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $courseWiseResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $courseWiseResultAnalysisRequest->absenteesAsFailedStatus = $absenteesAsFailedStatus;
            $courseWiseResultAnalysisRequest->groupId = $searchRequest->groupId;
            $courseWiseResultAnalysisRequest->isStaffSideView = $searchRequest->isStaffSideView;
            // $regularExamReportJson = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_REPORT, SettingsConstents::REGULAR_EXAM_REPORTS_UI_TYPES);
            // $regularExamReportObj = json_decode($regularExamReportJson);
            
            // current exam Registration Details 
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->id = $searchRequest->examRegistrationId;
            $examRegistration = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
            if(!empty($examRegistration)){
                $additionalDetails->examRegistrationName = reset($examRegistration)->name;
                $additionalDetails->examRegistrationType = reset($examRegistration)->type; 
            }
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "REGULAR_EXAM_REPORTS_UI_TYPES";
            $regularExamReportObj = reset(RuleService::getInstance()->searchRule($searchRuleRequest))->rule;
            //Template 1 For Grade Head
            if($regularExamReportObj->IsVisibleGradeHeadInResultAnalysisCourseWise){
                $gradeSchemeRequest = new \stdClass;
                $gradeSchemeRequest->examRegistrationId = $searchRequest->examRegistrationId;
                $gradeSchemeRequest->academicTermId = $searchRequest->academicTermId;
                $gradeSchemeRequest->gradeHead = $searchRequest->courseWiseGradeHead;
                $gradeSchemeDetals = $this->getAllGradeSchemesDetailsByExamRegistration($gradeSchemeRequest);
                $uniqueClassNames = array_unique($gradeSchemeDetals->classNames);
                $courseWiseResultAnalysisRequest->IsVisibleGradeHeadInResultAnalysisCourseWise = $regularExamReportObj->IsVisibleGradeHeadInResultAnalysisCourseWise; 
                $courseWiseResultAnalysisRequest->uniqueClassNames = $uniqueClassNames; 
                $courseWiseResultAnalysisRequest->gradeHead = $gradeSchemeRequest->gradeHead;
                $resultAnalysis = $this->getCourseWiseResultAnalysis($courseWiseResultAnalysisRequest);
                if(empty($resultAnalysis)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"Result analysis not available");
                }
                else{
                    $templateName = "CourseWiseResultAnalysisTemplateWithGradeHead";
                    $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ,'uniqueClassNames'=>$uniqueClassNames ,'classHeaderNames'=>$gradeSchemeDetals->classHeaderNames,'additionalDetails'=>$additionalDetails ]);
                    $prtContent = NULL;
                        $prtContent .= '<html><head>';
                        $prtContent .= "<style>
                            .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                            table, th, td {border: 1px solid black;border-collapse: collapse;}
                            </style>";
                        $prtContent .= '</head><title>Course Wise Result Anaysis</title><body>';
                        $prtContent .= $responseHtml;
                        $prtContent .= '</body></html>';
                        $totalWidth = 210;
                        $totalHeight = 297;
                        $options = array(
                            'page-width'     => $totalHeight."mm",
                            'page-height'    => $totalWidth."mm",
                            'dpi'            => 96,
                            'margin-top' => "9mm",
                            'margin-left' => "1mm",
                            'margin-right' => "1mm",
                            'margin-bottom' => "9mm",
                            // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                            'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                        );
                    $programResult = new \stdClass;
                    $programResult->dispalyHtmlData = $responseHtml;
                    $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
                } 
            }
            //Template 2 For With Out Grade Head
            else
            {
                $resultAnalysis = $this->getCourseWiseResultAnalysis($courseWiseResultAnalysisRequest);
                if(empty($resultAnalysis)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"Result analysis not available");
                }
                else{
                    $templateName = "CourseWiseResultAnalysisTemplateWithOutGradeHead";
                    $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ,'absenteesAsFailedStatus'=>$absenteesAsFailedStatus,'additionalDetails'=>$additionalDetails]);
                    $prtContent = NULL;
                        $prtContent .= '<html><head>';
                        $prtContent .= "<style>
                            h5 {font-size: 26px;} h6 {font-size: 20px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                            table, th, td {border: 1px solid black;border-collapse: collapse;}
                            </style>";
                        $prtContent .= '</head><title>Subject Wise Result Anaysis</title><body>';
                        $prtContent .= $responseHtml;
                        $prtContent .= '</body></html>';
                        $totalWidth = 210;
                        $totalHeight = 297;
                        $options = array(
                            'page-width'     => $totalHeight."mm",
                            'page-height'    => $totalWidth."mm",
                            'dpi'            => 96,
                            'margin-top' => "9mm",
                            'margin-left' => "1mm",
                            'margin-right' => "1mm",
                            'margin-bottom' => "9mm",
                            // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                            'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                        );
                    $programResult = new \stdClass;
                    $programResult->dispalyHtmlData = $responseHtml;
                    $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
                }
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
    public function getCourseWiseResultAnalysis($request)
    {
        $request = $this->realEscapeObject($request);
        try{
            $resultAnalysis = [];
            $searchRequest = new ConsolidatedMarkReportRequest;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->academicTermId = $request->academicTermId;
            $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
            if( $request->isStaffSideView == 'true'){
                $requestForExamRegistration = new SearchExamRegistrationRequest;
                $requestForExamRegistration->parentExamRegistrationId = $request->examRegistrationId;
                $revaluationRegistrations = ExamRegistrationService::getInstance()->getAllExamRevaluation($requestForExamRegistration);    
            }
            // $studentMarkDetails = $this->getMarkReportDummyData();
            if($studentMarkDetails){
                foreach($studentMarkDetails as $key => $student){
                    if( $request->isStaffSideView == 'true'){
                        $examBatchProperties = $student->examBatchProperties;
                        if($student->isResultWithHeld == '1' ||  (!($examBatchProperties->isResultPublished ) ||  (($examBatchProperties->isResultPublished) && (strtotime($examBatchProperties->publishingStartDate) > strtotime(date("Y-m-d H:i")))))) {
                            unset($studentMarkDetails[$key]);
                            $student = null;                        
                        }
                    }
                    if($student){
                        $student->academicTerm = reset($student->academicTerms);
                        $currentAcademicTerm = reset(array_filter(reset($student->academicTerms)->markHistory,function($value)use($request){
                            return $value->historyType == "REGULAR" && $value->examRegistrationId == $request->examRegistrationId;
                        }));
                        if( $request->isStaffSideView == 'true'){
                            if ( $currentAcademicTerm->hasRevaluationMark ){
                                $currentRegistration = reset(array_filter($revaluationRegistrations,function($value)use($currentAcademicTerm){
                                    return $value->id == $currentAcademicTerm->revaluationId;
                                }));
                                $revaluationBatch = reset(array_filter($currentRegistration->groups,function($value)use($currentAcademicTerm){
                                    return $value->id == $currentAcademicTerm->groupId;
                                }));
                                if ( $revaluationBatch->properties->isResultPublished != 1 || strtotime($revaluationBatch->properties->publishingStartDate) > strtotime(date("Y-m-d H:i"))){
                                    $currentAcademicTerm->failedStatus = $currentAcademicTerm->withoutRevaluationFailedStatus;
                                    $currentAcademicTerm->isFailed = $currentAcademicTerm->failedStatus;
                                }
                            }
                        }
                        $batchId = $student->studentDetails->batchId;
                        $resultAnalysis[$batchId]->batchId = $student->studentDetails->batchId;
                        $resultAnalysis[$batchId]->batchName = $student->studentDetails->batchName;
                        $resultAnalysis[$batchId]->enrolled++;
                        $resultAnalysis[$batchId]->passed += $currentAcademicTerm->failedStatus == "FAILED" ? 0 : 1;
                        $resultAnalysis[$batchId]->failed += $currentAcademicTerm->failedStatus == "FAILED" ? 1 : 0;
                        if($request->IsVisibleGradeHeadInResultAnalysisCourseWise){
                            if($request->gradeHead == 'class'){
                                $resultAnalysis[$batchId]->analysisHead[strtoupper($currentAcademicTerm->class)]++;
                            }
                            elseif($request->gradeHead == 'grade'){
                                $resultAnalysis[$batchId]->analysisHead[strtoupper($currentAcademicTerm->grade)]++;
                            }
                            elseif($request->gradeHead == 'classGrade'){
                                $resultAnalysis[$batchId]->analysisHead[strtoupper($currentAcademicTerm->class.$currentAcademicTerm->grade)]++;
                            }
                        }
                        $student->isAbsentInSubject = 1;
                        foreach ( $student->academicTerm->subjects as $subject ) {
                            if ($subject->examAttendanceStatus == 'PRESENT') {
                                $student->isAbsentInSubject = 0;
                                break;
                            }
                        }
                        if($request->absenteesAsFailedStatus){
                            $resultAnalysis[$batchId]->appeared++;
                        }
                        else{
                            if (!$student->isAbsentInSubject) {
                                $resultAnalysis[$batchId]->appeared++;
                            }
                            else{
                                $resultAnalysis[$batchId]->absent++;
                                $resultAnalysis[$batchId]->failed -=1;
                            }
                        }
                    }
                }
                foreach($resultAnalysis as $singleResultAnalysis){
                    $singleResultAnalysis->passPercentage = round ( ( 100 * $singleResultAnalysis->passed / ($singleResultAnalysis->appeared ? $singleResultAnalysis->appeared : 0 )), 2);                    
                }
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $resultAnalysis;
    }
     /**
     * get Regular Exam Student Wise Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamStudentWiseResultAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $StudentWiseResultAnalysisRequest = new \stdClass;
            $StudentWiseResultAnalysisRequest->gradeClass = $searchRequest->gradeClass; 
            $StudentWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $StudentWiseResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId; 
            $StudentWiseResultAnalysisRequest->groupId = $searchRequest->examRegBatchIds; 
            $resultAnalysis = $this->getStudentWiseResultAnalysis($StudentWiseResultAnalysisRequest);
            if(empty($resultAnalysis->batches)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Entry In This Exam Registration");
            }
            else{
                $templateName = "StudentWiseResultAnalysisTemplate";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "<style>
                        h6 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                        table, th, td {border: 1px solid black;border-collapse: collapse;}
                        </style>";
                    $prtContent .= '</head><title>Student Wise Result Anaysis</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 210;
                    $totalHeight = 297;
                    $options = array(
                        'page-width'     => $totalHeight."mm",
                        'page-height'    => $totalWidth."mm",
                        'dpi'            => 96,
                        'margin-top' => "9mm",
                        'margin-left' => "1mm",
                        'margin-right' => "1mm",
                        'margin-bottom' => "9mm",
                        // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                        'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                    );
                $programResult = new \stdClass;
                $programResult->dispalyHtmlData = $responseHtml;
                $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
    public function getStudentWiseResultAnalysis($request){
        $request = $this->realEscapeObject($request);
        try{
            $batches = [];
            $resultAnalysis = new \stdClass;
            $searchRequest = new ConsolidatedMarkReportRequest;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->academicTermId = $request->academicTermId;
            $searchRequest->groupId = $request->groupId;
            $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
            // $studentMarkDetails = $this->getMarkReportDummyData();
            if($studentMarkDetails)
            {
                foreach($studentMarkDetails as $student) {
                    $studentDisplay = new \stdClass;
                    if ($student->studentDetails->registerNo !== NULL ) {
                        $studentDisplay->registerNo = $student->studentDetails->registerNo;
                        $studentDisplay->percentage = round(100 * ( $student->markObtained / $student->totalMarks),2);
                    }
                    $academicTerm = reset(array_filter(reset($student->academicTerms)->markHistory,function($value)use($request){
                        return $value->examRegistrationId == $request->examRegistrationId;
                    }));
                    $semesterClass = $academicTerm->class;
                    $studentDisplay->cgpa = round($academicTerm->sgpa, 2);
                    if ($request->gradeClass) {
                        if (strtoupper($semesterClass) != strtoupper($request->gradeClass)) {
                            $studentDisplay->registerNo = NULL;
                        }
                    }
                    if ($studentDisplay->registerNo !== NULL ) {
                        $studentDisplay->name = $student->studentDetails->name;
                        $studentDisplay->gender = $student->studentDetails->gender;
                        $studentDisplay->class = $semesterClass;
                        $studentDisplay->totalMarkObtained = $student->markObtained;
                        $batches[$student->studentDetails->batchId]->students[$student->studentDetails->id] = $studentDisplay;
                        $batches[$student->studentDetails->batchId]->batchName = $student->studentDetails->batchName;
                    }
                }
                $resultAnalysis->batches = $batches;
            }       
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        
        return $resultAnalysis;
    }
   /**
     * get Regular Exam Grade Report Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamGradeReportResultAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $gradeReportResultAnalysisRequest = new \stdClass;
            $gradeReportResultAnalysisRequest->gradeClass = $searchRequest->gradeClass; 
            $gradeReportResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId; 
            $request = new \stdClass;
            $request->courseTypeId = $searchRequest->courseTypeId;
            $request->examRegistrationId = $searchRequest->examRegistrationId;
            $gradeSchemes = GradeSchemeService::getInstance()->getAllGradeScemesByCurriculum($request);
            foreach($gradeSchemes as $gradeScheme){
                $gradeScheme->properties = json_decode($gradeScheme->properties);
                $gradeScheme->className = $gradeScheme->properties->class;
                $gradeScheme->grade = $gradeScheme->name;
                $gradeNames[strtoupper($gradeScheme->grade)] = strtoupper($gradeScheme->grade);
                $classHeaderNames[strtoupper($gradeScheme->grade)] = strtoupper($gradeScheme->grade);
            }
            $uniqueGrades = array_unique($gradeNames);
            $resultAnalysis = $this->getGradeReportResultAnalysis($gradeReportResultAnalysisRequest);
            if(empty($resultAnalysis)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Entry In This Exam Registration");
            }
            else{
                $templateName = "GradeReportResultAnalysisTemplate";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ,'uniqueGrades'=>$uniqueGrades ,'classHeaderNames'=>$classHeaderNames ]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "<style>
                        h6 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                        table, th, td {border: 1px solid black;border-collapse: collapse;}
                        </style>";
                    $prtContent .= '</head><title>Student Wise Result Anaysis</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 210;
                    $totalHeight = 297;
                    $options = array(
                        'page-width'     => $totalHeight."mm",
                        'page-height'    => $totalWidth."mm",
                        'dpi'            => 96,
                        'margin-top' => "9mm",
                        'margin-left' => "1mm",
                        'margin-right' => "1mm",
                        'margin-bottom' => "9mm",
                        // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                        'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                    );
                $programResult = new \stdClass;
                $programResult->dispalyHtmlData = $responseHtml;
                $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
    public function getGradeReportResultAnalysis($request)
    {
        $request = $this->realEscapeObject($request);
        try{
            $resultAnalysis = [];
            $searchRequest = new ConsolidatedMarkReportRequest;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
            // $studentMarkDetails = $this->getMarkReportDummyData();
            if($studentMarkDetails){
                foreach($studentMarkDetails as $student){
                    $batchName = $student->studentDetails->batchName;
                    $resultAnalysis[$batchName]->batchId = $student->studentDetails->batchId;
                    $resultAnalysis[$batchName]->batchName = $student->studentDetails->batchName;
                    $resultAnalysis[$batchName]->appeared++;
                    $student->isFailedAnySubjectInExamRegistration = false;
                    $semesterMarkDetails = reset(array_filter(reset($student->academicTerms)->markHistory,function($value)use($request){
                        return $value->examRegistrationId == $request->examRegistrationId;
                    }));
                    $resultAnalysis[$batchName]->grade[strtoupper($semesterMarkDetails->grade)]++;
                    foreach ( $student->academicTerms as $academicTerm ) {
                        foreach ( $academicTerm->subjects as $subject ){
                            if($subject->isFailed == "FAILED"){
                                $student->isFailedAnySubjectInExamRegistration = true;
                            }
                        }
                    }
                    if ($student->isFailedAnySubjectInExamRegistration) {
                        $resultAnalysis[$batchName]->failed += $student->isFailedAnySubjectInExamRegistration ? 1 : 0;
                    }
                    else{
                        $resultAnalysis[$batchName]->passed += $student->isFailedAnySubjectInExamRegistration ? 0 : 1;
                    }                   
                }
                foreach($resultAnalysis as $singleResultAnalysis){
                    $singleResultAnalysis->passPercentage = round ( ( 100 * $singleResultAnalysis->passed / $singleResultAnalysis->appeared ), 2);                    
                }
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $resultAnalysis;
    }
     /**
     * get Regular Exam Statistical Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamStatisticalAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try
        {
            $genders = [
                "male"=>"male",
                "female"=>"female"
            ];
            $commonTypeArray = [];
            $totalResultAnalysis = [];
            $commonTypeHeadName = '';
            $addiionalDetails = new \stdClass;
            $gradeSchemeRequest = new \stdClass;
            $gradeSchemeRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $gradeSchemeRequest->gradeHead = $searchRequest->gradeHead ? $searchRequest->gradeHead : "grade";
            $gradeSchemeDetals = $this->getAllGradeSchemesDetailsByExamRegistration($gradeSchemeRequest);
            $uniqueClassNames = array_unique($gradeSchemeDetals->classNames);
            $statisticalResultAnalysisRequest = new \stdClass;
            $searchRuleRequest = new SearchRuleRequest;
            $searchRuleRequest->name = "REGULAR_EXAM_REPORT_RULE";
            $regularExamReportRuleArray = RuleService::getInstance()->searchRule($searchRuleRequest);
            if(!empty($regularExamReportRuleArray)){
                $IsConsiderNotAppearedWhenStudentAbsentInExam = $regularExamReportRuleArray[0]->rule->IsConsiderNotAppearedWhenStudentAbsentInExam;
            }
            $statisticalResultAnalysisRequest->IsConsiderNotAppearedWhenStudentAbsentInExam = $IsConsiderNotAppearedWhenStudentAbsentInExam;
            $statisticalResultAnalysisRequest->gradeClass = $searchRequest->gradeHead ? $searchRequest->gradeHead : "grade"; 
            $statisticalResultAnalysisRequest->academicTermId = $searchRequest->academicTermIds;
            $statisticalResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $statisticalResultAnalysisRequest->groupId = $searchRequest->examRegBatchIds;
            $statisticalResultAnalysisRequest->uniqueClassNames = $uniqueClassNames;
            $statisticalResultAnalysisRequest->IsVisibleGradeHeadInResultAnalysisCourseWise = true; #Important For get gradescheme wise result
            $examRegistrationBatches = $searchRequest->examRegBatchIds;
            if(empty($examRegistrationBatches))
            {
                $batchRequest = new SearchExamRegistrationBatchRequest();
                $batchRequest->examRegistrationId = $searchRequest->examRegistrationId;
                $batchRequest->academicTermId = $searchRequest->academicTermIds;
                $examRegistrationBatches = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatch($batchRequest);
            }
            if($searchRequest->reportType == 'RELIGION_WISE')
            {
                $commonTypeArray = ReligionService::getInstance()->getAllReligion();
                $commonTypeHeadName = 'religionName';
                $addiionalDetails->headingNameForTemplate = "RELIGION WISE RESULT";
            }
            else if($searchRequest->reportType == 'CATEGORY_WISE')
            {
                $commonTypeArray = AdmissionService::getInstance()->getStudentReservation();
                $commonTypeHeadName = 'reservName';
                $addiionalDetails->headingNameForTemplate = "CATEGORY WISE RESULT";
            }
            else if($searchRequest->reportType == 'COURSE_WISE')
            {
                $batchRequest = new SearchExamRegistrationBatchRequest();
                $batchRequest->examRegistrationId = $searchRequest->examRegistrationId;
                $batchRequest->academicTermId = $searchRequest->academicTermIds;
                if(!empty($searchRequest->examRegBatchIds)){
                    $batchRequest->groupId = $searchRequest->examRegBatchIds;
                }
                $commonTypeArray = ExamRegistrationBatchService::getInstance()->searchExamRegistrationBatch($batchRequest);
                $commonTypeHeadName = 'groupName';
                $addiionalDetails->headingNameForTemplate = "COURSE WISE RESULT";
                
            }
            $overallResultAnalysis = [];
            foreach ( $commonTypeArray as $commonType ) {
                $totalAnalysis = new \stdClass();
                $genderResultAnalysis = [];
                $totClasses=[];
                $prevGender = '';
                foreach ( $examRegistrationBatches as $batch ) {
                    if( $batch->id){
                        $batchId = $batch->id;
                    }
                    else{
                        $batchId = $batch;
                    }
                    foreach ( $genders as $gender ) {
                        $statisticalResultAnalysisRequest->gender = $gender;
                        $statisticalResultAnalysisRequest->batchId = $batchId; 
                        $resultAnalysis = $this->getCourseWiseResultAnalysis($statisticalResultAnalysisRequest);
                        foreach($resultAnalysis as $analysis){
                            if($genderResultAnalysis){ 
                                foreach($uniqueClassNames as $className)
                                {
                                    $totClasses[strtoupper($className)] = $analysis->class[strtoupper($className)] + $genderResultAnalysis[$prevGender]->class[strtoupper($className)];
                                }
                                
                            }
                            $totalAnalysis->appeared += $analysis->appeared ;
                            $totalAnalysis->enrolled += $analysis->enrolled ;
                            $totalAnalysis->passed += $analysis->passed;
                            $totalAnalysis->failed += $analysis->failed;
                            $prevGender = $gender;
                            if($genderResultAnalysis[$gender]){
                                $genderResultAnalysis[$gender]->appeared += $analysis->appeared ;
                                $genderResultAnalysis[$gender]->enrolled += $analysis->enrolled ;
                                $genderResultAnalysis[$gender]->passed += $analysis->passed;
                                $genderResultAnalysis[$gender]->failed += $analysis->failed;
                            }
                            else{
                                $genderResultAnalysis[$gender] = $analysis;
                            }
                        }
                    }
                }
                $totalAnalysis->class = $totClasses;
                $totalAnalysis->passPercentage =  round ( ( 100 * $totalAnalysis->passed / $totalAnalysis->appeared ? $totalAnalysis->appeared : 0 ), 2);
                if($genderResultAnalysis){
                    $genderResultAnalysis['total'] = $totalAnalysis;
                }
                $overallResultAnalysis[$commonType->$commonTypeHeadName] = $genderResultAnalysis;
                foreach($genderResultAnalysis as $key => $genderAnalysis){
                    $totalResultAnalysis[$key]->appeared += $genderAnalysis->appeared;
                    $totalResultAnalysis[$key]->enrolled += $genderAnalysis->enrolled;
                    $totalResultAnalysis[$key]->passed += $genderAnalysis->passed;
                    $totalResultAnalysis[$key]->failed += $genderAnalysis->failed;
                    foreach($uniqueClassNames as $className)
                    {
                        $totalResultAnalysis[$key]->class[strtoupper($className)] += $genderAnalysis->class[strtoupper($className)];
                    }
                }
            }
            foreach($totalResultAnalysis as $singleAnalysis){
                $singleAnalysis->passPercentage =  round ( ( 100 * $singleAnalysis->passed / $singleAnalysis->appeared ? $singleAnalysis->appeared : 0 ), 2);
            }
            
            $templateName = "StatisticalResultAnalysisTemplate";
            $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'overallResultAnalysis'=>$overallResultAnalysis,'totalResultAnalysis'=>$totalResultAnalysis,'addiionalDetails'=>$addiionalDetails,'uniqueClassNames'=>$uniqueClassNames ,'classHeaderNames'=>$gradeSchemeDetals->classHeaderNames ]);
            $prtContent = NULL;
                $prtContent .= '<html><head>';
                $prtContent .= "<style>
                    h6 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                    table, th, td {border: 1px solid black;border-collapse: collapse;}
                    </style>";
                $prtContent .= '</head><title>Student Wise Result Anaysis</title><body>';
                $prtContent .= $responseHtml;
                $prtContent .= '</body></html>';
                $totalWidth = 210;
                $totalHeight = 297;
                $options = array(
                    'page-width'     => $totalHeight."mm",
                    'page-height'    => $totalWidth."mm",
                    'dpi'            => 96,
                    'margin-top' => "9mm",
                    'margin-left' => "1mm",
                    'margin-right' => "1mm",
                    'margin-bottom' => "9mm",
                    // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                    'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                );
            $programResult = new \stdClass;
            $programResult->dispalyHtmlData = $responseHtml;
            $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
      /**
     * print All absent Students For Special Exam
     * @param $searchRequest 
     * @return $response 
     */
    public function getRegularExamSemesterWiseAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $response = new \stdClass;
            $request = new \stdClass;
            $additionalDetails = new \stdClass;
            $response = new \stdClass;
            $request = new \stdClass;
            $additionalDetails->collageName = $GLOBALS['COLLEGE_NAME'];
            if(!empty($searchRequest->percentageType) && $searchRequest->percentageType !='BETWEEN' && !empty($searchRequest->precentageInput)){
                $additionalDetails->isPercentageFilter = true;
                if($searchRequest->percentageType == 'GREATER_THAN'){
                    $additionalDetails->percentageMsg = "List of students having percentage greater than ".$searchRequest->precentageInput;
                }
                elseif($searchRequest->percentageType == 'LESS_THAN'){
                    $additionalDetails->percentageMsg = "List of students having percentage less than ".$searchRequest->precentageInput;
                }
                elseif($searchRequest->percentageType == 'EQUAL_TO'){
                    $additionalDetails->percentageMsg = "List of students having percentage equal to ".$searchRequest->precentageInput;
                }
            }
            if(!empty($searchRequest->SGPAType) && !empty($searchRequest->SGPAInput)){
                $additionalDetails->isPercentageFilter = true;
                if($searchRequest->SGPAType == 'GREATER_THAN'){
                    $additionalDetails->SGPAMsg = "List of students having SGPA greater than ".$searchRequest->precentageInput;
                }
                elseif($searchRequest->SGPAType == 'LESS_THAN'){
                    $additionalDetails->SGPAMsg = "List of students having SGPA less than ".$searchRequest->precentageInput;
                }
                elseif($searchRequest->SGPAType == 'EQUAL_TO'){
                    $additionalDetails->SGPAMsg = "List of students having percentage equal to ".$searchRequest->precentageInput;
                }
            }
            $studentDetails = [];
            $studentDetailsArray = [];
            $request->groupId = $searchRequest->groupId;
            $request->academicTermId = $searchRequest->academicTermId;
            $request->departmentId = $searchRequest->departmentId;
            $request->courseType = $searchRequest->courseType;
            $request->percentageType = $searchRequest->percentageType;
            $request->precentageInput = $searchRequest->precentageInput;
            $request->fromPercent = $searchRequest->fromPercent;
            $request->toPercent = $searchRequest->toPercent;
            $request->fromSgpaInput = $searchRequest->fromSgpaInput;
            $request->toSgpaInput = $searchRequest->toSgpaInput;
            $request->SGPAType = $searchRequest->SGPAType;
            $request->SGPAInput = $searchRequest->SGPAInput;
            $studentsArray = $this->getAllStudentDetailsListForSemesterWise($request);
            if(empty($studentsArray)){
                throw new ExamControllerException(ExamControllerException::NO_STUDENTS_IN_THIS_EXAM_REGISTRATION,"No Students In This Exam Registration");
            }
            else{
                $additionalDetails->examRegistrationName = $studentsArray[0]->examRegistrationName;
                $additionalDetails->groupName = $studentsArray[0]->groupName;
                $additionalDetails->academicTerm = $studentsArray[0]->academicTerm;
                $additionalDetails->courseType = $studentsArray[0]->courseType;
                foreach($studentsArray as $student){
                    $studentDetails[$student->studentId]->studentId = $student->studentId;
                    $studentDetails[$student->studentId]->studentName = $student->studentName;
                    $studentDetails[$student->studentId]->regNo = $student->regNo;
                    $studentDetails[$student->studentId]->admissionNo = $student->admissionNo;
                    $studentDetails[$student->studentId]->percentage = $student->percentage;
                    $studentDetails[$student->studentId]->sgpa = $student->sgpa;
                    $studentDetails[$student->studentId]->failedStatus = $student->failedStatus;
                    $studentDetails[$student->studentId]->roundOff = $student->roundOff;
                    $studentDetails[$student->studentId]->courseType = $student->courseType;
                }
            }
            $studentDetailsArray = array_values($studentDetails);
            if(empty($studentDetailsArray)){
                throw new ExamControllerException(ExamControllerException::NO_STUDENTS_IN_THIS_EXAM_REGISTRATION,"No Students In This Special Exam Registration");
            }
            else
            {
                $templateName = "SemesterWiseResultAnalysis";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'students'=>$studentDetailsArray ,'additionalDetails'=>$additionalDetails]);
                $prtContent = NULL;
                $prtContent .= '<html><head>';
                $prtContent .= "<style>
                    h6 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                    table, th, td {border: 1px solid black;border-collapse: collapse;}
                    </style>";
                $prtContent .= '</head><title>Semester Wise Result Analysis Report</title><body>';
                $prtContent .= $responseHtml;
                $prtContent .= '</body></html>';
                $totalWidth = 210;
                $totalHeight = 297;
                $options = array(
                    'page-width'     => $totalWidth."mm",
                    'page-height'    => $totalHeight."mm",
                    'dpi'            => 96,
                    'margin-top' => "9mm",
                    'margin-left' => "1mm",
                    'margin-right' => "1mm",
                    'margin-bottom' => "9mm",
                    // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                    'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                );
            $programResult = new \stdClass;
            $programResult->dispalyHtmlData = $responseHtml;
            $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
                return  $programResult;
            }
        }
         catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $response;
    }
    /**
     * get All Students For Special Exam,
     * @param $searchRequest 
     * @return $response 
     */
    public function getAllStudentDetailsListForSemesterWise($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $sortBy = " ORDER BY sa.regNo ASC";
            $whereQuery = "";
            if(!empty($searchRequest->groupId)){
                $whereQuery .= " AND eerb.groups_id = '$searchRequest->groupId";
            }
            if(!empty($searchRequest->academicTermId)){
                $whereQuery .= " AND CAST(eerb.properties ->> '$.academicTermId'AS CHAR) = '$searchRequest->academicTermId";
            }
            if(!empty($searchRequest->departmentId)){
                $whereQuery .= " AND g.properties ->> '$.departmentId' = '$searchRequest->departmentId";
            }
            
            $query = "SELECT DISTINCT
                        sa.studentID as studentId,
                        sa.studentName,
                        sa.regNo,
                        sa.admissionNo,
                        g.name as groupName,
                        g.properties ->> '$.startYear' as admissionYear,
                        act.name as academicTerm,
                        eer.id AS examRegistrationId,
                        eer.name as examRegistrationName,
                        esmd.mark_history AS markHistory,
                        ct.course_Type AS courseType
                    FROM
                        `groups` g
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.groups_id = g.id
                    INNER JOIN ec_exam_registration_subject eers ON
                        eers.ec_exam_registration_batch_id = eerb.id
                    INNER JOIN ec_exam_registration eer ON
                        eer.id = eerb.ec_exam_registration_id AND eer.type = 'REGULAR'
                    INNER JOIN ec_student_assessment_registration esar ON
                        esar.am_assessment_id = eers.am_assessment_id AND 
                        CAST(esar.properties ->> '$.registrationStatus' AS CHAR) = 'REGISTERED' AND 
                        CAST(esar.properties ->> '$.feeStatus' AS CHAR) = 'PAID' AND 
                        esar.ec_exam_registration_type = eer.type
                    INNER JOIN studentaccount sa ON 
                        sa.studentID = esar.student_id
                    INNER JOIN  academic_term act ON 
                        act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) 
                    INNER JOIN ec_semester_mark_details esmd ON
                        esmd.groups_id = g.id AND esmd.academic_term_id = act.id AND esmd.student_id = sa.studentID
                    LEFT JOIN program p ON
                        p.id = CAST(g.properties->>'$.programId' AS CHAR)
                    LEFT JOIN course_type ct ON
                        ct.courseTypeID = p.course_type_id
                    WHERE 1=1 AND eer.trashed IS NULL";
            $studentsDetails = $this->executeQueryForList($query.$whereQuery.$sortBy);
            foreach($studentsDetails as $key => $student){
                $student->markHistory = json_decode($student->markHistory);
                $semesterMarkDetails = reset(array_filter($student->markHistory,function($value)use($student){
                    return $value->examRegistrationId == $student->examRegistrationId;
                }));
                $student->roundOff = $student->admissionYear < 2019 ?  2 : 3;
                $student->roundOff = $student->courseType == "PG_DIPLOMA" ?  2 : $student->roundOff;
                $student->sgpa = round($semesterMarkDetails->sgpa, $student->roundOff);
                $student->percentage = round($semesterMarkDetails->percentage,2);
                $semesterMarkDetails->percentage = round($semesterMarkDetails->percentage,2);
                $student->failedStatus = $semesterMarkDetails->failedStatus;
                if((!empty($searchRequest->percentageType) && $searchRequest->percentageType != 'BETWEEN' && !empty($searchRequest->precentageInput)) || ($searchRequest->percentageType == 'BETWEEN' && (!empty($searchRequest->fromPercent) || $searchRequest->fromPercent == 0) && !empty($searchRequest->toPercent))){
                    if($searchRequest->percentageType == 'GREATER_THAN'){
                        if($semesterMarkDetails->percentage < $searchRequest->precentageInput){
                            unset($studentsDetails[$key]);
                        }
                    }
                    elseif($searchRequest->percentageType == 'LESS_THAN'){
                        if($semesterMarkDetails->percentage > $searchRequest->precentageInput){
                            unset($studentsDetails[$key]);
                        }
                    }
                    elseif($searchRequest->percentageType == 'EQUAL_TO'){
                        if($semesterMarkDetails->percentage != $searchRequest->precentageInput){
                            unset($studentsDetails[$key]);
                        }
                    }
                    elseif($searchRequest->percentageType == 'BETWEEN'){
                        if($searchRequest->fromPercent <= $semesterMarkDetails->percentage && $searchRequest->toPercent >= $semesterMarkDetails->percentage){
                            //skip
                        }
                        else{
                            unset($studentsDetails[$key]);
                        }
                    }
                }
                if((!empty($searchRequest->SGPAType) && $searchRequest->SGPAType != 'BETWEEN' && !empty($searchRequest->SGPAInput)) || ($searchRequest->SGPAType == 'BETWEEN' && (!empty($searchRequest->fromSgpaInput) || $searchRequest->fromSgpaInput == 0) && !empty($searchRequest->toSgpaInput))){
                    if($searchRequest->SGPAType == 'GREATER_THAN'){
                        if($student->sgpa < $searchRequest->SGPAInput){
                            unset($studentsDetails[$key]);
                        }
                    }
                    elseif($searchRequest->SGPAType == 'LESS_THAN'){
                        if($student->sgpa > $searchRequest->SGPAInput){
                            unset($studentsDetails[$key]);
                        }
                    }
                    elseif($searchRequest->SGPAType == 'EQUAL_TO'){
                        if($student->sgpa != $searchRequest->SGPAInput){
                            unset($studentsDetails[$key]);
                        }
                    }
                    elseif($searchRequest->SGPAType == 'BETWEEN'){
                        if($searchRequest->fromSgpaInput <= $student->sgpa && $searchRequest->toSgpaInput >= $student->sgpa && $student->failedStatus == 'PASSED'){
                            //skip
                        }
                        else{
                            unset($studentsDetails[$key]);
                        }
                    }
                }
            }
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $studentsDetails;
    }
    public function getAllGradeSchemesDetailsByExamRegistration($request){
        $request = $this->realEscapeObject($request);
        $searchRequest = new \stdClass;
        $searchRequest->courseTypeId = $request->courseTypeId;
        $searchRequest->admissionYear = $request->admissionYear;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->academicTermId = $request->academicTermId;
        try{
            $gradeSchemeResponse = new \stdClass;
            $gradeSchemes = GradeSchemeService::getInstance()->getAllExamRegistrationGradeSchemes($searchRequest);
            foreach($gradeSchemes as $key => $gradeScheme){
                $gradeScheme->properties = json_decode($gradeScheme->properties);
                $gradeScheme->className = $gradeScheme->properties->class;
                $gradeScheme->grade = $gradeScheme->name;
                $classNames[strtoupper($gradeScheme->className)] = strtoupper($gradeScheme->className);
                if ($request->excludeFailedGrade == true && $gradeScheme->properties->failStatus ) {
                    unset($gradeSchemes[$key]);
                }
            }
            if($request->gradeHead == 'class'){
                foreach($gradeSchemes as $gradeScheme){
                    $classHeaderNames[strtoupper($gradeScheme->className)] = strtoupper($gradeScheme->className);
                }
            }
            elseif($request->gradeHead == 'grade'){
                foreach($gradeSchemes as $gradeScheme){
                    $classHeaderNames[strtoupper($gradeScheme->grade)] = strtoupper($gradeScheme->grade);
                }
            }
            elseif($request->gradeHead == 'classGrade'){
                foreach($gradeSchemes as $gradeScheme){
                    $classHeaderNames[strtoupper($gradeScheme->className.$gradeScheme->grade)] = strtoupper($gradeScheme->className)."(". strtoupper($gradeScheme->grade).")";
                }
            }
            $gradeSchemeResponse->classHeaderNames = $classHeaderNames;
            $gradeSchemeResponse->classNames = $classNames;
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $gradeSchemeResponse;
    }
    public function getAllSubjectGradeSchemesDetailsByExamRegistration($request){
        $request = $this->realEscapeObject($request);
        $searchRequest = new \stdClass;
        $searchRequest->courseTypeId = $request->courseTypeId;
        $searchRequest->admissionYear = $request->admissionYear;
        $searchRequest->examRegistrationId = $request->examRegistrationId;
        $searchRequest->academicTermId = $request->academicTermId;
        try{
            $gradeSchemeResponse = new \stdClass;
            $gradeSchemes = GradeSchemeService::getInstance()->getAllSubjectGradeSchemes($searchRequest);
            foreach($gradeSchemes as $key => $gradeScheme){
                $gradeScheme->properties = json_decode($gradeScheme->properties);
                $gradeScheme->className = $gradeScheme->properties->class;
                $gradeScheme->grade = $gradeScheme->name;
                $classNames[strtoupper($gradeScheme->className)] = strtoupper($gradeScheme->className);
                if ($request->excludeFailedGrade == true && $gradeScheme->properties->failStatus ) {
                    unset($gradeSchemes[$key]);
                }
            }
            if($request->gradeHead == 'class'){
                foreach($gradeSchemes as $gradeScheme){
                    $classHeaderNames[strtoupper($gradeScheme->className)] = strtoupper($gradeScheme->className);
                }
            }
            elseif($request->gradeHead == 'grade'){
                foreach($gradeSchemes as $gradeScheme){
                    $classHeaderNames[strtoupper($gradeScheme->grade)] = strtoupper($gradeScheme->grade);
                }
            }
            elseif($request->gradeHead == 'classGrade'){
                foreach($gradeSchemes as $gradeScheme){
                    $classHeaderNames[strtoupper($gradeScheme->className.$gradeScheme->grade)] = strtoupper($gradeScheme->className)."(". strtoupper($gradeScheme->grade).")";
                }
            }
            $gradeSchemeResponse->classHeaderNames = $classHeaderNames;
            $gradeSchemeResponse->classNames = $classNames;
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $gradeSchemeResponse;
    }
    
     /**
     * get All Registered Students Details
     * @param $searchRequest 
     */
    public function getAllRegistredStudentOverAllDetails($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $orderBy = "ORDER BY spa.properties->>'$.registerNumber' ASC";
            $whereQuery = "";
            $joinQuery = "";
            if(!empty($searchRequest->degreeId)) {
                $degreeIdString = is_array($searchRequest->degreeId) ? "'" . implode("','",$searchRequest->degreeId) . "'" : "'".$searchRequest->degreeId."'";
                $whereQuery .= " AND deg.id IN ( $degreeIdString )";
            }
            if(!empty($searchRequest->groupId)) {
                $groupIdString = is_array($searchRequest->groupId) ? "'" . implode("','",$searchRequest->groupId) . "'" : "'".$searchRequest->groupId."'";
                $whereQuery .= " AND g.id IN ( $groupIdString )";
            }
            if(!empty($searchRequest->academicTermId)) {
                $semesterIdString = is_array($searchRequest->academicTermId) ? "'" . implode("','",$searchRequest->academicTermId) . "'" : "'".$searchRequest->academicTermId."'";
                $whereQuery .= " AND act.id IN ( $semesterIdString )";
            }
            if(!empty($searchRequest->examRegistrationId)) {
                $examRegistrationIdString = is_array($searchRequest->examRegistrationId) ? "'" . implode("','",$searchRequest->examRegistrationId) . "'" : "'".$searchRequest->examRegistrationId."'";
                $whereQuery .= " AND eer.id IN ( $examRegistrationIdString )";
            }
            if(!empty($searchRequest->studentId)) {
                $studentIdString = is_array($searchRequest->studentId) ? "'" . implode("','",$searchRequest->studentId) . "'" : "'".$searchRequest->studentId."'";
                $whereQuery .= " AND sa.studentID IN ( $studentIdString )";
            }
            if(!empty($searchRequest->academicPaperSubjectId)) {
                $academicPaperSubjectIdString = is_array($searchRequest->academicPaperSubjectId) ? "'" . implode("','",$searchRequest->academicPaperSubjectId) . "'" : "'".$searchRequest->academicPaperSubjectId."'";
                $whereQuery .= " AND aps.id IN ( $academicPaperSubjectIdString )";
            }
            if(!empty($searchRequest->religionId)) {
                $religionIdString = is_array($searchRequest->religionId) ? "'" . implode("','",$searchRequest->religionId) . "'" : "'".$searchRequest->religionId."'";
                $whereQuery .= " AND sa.religionID IN ( $religionIdString )";
            }
            if(!empty($searchRequest->reservationId)) {
                $reservationIdString = is_array($searchRequest->reservationId) ? "'" . implode("','",$searchRequest->reservationId) . "'" : "'".$searchRequest->reservationId."'";
                $whereQuery .= " AND sa.reservationID IN ( $reservationIdString )";
            }
            if(!empty($searchRequest->campusTypeId)) {
                $campusTypeIdString = is_array($searchRequest->campusTypeId) ? "'" . implode("','",$searchRequest->campusTypeId) . "'" : "'".$searchRequest->campusTypeId."'";
                $whereQuery .= " AND sa.campus_type_id IN ( $campusTypeIdString )";
            }
            if(!empty($searchRequest->gender)) {
                $genderString = is_array($searchRequest->gender) ? "'" . implode("','",$searchRequest->gender) . "'" : "'".$searchRequest->gender."'";
                $whereQuery .= " AND sa.studentGender IN ( $genderString )";
            }
            if(!empty($searchRequest->excludeMinorHonor)) {
                $whereQuery .= " AND  ( (eer.properties ->> '$.isHonorCourse' IS NULL OR eer.properties ->> '$.isHonorCourse' != '1') AND (eer.properties ->> '$.isMinorCourse' IS NULL OR eer.properties ->> '$.isMinorCourse' != '1'))";
            }
            // this case to fetch fe subject details
            // by default get registered subject (not include fe subjects)
            if(!empty($searchRequest->isFetchWithFeSubject)) {
                $joinQuery = " INNER JOIN ec_student_assessment_registration esar ON
                    esar.am_assessment_id = eers.am_assessment_id AND 
                    esar.ec_exam_registration_type = eer.type AND
                    ((CAST(esar.properties ->> '$.registrationStatus' AS CHAR) = 'REGISTERED' AND 
                    CAST(esar.properties ->> '$.feeStatus' AS CHAR) = 'PAID' ) OR 
                    CAST(esar.properties->>'$.studentAttendanceStatus' AS CHAR) = 'FE' AND
                    CAST(esar.properties->>'$.registrationStatus' AS CHAR) ='NOT_REGISTERED')";
            }
            else{
                $joinQuery = " INNER JOIN ec_student_assessment_registration esar ON
                    esar.am_assessment_id = eers.am_assessment_id 
                    AND esar.properties ->>'$.feeStatus' = 'PAID' 
                    AND esar.properties ->>'$.registrationStatus' = 'REGISTERED'
                    AND esar.ec_exam_registration_type = eer.type";
            }
            $query = "SELECT DISTINCT
                        sa.studentID AS id,
                        sa.studentID AS studentId,
                        sa.studentName,
                        sa.casteID as casteId,
                        caste.casteName as casteName,
                        sa.reservationID as reservationId,
                        category.reservationName as reservationName,
                        spa.properties->>'$.registerNumber' as regNo,
                        sa.rollNo,
                        sa.admissionNo,
                        sa.myImage,
                        sa.studentGender,
                        g.id AS groupId,
                        g.name AS groupName,
                        act.id AS academicTermId,
                        act.name AS academicTermName,
                        dept.deptID,
                        deg.name AS degreeName,
                        deg.id AS degreeId,
                        dept.deptName,
                        ct.courseTypeID,
                        ct.typeName AS courseType,
                        ct.course_Type AS courseTypeMethod, 
                        g.properties ->> '$.startYear' AS academicYear,
                        eer.type AS latestExamType,
                        eer.properties ->> '$.examYear' AS latestExamYear,
                        eer.properties ->> '$.examMonth' AS latestExamMonth,
                        
                        esmdsem.mark_details ->>'$.sgpa' AS semesterSgpa,
                        esmdsem.mark_details ->>'$.percentage' AS semesterPercentage,
                        esmdsem.mark_details ->>'$.grade' AS semesterGrade,
                        esmdsem.mark_details ->>'$.markObtained' AS semesterMarkObtained,
                        esmdsem.mark_details ->>'$.class' AS semesterClass,
                        esmdsem.mark_details ->>'$.totalMarks' AS semesterTotalMarks,
                        esmdsem.mark_details ->>'$.credit' AS semesterCredit,
                        esmdsem.mark_details ->>'$.gradePoint' AS semesterGradePoint,
                        esmdsem.mark_details ->>'$.creditGradePoint' AS semesterCreditGradePoint,
                        esmdsem.mark_history AS semesterMarkHistory,
                        esmdsem.failed_status AS semesterFailedStatus,
                        s.code AS subjectCode,
                        aps.properties ->> '$.syllabusName' AS syllabusName,
                        s.name AS subjectName,
                        eers.cm_academic_paper_subjects_id AS academicPaperSubjectId,
                        esmdsub.mark_details ->>'$.markObtained' AS subjectMarkObtained,
                        esmdsub.mark_details ->>'$.internalGrade' AS subjectInternalGrade,
                        esmdsub.mark_details ->>'$.internalGradePoint' AS subjectInternalGradePoint,
                        esmdsub.mark_details ->>'$.externalGrade' AS subjectExtrenalGrade,
                        esmdsub.mark_details ->>'$.externalGradePoint' AS subjectExternalGradePoint,
                        esmdsub.mark_details ->>'$.wgpa' AS subjectWgpa,
                        esmdsub.mark_details ->>'$.class' AS subjectClass,
                        esmdsub.percentage AS subjectPercentage,
                        esmdsub.grade AS subjectGrade,
                        esmdsub.failed_status AS subjectFailedStatus,
                        esmdsub.mark_details ->>'$.externalResultStatus' AS isExternalFailed,
                        esmdsub.mark_details ->>'$.internalResultStatus' AS isInternalFailed,
                        esmdsub.mark_details ->>'$.markNeededToPass' AS markNeededToPass,
                        esmdsub.mark_details ->>'$.markNeededToPassWithoutGraceMark' AS markNeededToPassWithoutGraceMark,
                        esmdsub.mark_details ->>'$.internalAttendanceStatus' AS subjectInternalAttendance,
                        esmdsub.mark_details ->>'$.externalMark' AS externalMark,
                        esmdsub.mark_details ->>'$.resultStatusWithoutGraceMark' AS resultStatusWithoutGraceMark,
                        esmdsub.mark_details ->>'$.attendanceStatus' AS subjectExamAttendanceStatus, 
                        esmdsub.mark_details ->>'$.revaluationId' AS subjectRevaluationId,
                        esmdsub.mark_details ->>'$.hasRevaluationMark' AS subjectHasRevaluationMark,
                        esmdsub.mark_details ->>'$.withoutRevaluationIsFailed' AS subjectWithoutRevaluationIsFailed,
                        esmdsub.mark_details ->>'$.studentAttendanceStatus' AS studentAttendanceStatus,
                        esmdsubcon.mark_details ->>'$.internalMark' AS internalMark,
                        esmdsubcon.mark_details ->>'$.attendanceStatus' AS subjectAttendanceStatus,
                        esmdsubcon.mark_details ->>'$.gradePoint' AS subjectGradePoint,
                        esmdsubcon.mark_details ->>'$.creditGradePoint' AS subjectCreditGradePoint,
                        esmdsubcon.mark_details ->>'$.credit' AS subjectCredit,
                        esmdsubcon.mark_details ->>'$.externalMaxMark' AS externalMaxMark,
                        esmdsubcon.mark_details ->>'$.internalMaxMark' AS internalMaxMark,
                        esmdsubcon.mark_details ->>'$.totalMarks' AS subjectTotalMarks,
                        esmdsubcon.mark_details ->>'$.isExternal' AS isExternal,
                        esmdsubcon.mark_details ->>'$.isInternal' AS isInternal,
                        esmdsubcon.mark_details ->>'$.categoryId' AS subjectCategoryId,
                        esmdsubcon.mark_details ->>'$.categoryName' AS subjectCategoryName,
                        esmdsubcon.mark_details ->>'$.categoryCode' AS subjectCategoryCode,
                        esmdsubcon.mark_details ->>'$.internalPassPercentage' AS subjectInternalPassPercentage,
                        esmdsubcon.mark_details ->>'$.externalPassPercentage' AS subjectExternalPassPercentage,
                        esmdsubcon.mark_details ->>'$.aggregatePassPercentage' AS subjectAggregatePassPercentage,
                        esmdsubcon.failed_status AS subjectConsolidatedFailedStatus,
                        esmdsubcon.mark_history AS subjectMarkHistory,
                        
                        ecmdcourse.mark_details ->>'$.cgpa' AS cgpa,
                        ecmdcourse.percentage AS overallPercentage,
                        ecmdcourse.mark_details ->>'$.grade' AS overallGrade,
                        ecmdcourse.mark_details ->>'$.class' AS overallClass,
                        ecmdcourse.mark_details ->>'$.markObtained' AS courseObtainedMark,
                        ecmdcourse.mark_details ->>'$.totalMarks' AS courseTotalMark,
                        ecmdcourse.mark_details ->>'$.creditxMark' AS courseCreditxMark,
                        ecmdcourse.mark_details ->>'$.creditGradePoint' AS courseCreditGradePoint,
                        ecmdcourse.mark_details ->>'$.credit' AS courseTotalCredit,
                        ecmdcourse.mark_details ->>'$.wgp' AS courseWgp,
                        ecmdcourse.mark_details ->>'$.wgpa' AS courseWgpa,
                        ecmdcourse.mark_details ->>'$.gradePoint' AS courseGradePoint,
                        ecmdcourse.failed_status AS courseFailedStatus,
                        eerb.properties AS examBatchProperties,
                        eserd.properties->>'$.isResultWithHeld' AS isResultWithHeld,
                        esar.properties->>'$.studentAttendanceStatus' AS studentAttendanceStatus
                        
                    FROM
                        `groups` g
                    INNER JOIN ec_exam_registration_batch eerb ON
                        eerb.groups_id = g.id
                    INNER JOIN ec_exam_registration_subject eers ON
                        eers.ec_exam_registration_batch_id = eerb.id
                    INNER JOIN  cm_academic_paper_subjects aps ON 
                        eers.cm_academic_paper_subjects_id = aps.id
                    INNER JOIN  v4_ams_subject s ON 
                        aps.ams_subject_id = s.id
                    INNER JOIN ec_exam_registration eer ON
                        eer.id = eerb.ec_exam_registration_id
                    $joinQuery
                    INNER JOIN ec_student_exam_registration_details eserd ON 
                        eserd.student_id = esar.student_id AND 
                        eserd.ec_exam_registration_id = eer.id 
                    INNER JOIN studentaccount sa ON 
                        sa.studentID = esar.student_id
                    INNER JOIN student_program_account spa
                        ON spa.student_id = sa.studentID
                    INNER JOIN department dept ON
                        dept.deptID = g.properties ->> '$.departmentId'
                    INNER JOIN  academic_term act ON 
                        act.id = CAST(eerb.properties ->> '$.academicTermId'AS CHAR) 
                    INNER JOIN program p ON
                        p.id = CAST(g.properties ->> '$.programId' AS CHAR)
                    INNER JOIN degree deg ON
                        deg.id = p.degree_id
                    INNER JOIN `course_type` ct ON
                        ct.courseTypeID = p.course_type_id
                    INNER JOIN ec_semester_mark_details esmdsem ON
                        esmdsem.groups_id = eerb.groups_id AND esmdsem.academic_term_id = act.id AND esmdsem.student_id = sa.studentID 
                    INNER JOIN ec_subject_mark_details esmdsub ON
                        esmdsub.ec_exam_registration_id = eerb.ec_exam_registration_id AND esmdsub.groups_id = eerb.groups_id AND esmdsub.cm_academic_paper_subjects_id = eers.cm_academic_paper_subjects_id AND esmdsub.student_id = sa.studentID 
                    INNER JOIN ec_consolidated_subject_mark_details esmdsubcon ON
                        esmdsubcon.groups_id = eerb.groups_id AND esmdsubcon.cm_academic_paper_subjects_id = eers.cm_academic_paper_subjects_id AND esmdsubcon.student_id = sa.studentID 
                    LEFT JOIN  ec_course_mark_details ecmdcourse ON
                        ecmdcourse.groups_id = eerb.groups_id AND ecmdcourse.student_id = sa.studentID 
                    LEFT JOIN student_caste caste ON 
                        caste.casteID = sa.casteID
                    LEFT JOIN reservation_students category ON 
                        category.reservationID = sa.reservationID
                    WHERE 1=1 AND (CAST(esar.properties ->> '$.syllabusSubType' AS CHAR) != 'MOOC' OR esar.properties ->> '$.syllabusSubType' IS NULL) ";
            $studentMarkDetails = $this->executeQueryForList($query.$whereQuery.$orderBy, $this->mapper[RegularExamReportServiceMapper::OVER_ALL_MARK_DETAILS]);
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $studentMarkDetails;
    }
    /**
     * Get Exam Valuation Report 
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getExamValuationReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        $staffSideMarkEntryUItype = CommonService::getInstance()->getSettings(SettingsConstents::EXAM_VALUATION, SettingsConstents::STAFF_SIDE_MARK_ENTRY_UI_FORMAT);
        $request = new \stdClass;
        $packetNoArray = [];
        $packetNoObjArray = [];
        $additionalDetails = new \stdClass;
        $registeredStudentsByBatch = [];
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->academicPaperSubjectId = $searchRequest->academicPaperSubjectId;
        if($staffSideMarkEntryUItype == 'DIGITAL_VALUATION'){
            $studentsValuationDetails = ExamValuationService::getInstance()->getAllStudentValuationMarkForDigitalValuation($request);
        }
        else{
            $studentsValuationDetails = ExamValuationService::getInstance()->getAllStudentExternalMarksByExamRegistrationSubject($request);
        }
        if(empty($studentsValuationDetails)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No student(s) registered.");
        }
        $courseTypeId = ExamValuationService::getInstance()->getCourseTypeIdByExamRegistrationIdAndPaperSubjectId($request->examRegistrationId,$request->academicPaperSubjectId);
        $courseType = CourseTypeService::getInstance()->getCourseTypesById($courseTypeId);
        $requestForExamRegistration = new SearchExamRegistrationRequest;
        $requestForExamRegistration->id = $searchRequest->examRegistrationId;
        $examRegistration = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
        if(!empty($examRegistration)){
            $additionalDetails->examRegistrationName = reset($examRegistration)->name;
            $additionalDetails->examRegistrationType = reset($examRegistration)->type; 
        }
        $additionalDetails->courseTypeMethod = "UG";
        $additionalDetails->collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $additionalDetails->examDate = reset($studentsValuationDetails)->assessmentDate;
        $additionalDetails->examDate = $additionalDetails->examDate ? date("d-m-Y", strtotime($additionalDetails->examDate)) : "";
        $additionalDetails->subjectName = reset($studentsValuationDetails)->subjectName;
        $additionalDetails->subjectCode = reset($studentsValuationDetails)->subjectCode;
        $packetNoArray = array_unique(array_column($studentsValuationDetails, 'packetNo'));
        foreach($packetNoArray as $packetNo){
            $packetNoObj = new \stdClass;
            $packetNoObj->id= $packetNo;
            $packetNoObj->text= $packetNo;
            $packetNoObjArray[]= $packetNoObj;
        }
        if($searchRequest->packetNo){
            $studentsValuationDetails = array_filter( $studentsValuationDetails, function($student)use($searchRequest){ 
                return ($searchRequest->packetNo == $student->packetNo) ? true : false;
            });
        }
        foreach($studentsValuationDetails as $student){
            $registeredStudentsByBatch[$student->groupId]->id = $student->groupId;
            $registeredStudentsByBatch[$student->groupId]->name = $student->groupName;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->id = $student->id;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->studentId = $student->studentId;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->studentName = $student->studentName;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->regNo = $student->regNo;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->groupName = $student->groupName;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->falseNo = $student->falseNo;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->alphaNumericCode = $student->alphaNumericCode;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->packetNo = $student->packetNo;
            $registeredStudentsByBatch[$student->groupId]->students[$student->id]->thirdValEligible = $student->thirdValReq == '1' ? true : false;
            if($student->firstValuationConfirm){
                $registeredStudentsByBatch[$student->groupId]->students[$student->id]->firstValuationMark = $student->firstValuationMark ;
            }
            if($student->secondValuationConfirm){
                $registeredStudentsByBatch[$student->groupId]->students[$student->id]->secondValuationMark = $student->secondValuationMark ;
            }
            if($student->thirdValuationConfirm){
                $registeredStudentsByBatch[$student->groupId]->students[$student->id]->thirdValuationMark = $student->thirdValuationMark ;
            }
            if($student->finalizedValuationConfirm){
                $registeredStudentsByBatch[$student->groupId]->students[$student->id]->finalizedMark = $student->finalizedMark ;
            }
            if($registeredStudentsByBatch[$student->groupId]->students[$student->id]->firstValuationMark && $registeredStudentsByBatch[$student->groupId]->students[$student->id]->secondValuationMark) {
                $registeredStudentsByBatch[$student->groupId]->students[$student->id]->markDifference = abs($registeredStudentsByBatch[$student->groupId]->students[$student->id]->firstValuationMark - $registeredStudentsByBatch[$student->groupId]->students[$student->id]->secondValuationMark) ;
            }
        }
        
        $templateName = $staffSideMarkEntryUItype == 'STUDENT_WITH_PACKET' ? "Template_2_exam_valuation_report" : "Template_1_exam_valuation_report";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'students'=>$registeredStudentsByBatch,'data'=>$additionalDetails ]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                h6 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                table, th, td {border: 1px solid black;border-collapse: collapse;}
                </style>";
            $prtContent .= '</head><title>Exam Valuation Report</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $totalWidth = 210;
            $totalHeight = 297;
            $options = array(
                'page-width'     => $totalHeight."mm",
                'page-height'    => $totalWidth."mm",
                'dpi'            => 96,
                'margin-top' => "9mm",
                'margin-left' => "1mm",
                'margin-right' => "1mm",
                'margin-bottom' => "9mm",
                // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
            );
        $programResult = new \stdClass;
        $programResult->dispalyHtmlData = $responseHtml;
        $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
        $programResult->uiType = $staffSideMarkEntryUItype;
        $programResult->packetNumbers = $packetNoObjArray;
        return  $programResult;
    }
    /**
     * Get Failed Student List
     * @param $searchRequest 
     * @return $programResult 
     */
    public function getFailedStudentListReport($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest); 
        $failedStudents = [];
        $considerSupplementaryResult = false;
       
        $request = new \stdClass;
        $request->examRegistrationId = $searchRequest->examRegistrationId;
        $request->academicTermId = $searchRequest->academicTermId;
        $request->groupId = $searchRequest->groupId;
        $request->courseTypeId = $searchRequest->courseTypeId;
        $request->religionId = $searchRequest->religionId;
        $request->reservationId = $searchRequest->reservationId;
        $request->campusTypeId = $searchRequest->campusTypeId;
        $request->gender = $searchRequest->gender;
        // Rule for Regular Failed Student List
        $searchRuleRequest = new SearchRuleRequest;
        $searchRuleRequest->name = "FAILED_STUDENT_LIST_RULE";
        $failedStudentListRule = RuleService::getInstance()->searchRule($searchRuleRequest);
        $failedStudentListRule = $failedStudentListRule ? reset($failedStudentListRule) : null;
        $isShowAdditionalFilter = false;
        $isShowFeStudentAsFailed = false;
        if(!empty($failedStudentListRule)){
            $considerSupplementaryResult = $failedStudentListRule->rule->considerSupplementaryResult;
            $isShowAdditionalFilter =  $failedStudentListRule->rule->isShowAdditionalFilter ? true : false;
            $isShowFeStudentAsFailed =  $failedStudentListRule->rule->isShowFeStudentAsFailed ? true : false;
        }
        $request->isFetchWithFeSubject = true;
        $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
        if(empty($studentMarkDetails)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No student(s) registered.");
        }
        foreach($studentMarkDetails as $student){
            $failedStudents[$student->id]->id = $student->id;
            $failedStudents[$student->id]->registerNo = $student->studentDetails->registerNo;
            $failedStudents[$student->id]->name = $student->studentDetails->name;
            $failedStudents[$student->id]->batchName = $student->studentDetails->batchName;
            $failedStudents[$student->id]->subjects = [];
            foreach($student->academicTerms as $academicTerm){
                $failedStudents[$student->id]->semesterName = $academicTerm->name;
                $semesterNames = CommonExamService::getInstance()->getDifferentSemesterName($academicTerm->name);
                $failedStudents[$student->id]->semInSemNumber = $semesterNames->semNumber;
                $failedStudents[$student->id]->semNumberSuffix = CommonExamService::getInstance()->addOrdinalNumberSuffix($semesterNames->semNumber,false);
                
                foreach($academicTerm->subjects as $subject){
                    $subject->currentFailedStatus = $considerSupplementaryResult ? $subject->subjectConsolidatedFailedStatus : $subject->isFailed;
                    $subject->currentAttendanceStatus = $considerSupplementaryResult ? $subject->attendanceStatus : $subject->examAttendanceStatus ;
                    if($searchRequest->absenteesAsFailedStatus =='true'){
                        $subject->currentFailedStatus = $subject->currentAttendanceStatus == 'ABSENT' ? 'FAILED' : $subject->currentFailedStatus;
                    }
                    else{
                        $subject->currentFailedStatus = $subject->currentAttendanceStatus == 'ABSENT' ? 'PASSED' : $subject->currentFailedStatus;
                    }
                    if($searchRequest->feStudentsAsFailedStatus == 'true'){
                        $subject->currentFailedStatus = $subject->studentAttendanceStatus == 'FE' && $subject->currentFailedStatus == 'FAILED' ? 'FAILED' : $subject->currentFailedStatus;
                    }
                    else{
                        $subject->currentFailedStatus = $subject->studentAttendanceStatus == 'FE' ? 'PASSED' : $subject->currentFailedStatus;
                    }
                    if($subject->currentFailedStatus == 'FAILED'){
                        $failedStudents[$student->id]->subjects[$subject->id]->id = $subject->id;
                        $failedStudents[$student->id]->subjects[$subject->id]->code = $subject->code;
                        $failedStudents[$student->id]->subjects[$subject->id]->name = $subject->name;
                    }
                }
            }
        }
        $failedStudentsArray = array_filter($failedStudents,function($value){
            return count($value->subjects) > 0;
        });
        if(empty($failedStudentsArray)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Failed students in exam registration.");
        }
        $collegeData = CommonExamService::getInstance()->getCollegeDetails();
        $templateName = "Template_1_failed_student_list_report";
        $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'students'=>$failedStudentsArray,'data'=>$collegeData ]);
        $prtContent = NULL;
            $prtContent .= '<html><head>';
            $prtContent .= "<style>
                </style>";
            $prtContent .= '</head><title>Failed Student List</title><body>';
            $prtContent .= $responseHtml;
            $prtContent .= '</body></html>';
            $totalWidth = 210;
            $totalHeight = 297;
            $options = array(
                'page-width'     => $totalHeight."mm",
                'page-height'    => $totalWidth."mm",
                'dpi'            => 96,
                'margin-top' => "9mm",
                'margin-left' => "1mm",
                'margin-right' => "1mm",
                'margin-bottom' => "9mm",
                // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
            );
        $programResult = new \stdClass;
        $programResult->dispalyHtmlData = $responseHtml;
        $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
        $programResult->isShowAdditionalFilter = $isShowAdditionalFilter;
        $programResult->isShowFeStudentAsFailed = $isShowFeStudentAsFailed;
        return  $programResult;
    }
     /**
     * get Regular Exam Program Wise Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
     public function getRegularExamSubjectProgramCombainedResultAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $additionalDetails = new \stdClass;
            $additionalDetails->collegeName = $GLOBALS['COLLEGE_NAME'];
            $additionalDetails->collegeUrl = $GLOBALS['_SERVER']['REQUEST_SCHEME']."://".$GLOBALS['_SERVER']['HTTP_HOST'];
            $absenteesAsFailedStatus = $searchRequest->absenteesAsFailedStatus == 'true' ? true : false;
            $programWiseResultAnalysisRequest = new \stdClass;
            $programWiseResultAnalysisRequest->academicTermId = $searchRequest->academicTermId;
            $programWiseResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $programWiseResultAnalysisRequest->groupId = $searchRequest->groupId;
            $programWiseResultAnalysisRequest->absenteesAsFailedStatus = $absenteesAsFailedStatus;
            $isCombained =  $searchRequest->isCombained == 'true' ? true : false;
            $isSubjectWise =  $searchRequest->isSubjectWise == 'true' ? true : false;
            $programWiseResultAnalysisRequest->absenteesAsFailedStatus = $absenteesAsFailedStatus;
        
            $requestForExamRegistration = new SearchExamRegistrationRequest;
            $requestForExamRegistration->id = $searchRequest->examRegistrationId;
            $examRegistration = ExamRegistrationService::getInstance()->searchExamRegistration($requestForExamRegistration);
            if(!empty($examRegistration)){
                $additionalDetails->examRegistrationName = reset($examRegistration)->name;
                $additionalDetails->examRegistrationType = reset($examRegistration)->type; 
            }
            $gradeSchemeRequest = new \stdClass;
            $gradeSchemeRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $gradeSchemeRequest->academicTermId = $searchRequest->academicTermId;
            $gradeSchemeRequest->gradeHead = 'grade';
            $gradeSchemeRequest->courseTypeId = $searchRequest->courseType;
            $gradeSchemeRequest->excludeFailedGrade = false;
            $gradeSchemeDetals = $this->getAllSubjectGradeSchemesDetailsByExamRegistration($gradeSchemeRequest);
            $additionalDetails->gradeList = $gradeSchemeDetals->classHeaderNames;
            $resultAnalysis = $this->getSubjectProgramCombainedResultAnalysis($programWiseResultAnalysisRequest);
            $additionalDetails->toatalBatch->enrolled = array_sum(array_column($resultAnalysis,'enrolled'));
            $additionalDetails->toatalBatch->appeared = array_sum(array_column($resultAnalysis,'appeared'));
            $additionalDetails->toatalBatch->passed = array_sum(array_column($resultAnalysis,'passed'));
            $additionalDetails->toatalBatch->failed = array_sum(array_column($resultAnalysis,'failed'));
            $additionalDetails->toatalBatch->enrolled = array_sum(array_column($resultAnalysis,'enrolled'));
            $additionalDetails->toatalBatch->passPercentage = round ( ( 100 * $additionalDetails->toatalBatch->passed / ($additionalDetails->toatalBatch->appeared ? $additionalDetails->toatalBatch->appeared : 0 )), 2);                    
            foreach ($resultAnalysis as $batch) {
                foreach ($batch->analysisHead  as  $grade => $gradeCount) {
                    $additionalDetails->toatalBatch->grades[$grade]+=$gradeCount;
                }
            }
            if(empty($resultAnalysis)){
            throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Entry In This Exam Registration");
            }
            else{
                $templateName = $isCombained ? "CombinedWiseResultAnalysisTemplate" : "ProgramWiseResultAnalysisTemplate";
                if($isSubjectWise){
                    $templateName ="SubjectWiseResultAnalysisTemplate_2" ;
                }
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'resultAnalysis'=>$resultAnalysis ,'additionalDetails'=>$additionalDetails]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "<style>
                        h5 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                        table, th, td {border: 1px solid black;border-collapse: collapse;}
                        </style>";
                    $prtContent .= '</head><title>Subject Wise Result Anaysis</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 297;
                    $totalHeight = 210;
                    $options = array(
                        'page-width'     => $totalHeight."mm",
                        'page-height'    => $totalWidth."mm",
                        'dpi'            => 96,
                        'margin-top' => "3mm",
                        'margin-left' => "10mm",
                        'margin-right' => "10mm",
                        'margin-bottom' => "5mm",
                        // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                        'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                    );
                $programResult = new \stdClass;
                $programResult->dispalyHtmlData = $responseHtml;
                $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
            }
            
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
    public function getSubjectProgramCombainedResultAnalysis($request){
        $request = $this->realEscapeObject($request);
        try{
            $resultAnalysis = [];
            $searchRequest = new ConsolidatedMarkReportRequest;
            $searchRequest->examRegistrationId = $request->examRegistrationId;
            $searchRequest->academicTermId = $request->academicTermId;
            $searchRequest->degreeId = $request->degreeId;
            $searchRequest->groupId = $request->groupId;
            $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($request);
            if($studentMarkDetails){
                foreach($studentMarkDetails as $student){
                    $student->academicTerm = reset($student->academicTerms);
                    $currentAcademicTerm = reset(array_filter(reset($student->academicTerms)->markHistory,function($value){
                        return $value->historyType == "REGULAR";
                    }));
                    $batchId = $student->studentDetails->batchId;
                    $resultAnalysis[$batchId]->batchId = $student->studentDetails->batchId;
                    $resultAnalysis[$batchId]->batchName = $student->studentDetails->batchName;
                    $resultAnalysis[$batchId]->enrolled++;
                    $resultAnalysis[$batchId]->passed += $currentAcademicTerm->failedStatus == "FAILED" ? 0 : 1;
                    $resultAnalysis[$batchId]->failed += $currentAcademicTerm->failedStatus == "FAILED" ? 1 : 0;
                    $student->isAbsentInSubject = 1;
                    foreach ( $student->academicTerm->subjects as $subject ) {
                        $resultAnalysis[$batchId]->subjects[$subject->id]->id = $subject->id;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->code = $subject->code;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->name = $subject->name;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->enrolled++;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->passed += $subject->isFailed == 'FAILED' ? 0 : 1;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->failed += $subject->isFailed == 'FAILED' ? 1 : 0;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->absent += $subject->attendanceStatus == 'PRESENT' ? 0 : 1;
                        $resultAnalysis[$batchId]->subjects[$subject->id]->appeared += $subject->attendanceStatus == 'PRESENT' ? 1 : 0;
                        if ($subject->examAttendanceStatus == 'PRESENT') {
                            $student->isAbsentInSubject = 0;
                            break;
                        }
                    }
                    $resultAnalysis[$batchId]->analysisHead[strtoupper($currentAcademicTerm->grade)]++;
                    if (!$student->isAbsentInSubject) {
                        $resultAnalysis[$batchId]->appeared++;
                    }
                }
                foreach($resultAnalysis as $singleResultAnalysis){
                    $singleResultAnalysis->passPercentage = round ( ( 100 * $singleResultAnalysis->passed / ($singleResultAnalysis->appeared ? $singleResultAnalysis->appeared : 0 )), 2);                    
                }
            }
        }
        catch (\Exception $e){
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return $resultAnalysis;
    }
    /**
     * get Regular Exam Program Wise Result Analysis
     * @param $searchRequest 
     * @return $response 
     */
     public function getRegularExamCasteCategoryResultAnalysis($searchRequest) {
        $searchRequest = $this->realEscapeObject($searchRequest);
        try{
            $additionalDetails = new \stdClass;
            $additionalDetails->collegeData = CommonExamService::getInstance()->getCollegeDetails();
            $requestForExamRegistration = new \stdClass;
            $casteCategoryStudents = [];
            $gradeList = [];
            $additionalDetails->currentDate = date("d M Y");
            $requestForExamRegistration->examRegistrationId = $searchRequest->examRegistrationId;
            $examRegistration = reset(ExamRegistrationService::getInstance()->searchDetailedExamRegistrationDetails($requestForExamRegistration));
            if(!empty($examRegistration)){
                $additionalDetails->examRegistrationName = $examRegistration->name;
                $additionalDetails->examRegistrationType = $examRegistration->type; 
                $additionalDetails->degreeDescription = reset($examRegistration->groups)->degreeDescription;
                $additionalDetails->endYear = reset($examRegistration->groups)->properties->endYear;
                $additionalDetails->startYear = reset($examRegistration->groups)->properties->startYear;
                $additionalDetails->academicTermName = reset($examRegistration->groups)->academicTermName;
                $semesterNames = CommonExamService::getInstance()->getDifferentSemesterName($additionalDetails->academicTermName);
                $additionalDetails->academicTermRoman = $semesterNames->romanLetter;
                
            }
            $gradeSchemeRequest = new \stdClass;
            $gradeSchemeRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $gradeSchemeRequest->groupId = array_column($examRegistration->groups,'groupId');
            $gradeSchemeRequest->requestType = "SEMESTER";
            $grades = GradeSchemeService::getInstance()->getAllSemesterSubjectCurriculumGrades($gradeSchemeRequest);
            foreach($grades as $grade){
                if($grade->failStatus != '1'){
                    $gradeList[$grade->gradeName] = $grade;
                }
            }
            $gradeList["PASS"]->gradeName = "PASS";
            $gradeList["ATKT"]->gradeName = "ATKT";
            $gradeList["FAIL"]->gradeName = "FAIL";
            $additionalDetails->gradeList = $gradeList;
            $casteCategoryResultAnalysisRequest = new \stdClass;
            $casteCategoryResultAnalysisRequest->examRegistrationId = $searchRequest->examRegistrationId;
            $casteCategoryResultAnalysisRequest->groupId = $searchRequest->groupId;
            $studentMarkDetails = $this->getAllRegistredStudentOverAllDetails($casteCategoryResultAnalysisRequest);
            foreach($studentMarkDetails as $student){
                $currentAcademicTerm = reset(array_filter(reset($student->academicTerms)->markHistory,function($value)use($searchRequest){
                    return $value->examRegistrationId == $searchRequest->examRegistrationId;
                }));
                $reservationId = $student->studentDetails->reservationId;
                $casteId = $student->studentDetails->casteId;
                $studentGender = $student->studentDetails->gender;
                $studentGrade = $currentAcademicTerm->grade;
                $casteCategoryStudents[$student->studentDetails->batchId]->id = $student->studentDetails->batchId;
                $casteCategoryStudents[$student->studentDetails->batchId]->name = $student->studentDetails->batchName;
                $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->id = $reservationId;
                $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->name = $student->studentDetails->reservationName;
                if(empty($casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender])){
                    $casteCategoryStudents[$student->studentDetails->batchId]->categoryCount++;
                }
                $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->id = $studentGender;
                $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->name = ucwords($studentGender);
                $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->totalStudent++;
                $casteCategoryStudents[$student->studentDetails->batchId]->totalStudent++;
                if($currentAcademicTerm->failedStatus == "FAILED"){
                    $studentSubjects = reset($student->academicTerms)->subjects;
                    $failedSubjects = array_filter($studentSubjects,function($value){
                        return $value->isFailed == "FAILED";
                    });
                    if(count($failedSubjects) > 2){
                        $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->grades["FAIL"]++;
                        $casteCategoryStudents[$student->studentDetails->batchId]->gradeGrandTotal["FAIL"]++;    
                    }
                    else{
                        $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->grades["ATKT"]++;
                        $casteCategoryStudents[$student->studentDetails->batchId]->gradeGrandTotal["ATKT"]++;    
                    }
                }
                else{
                    $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->grades["PASS"]++;
                    $casteCategoryStudents[$student->studentDetails->batchId]->category[$reservationId]->genders[$studentGender]->grades[$studentGrade]++;
                    $casteCategoryStudents[$student->studentDetails->batchId]->gradeGrandTotal["PASS"]++;
                    $casteCategoryStudents[$student->studentDetails->batchId]->gradeGrandTotal[$studentGrade]++;
                }
            }
            $casteCategoryStudents = array_values($casteCategoryStudents);
            array_walk($casteCategoryStudents, function($student){
                $student->castes = array_values($student->castes);
            });
            if(empty($casteCategoryStudents)){
                throw new ExamControllerException(ExamControllerException::NO_REPORTS_DETAILS_FOUND,"No Entry In This Exam Registration");
            }
            else{
                $templateName = "casteCategoryWiseResultAnalysis";
                $responseHtml = TwigRenderer::renderTemplateFileToHtml(realpath(DOCUMENT_ROOT."../examcontroller-api/src/com/linways/web/templates/regularExamReportTwigs/$templateName.twig"), [ 'casteCategoryStudents'=>$casteCategoryStudents ,'additionalDetails'=>$additionalDetails]);
                $prtContent = NULL;
                    $prtContent .= '<html><head>';
                    $prtContent .= "<style>
                        h5 {font-size: 26px;} .text-center { text-align: center;} .align-middle {vertical-align: middle;}; tr.noBorder td {border: 0;  border-collapse:collapse;}
                        table, th, td {border: 1px solid black;border-collapse: collapse;}
                        </style>";
                    $prtContent .= '</head><title>Caste Category Wise Result Anaysis</title><body>';
                    $prtContent .= $responseHtml;
                    $prtContent .= '</body></html>';
                    $totalWidth = 297;
                    $totalHeight = 210;
                    $options = array(
                        'page-width'     => $totalHeight."mm",
                        'page-height'    => $totalWidth."mm",
                        'dpi'            => 96,
                        'margin-top' => "3mm",
                        'margin-left' => "10mm",
                        'margin-right' => "10mm",
                        'margin-bottom' => "5mm",
                        // 'binary' => "/usr/local/bin/wkhtmltopdf", // For Mac
                        'user-style-sheet' => realpath(DOCUMENT_ROOT . "/libcommon/bootstrap/css/bootstrap.min.css")
                    );
                $programResult = new \stdClass;
                $programResult->dispalyHtmlData = $responseHtml;
                $programResult->printData = PdfUtil::renderPdf($prtContent, $options);
            }
            
        }
        catch (\Exception $e)
        {
            throw new ExamControllerException($e->getCode(),$e->getMessage());
        }
        return  $programResult;
    }
    
    
   
    
    
}